mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-24 19:46:34 +01:00
Various (unfinished)
Fixes #439 Update to Java 8 Adds scrollable brushes to the API (action on brush scroll) - Clipboard - Mask - Pattern - Range - Size Adds movable brushes to the API (action on brush move) Adds different targeting modes for brushes (see enum TargetMode) Adds VisualBrush to API (sends client block changes instead of changing the world) Updater now checks every 30m for updates Adds in game updater changelog (/fawe changelog) Adds language option to config Adds german translations Adds CircleBrush (WIP) Simplify DoubleActionBrush and DoubleActionBrushTool to extend Brush/BrushTool Use ImmutableBlock instead of anonymous BaseBlock for cache Fixes CuboidRegion iteration (affected some commands) Fixes WorldCopyClipboard schematic saving Optimize FawePlayer -> Player by caching value Simplified pattern and mask API by extending legacy versions Optimize sphere, cylinder and deform Added brush cancellation by SHIFT + LEFT CLICK Probably some other stuff
This commit is contained in:
parent
74baf5fee8
commit
9c74d0b981
@ -74,8 +74,8 @@ subprojects {
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
135
bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java
Normal file
135
bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java
Normal file
@ -0,0 +1,135 @@
|
||||
package com.boydti.fawe.bukkit;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.MovableBrush;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollableBrush;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||
import com.sk89q.worldedit.command.tool.Tool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class BrushListener implements Listener {
|
||||
public BrushListener(Plugin plugin) {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerItemHoldEvent(final PlayerItemHeldEvent event) {
|
||||
final Player bukkitPlayer = event.getPlayer();
|
||||
if (bukkitPlayer.isSneaking()) {
|
||||
return;
|
||||
}
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(bukkitPlayer);
|
||||
com.sk89q.worldedit.entity.Player player = fp.getPlayer();
|
||||
LocalSession session = fp.getSession();
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool != null) {
|
||||
ScrollableBrush scrollable;
|
||||
if (tool instanceof ScrollableBrush) {
|
||||
scrollable = (ScrollableBrush) tool;
|
||||
} else if (tool instanceof BrushTool) {
|
||||
Brush brush = ((BrushTool) tool).getBrush();
|
||||
scrollable = brush instanceof ScrollableBrush ? (ScrollableBrush) brush : null;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (scrollable != null) {
|
||||
final int slot = event.getNewSlot();
|
||||
final int oldSlot = event.getPreviousSlot();
|
||||
final int ri;
|
||||
if ((((slot - oldSlot) <= 4) && ((slot - oldSlot) > 0)) || (((slot - oldSlot) < -4))) {
|
||||
ri = 1;
|
||||
} else {
|
||||
ri = -1;
|
||||
}
|
||||
if (scrollable.increment(ri)) {
|
||||
final PlayerInventory inv = bukkitPlayer.getInventory();
|
||||
final ItemStack item = inv.getItem(slot);
|
||||
final ItemStack newItem = inv.getItem(oldSlot);
|
||||
inv.setItem(slot, newItem);
|
||||
inv.setItem(oldSlot, item);
|
||||
bukkitPlayer.updateInventory();
|
||||
if (scrollable instanceof VisualBrush) {
|
||||
try {
|
||||
((VisualBrush) scrollable).queueVisualization(fp);
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
if ((from.getYaw() != to.getYaw() && from.getPitch() != to.getPitch()) || from.getBlockX() != to.getBlockX() || from.getBlockZ() != to.getBlockZ() || from.getBlockY() != to.getBlockY()) {
|
||||
Player bukkitPlayer = event.getPlayer();
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(bukkitPlayer);
|
||||
com.sk89q.worldedit.entity.Player player = fp.getPlayer();
|
||||
LocalSession session = fp.getSession();
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool != null) {
|
||||
if (tool instanceof MovableBrush) {
|
||||
((MovableBrush) tool).move(player);
|
||||
} else if (tool instanceof BrushTool) {
|
||||
Brush brush = ((BrushTool) tool).getBrush();
|
||||
if (brush instanceof MovableBrush) {
|
||||
if (((MovableBrush) brush).move(player)) {
|
||||
if (brush instanceof VisualBrush) {
|
||||
try {
|
||||
((VisualBrush) brush).queueVisualization(fp);
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(final PlayerInteractEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case LEFT_CLICK_AIR:
|
||||
case LEFT_CLICK_BLOCK:
|
||||
Player bukkitPlayer = event.getPlayer();
|
||||
if (!bukkitPlayer.isSneaking()) {
|
||||
return;
|
||||
}
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(bukkitPlayer);
|
||||
com.sk89q.worldedit.entity.Player player = fp.getPlayer();
|
||||
LocalSession session = fp.getSession();
|
||||
int item = player.getItemInHand();
|
||||
Tool tool = session.getTool(item);
|
||||
if (tool != null) {
|
||||
try {
|
||||
session.setTool(item, null, player);
|
||||
BBC.TOOL_NONE.send(player);
|
||||
} catch (InvalidToolBindException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
||||
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
||||
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
||||
import com.boydti.fawe.bukkit.v1_11.compression.CompressionOptimizer;
|
||||
import com.boydti.fawe.bukkit.v1_7.BukkitQueue17;
|
||||
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
||||
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
||||
@ -68,6 +69,15 @@ public class BukkitMain extends JavaPlugin {
|
||||
break;
|
||||
} catch (IllegalStateException e) {}
|
||||
}
|
||||
switch (version) {
|
||||
case v1_11_R1:
|
||||
try {
|
||||
CompressionOptimizer optimizer = new CompressionOptimizer();
|
||||
// optimizer.optimize();
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum Version {
|
||||
|
@ -92,7 +92,7 @@ public class BukkitPlayer extends FawePlayer<Player> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sk89q.worldedit.entity.Player getPlayer() {
|
||||
public com.sk89q.worldedit.entity.Player toWorldEditPlayer() {
|
||||
return PlayerWrapper.wrap(Fawe.<FaweBukkit> imp().getWorldEditPlugin().wrapPlayer(this.parent));
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
try {
|
||||
Fawe.set(this);
|
||||
setupInjector();
|
||||
new BrushListener(plugin);
|
||||
if (Bukkit.getVersion().contains("git-Spigot")) {
|
||||
debug("====== USE PAPER ======");
|
||||
debug("DOWNLOAD: https://ci.destroystokyo.com/job/PaperSpigot/");
|
||||
|
@ -9,6 +9,7 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
@ -142,9 +143,9 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
if ((BukkitQueue_0.adapter = adapter) != null) {
|
||||
fieldAdapter.set(instance, adapter);
|
||||
} else {
|
||||
BukkitQueue_0.adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||
BukkitQueue_0.adapter = adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||
}
|
||||
for (Method method : BukkitQueue_0.adapter.getClass().getDeclaredMethods()) {
|
||||
for (Method method : adapter.getClass().getDeclaredMethods()) {
|
||||
switch (method.getName()) {
|
||||
case "toNative":
|
||||
methodToNative = method;
|
||||
@ -237,28 +238,41 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (FawePlayer player : players) {
|
||||
Player bukkitPlayer = ((BukkitPlayer) player).parent;
|
||||
World world = bukkitPlayer.getWorld();
|
||||
for (Map.Entry<Long, Map<Short, Character>> entry : blockMap.entrySet()) {
|
||||
long chunkHash = entry.getKey();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
Map<Short, Character> blocks = entry.getValue();
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
short blockHash = blockEntry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + (cx << 4);
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + (cz << 4);
|
||||
char combined = blockEntry.getValue();
|
||||
int id = FaweCache.getId(combined);
|
||||
byte data = (byte) FaweCache.getData(combined);
|
||||
Location loc = new Location(world, x, y, z);
|
||||
bukkitPlayer.sendBlockChange(loc, id, data);
|
||||
}
|
||||
public void sendBlockUpdate(final FaweChunk chunk, FawePlayer... players) {
|
||||
if (players.length == 0) {
|
||||
return;
|
||||
}
|
||||
int cx = chunk.getX();
|
||||
int cz = chunk.getZ();
|
||||
int view = Bukkit.getServer().getViewDistance();
|
||||
boolean sendAny = false;
|
||||
boolean[] send = new boolean[players.length];
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
FawePlayer player = players[i];
|
||||
Player bp = ((BukkitPlayer) player).parent;
|
||||
Location loc = bp.getLocation();
|
||||
if (Math.abs((loc.getBlockX() >> 4) - cx) <= view && Math.abs((loc.getBlockZ() >> 4) - cz) <= view) {
|
||||
sendAny = true;
|
||||
send[i] = true;
|
||||
}
|
||||
}
|
||||
if (!sendAny) {
|
||||
return;
|
||||
}
|
||||
final World world = getWorld();
|
||||
final int bx = cx << 4;
|
||||
final int bz = cz << 4;
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
Location loc = new Location(world, bx + localX, y, bz + localZ);
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
if (send[i]) {
|
||||
((BukkitPlayer) players[i]).parent.sendBlockChange(loc, FaweCache.getId(combined), (byte) FaweCache.getData(combined));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,80 @@
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import net.minecraft.server.v1_10_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_10_R1.NibbleArray;
|
||||
|
||||
public class BukkitChunk_1_10_Copy extends BukkitChunk_1_10 {
|
||||
public final byte[][] idsBytes;
|
||||
public final byte[][] datasBytes;
|
||||
|
||||
public BukkitChunk_1_10_Copy(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
idsBytes = new byte[16][];
|
||||
datasBytes = new byte[16][];
|
||||
}
|
||||
|
||||
public void set(int i, byte[] ids, byte[] data) {
|
||||
this.idsBytes[i] = ids;
|
||||
this.datasBytes[i] = data;
|
||||
}
|
||||
|
||||
public boolean storeSection(ChunkSection section, int layer) throws IllegalAccessException {
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
set(layer, ids, data.asBytes());
|
||||
short solid = (short) getParent().fieldNonEmptyBlockCount.getInt(section);
|
||||
count[layer] = solid;
|
||||
air[layer] = (short) (4096 - solid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getCombinedIdArrays() {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
getIdArray(i);
|
||||
}
|
||||
return super.getCombinedIdArrays();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getIdArray(int i) {
|
||||
char[] combined = this.ids[i];
|
||||
if (combined != null) {
|
||||
return combined;
|
||||
}
|
||||
byte[] idsBytesArray = idsBytes[i];
|
||||
if (idsBytesArray == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] datasBytesArray = datasBytes[i];
|
||||
|
||||
idsBytes[i] = null;
|
||||
datasBytes[i] = null;
|
||||
|
||||
this.ids[i] = combined = new char[4096];
|
||||
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + (datasBytesArray[j] & 15));
|
||||
}
|
||||
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + ((datasBytesArray[j] >> 4) & 15));
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
}
|
@ -25,10 +25,13 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import net.minecraft.server.v1_10_R1.BiomeBase;
|
||||
import net.minecraft.server.v1_10_R1.BiomeCache;
|
||||
import net.minecraft.server.v1_10_R1.Block;
|
||||
import net.minecraft.server.v1_10_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_10_R1.ChunkProviderGenerate;
|
||||
import net.minecraft.server.v1_10_R1.ChunkProviderServer;
|
||||
import net.minecraft.server.v1_10_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_10_R1.DataBits;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_10_R1.Entity;
|
||||
import net.minecraft.server.v1_10_R1.EntityPlayer;
|
||||
@ -47,6 +50,7 @@ import net.minecraft.server.v1_10_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_10_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_10_R1.ServerNBTManager;
|
||||
import net.minecraft.server.v1_10_R1.TileEntity;
|
||||
import net.minecraft.server.v1_10_R1.WorldChunkManager;
|
||||
import net.minecraft.server.v1_10_R1.WorldData;
|
||||
import net.minecraft.server.v1_10_R1.WorldManager;
|
||||
import net.minecraft.server.v1_10_R1.WorldServer;
|
||||
@ -68,6 +72,8 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Field fieldPalette;
|
||||
protected static Field fieldSize;
|
||||
protected static Method getEntitySlices;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
@ -80,9 +86,10 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static MutableGenLayer genLayer;
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE + 1];
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
@ -93,21 +100,26 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = net.minecraft.server.v1_10_R1.ChunkProviderGenerate.class.getDeclaredField("C");
|
||||
fieldBiomes = ChunkProviderGenerate.class.getDeclaredField("D");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldChunkGenerator = net.minecraft.server.v1_10_R1.ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||
fieldChunkGenerator = ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||
fieldChunkGenerator.setAccessible(true);
|
||||
fieldSeed = net.minecraft.server.v1_10_R1.WorldData.class.getDeclaredField("e");
|
||||
fieldSeed = WorldData.class.getDeclaredField("e");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = net.minecraft.server.v1_10_R1.WorldChunkManager.class.getDeclaredField("c");
|
||||
fieldBiomeCache = WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = net.minecraft.server.v1_10_R1.WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomes2 = WorldChunkManager.class.getDeclaredField("e");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = net.minecraft.server.v1_10_R1.WorldChunkManager.class.getDeclaredField("a") ;
|
||||
fieldGenLayer2 = net.minecraft.server.v1_10_R1.WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer1 = WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer2 = WorldChunkManager.class.getDeclaredField("c") ;
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
|
||||
|
||||
fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
|
||||
fieldPalette.setAccessible(true);
|
||||
fieldSize = DataPaletteBlock.class.getDeclaredField("e");
|
||||
fieldSize.setAccessible(true);
|
||||
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
@ -115,12 +127,10 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_10_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
@ -140,6 +150,40 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getSections(net.minecraft.server.v1_10_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
@ -149,10 +193,10 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderGenerate generator = new net.minecraft.server.v1_10_R1.ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
ChunkProviderGenerate generator = new ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
Biome bukkitBiome = adapter.getBiome(biome.getId());
|
||||
net.minecraft.server.v1_10_R1.BiomeBase base = net.minecraft.server.v1_10_R1.BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new net.minecraft.server.v1_10_R1.BiomeBase[]{base});
|
||||
BiomeBase base = BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new BiomeBase[]{base});
|
||||
boolean cold = base.getTemperature() <= 1;
|
||||
net.minecraft.server.v1_10_R1.ChunkGenerator existingGenerator = nmsWorld.getChunkProviderServer().chunkGenerator;
|
||||
long existingSeed = world.getSeed();
|
||||
@ -166,7 +210,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new net.minecraft.server.v1_10_R1.BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
@ -217,9 +261,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
protected DataBits lastBits;
|
||||
protected DataPaletteBlock lastBlocks;
|
||||
|
||||
@Override
|
||||
public World createWorld(final WorldCreator creator) {
|
||||
final String name = creator.name();
|
||||
@ -303,46 +344,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection[] getSections(net.minecraft.server.v1_10_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk;
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection getCachedSection(net.minecraft.server.v1_10_R1.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection lastSection, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = lastSection.getBlocks();
|
||||
@ -356,6 +357,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = section.getBlocks();
|
||||
@ -403,6 +409,13 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
if (playerChunk.c.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (mask == 0) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65535);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Send chunks
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
@ -523,7 +536,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldSection.setAccessible(true);
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
@ -554,33 +566,18 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
public BukkitChunk_1_10 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
||||
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||
BukkitChunk_1_10 previous = getFaweChunk(fs.getX(), fs.getZ());
|
||||
// Copy blocks
|
||||
char[][] idPrevious = previous.getCombinedIdArrays();
|
||||
BukkitChunk_1_10_Copy previous = new BukkitChunk_1_10_Copy(this, fs.getX(), fs.getZ());
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
short solid = 0;
|
||||
char[] previousLayer = idPrevious[layer] = new char[4096];
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = FaweCache.CACHE_X[0][j];
|
||||
int y = FaweCache.CACHE_Y[0][j];
|
||||
int z = FaweCache.CACHE_Z[0][j];
|
||||
IBlockData ibd = blocks.a(x, y, z);
|
||||
Block block = ibd.getBlock();
|
||||
int combined = Block.getId(block);
|
||||
if (FaweCache.hasData(combined)) {
|
||||
combined = (combined << 4) + block.toLegacyData(ibd);
|
||||
} else {
|
||||
combined = combined << 4;
|
||||
}
|
||||
if (combined > 1) {
|
||||
solid++;
|
||||
}
|
||||
previousLayer[j] = (char) combined;
|
||||
}
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
previous.set(layer, ids, data.asBytes());
|
||||
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
@ -605,7 +602,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
}
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = ((int) Math.round(ent.locY)) & 255;
|
||||
int y = ((int) Math.round(ent.locY) & 0xFF);
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
|
@ -0,0 +1,118 @@
|
||||
package com.boydti.fawe.bukkit.v1_11.compression;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.LoaderClassPath;
|
||||
import net.minecraft.server.v1_11_R1.RegionFile;
|
||||
|
||||
public class CompressionOptimizer {
|
||||
|
||||
private final ClassPool pool;
|
||||
|
||||
public CompressionOptimizer() {
|
||||
this.pool = ClassPool.getDefault();
|
||||
}
|
||||
|
||||
public void loadSafe(String name) throws Throwable {
|
||||
try {
|
||||
pool.get(name).toClass();
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null) {
|
||||
e = e.getCause();
|
||||
}
|
||||
if (e instanceof ClassNotFoundException) {
|
||||
loadSafe(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadPackage(String... packages) throws IOException {
|
||||
JarInputStream jarFile = new JarInputStream(new FileInputStream(MainUtil.getJarFile()));
|
||||
JarEntry jarEntry;
|
||||
while(true) {
|
||||
jarEntry = jarFile.getNextJarEntry();
|
||||
if(jarEntry == null){
|
||||
break;
|
||||
}
|
||||
if (jarEntry.getName ().endsWith (".class")) {
|
||||
for (String p : packages) {
|
||||
if (jarEntry.getName ().startsWith(p)) {
|
||||
String name = jarEntry.getName().substring(0, jarEntry.getName().length() - 6).replaceAll("/", "\\.");
|
||||
try {
|
||||
loadSafe(name);
|
||||
} catch (Throwable ignore) {}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void optimize() throws Throwable {
|
||||
// pool.insertClassPath(new ClassClassPath(PGZIPOutputStream.class));
|
||||
// pool.insertClassPath(new ClassClassPath(PGZIPBlock.class));
|
||||
// pool.insertClassPath(new ClassClassPath(PGZIPState.class));
|
||||
// pool.insertClassPath(new ClassClassPath(PGZIPThreadLocal.class));
|
||||
// pool.insertClassPath(new ClassClassPath(ClassPath.class));
|
||||
// pool.insertClassPath(new ClassClassPath(CompressionOptimizer.class));
|
||||
pool.insertClassPath(new LoaderClassPath(this.getClass().getClassLoader()));
|
||||
pool.get("com.boydti.fawe.object.io.PGZIPOutputStream").toClass();
|
||||
pool.get("com.boydti.fawe.object.io.PGZIPBlock").toClass();
|
||||
pool.get("com.boydti.fawe.object.io.PGZIPState").toClass();
|
||||
pool.get("com.boydti.fawe.object.io.PGZIPThreadLocal").toClass();
|
||||
pool.get("com.boydti.fawe.bukkit.v1_11.compression.CompressionOptimizer").toClass();
|
||||
pool.get("javassist.ClassPath").toClass();
|
||||
pool.importPackage("net.minecraft.server.v1_11_R1");
|
||||
pool.importPackage("java.lang");
|
||||
pool.importPackage("java.lang.reflect");
|
||||
pool.importPackage("java.io");
|
||||
pool.importPackage("com.boydti.fawe.bukkit.v1_11.compression");
|
||||
// RegionFile.class.getDeclaredClasses()[0];
|
||||
|
||||
|
||||
{ // Optimize NBTCompressedStreamTools
|
||||
CtClass clazz = pool.get("net.minecraft.server.v1_11_R1.NBTCompressedStreamTools");
|
||||
CtMethod methodA_getStream = clazz.getDeclaredMethod("a", new CtClass[]{pool.get("net.minecraft.server.v1_11_R1.NBTTagCompound"), pool.get("java.io.OutputStream")});
|
||||
methodA_getStream.setBody("{" +
|
||||
"java.io.DataOutputStream dataoutputstream = new java.io.DataOutputStream(new java.io.BufferedOutputStream(new com.boydti.fawe.object.io.PGZIPOutputStream($2)));" +
|
||||
"try {" +
|
||||
" a($1, (java.io.DataOutput) dataoutputstream);" +
|
||||
"} finally {" +
|
||||
" dataoutputstream.close();" +
|
||||
"}" +
|
||||
"}");
|
||||
clazz.toClass();
|
||||
}
|
||||
|
||||
{ // Optimize RegionFile
|
||||
CtClass clazz = pool.get("net.minecraft.server.v1_11_R1.RegionFile");
|
||||
CtMethod methodB_getStream = clazz.getDeclaredMethod("b", new CtClass[]{CtClass.intType, CtClass.intType});
|
||||
methodB_getStream.setBody("{" +
|
||||
"Constructor constructor = $0.getClass().getDeclaredClasses()[0].getConstructors()[0];" +
|
||||
" constructor.setAccessible(true);" +
|
||||
" return $0.d($1, $2) ? null : new java.io.DataOutputStream(new java.io.BufferedOutputStream(new com.boydti.fawe.object.io.PGZIPOutputStream((OutputStream) CompressionOptimizer.newInstance(constructor, $0, $1, $2))));" +
|
||||
"}");
|
||||
clazz.toClass();
|
||||
|
||||
// RegionFile $0 = null;
|
||||
// int $1 = 0;
|
||||
// int $2 = 0;
|
||||
//
|
||||
// Constructor<?> constructor = $0.getClass().getDeclaredClasses()[0].getConstructors()[0];
|
||||
// constructor.setAccessible(true);
|
||||
// return $0.d($1, $2) ? null : new java.io.DataOutputStream(new java.io.BufferedOutputStream(new com.boydti.fawe.object.io.PGZIPOutputStream((OutputStream) constructor.newInstance($1, $2))));
|
||||
}
|
||||
}
|
||||
|
||||
public static Object newInstance(Constructor constructor, RegionFile file, int a, int b) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
return constructor.newInstance(file, a, b);
|
||||
}
|
||||
}
|
@ -14,9 +14,6 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'fawe.properties'
|
||||
|
@ -8,6 +8,7 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualQueue;
|
||||
import com.boydti.fawe.regions.general.plot.PlotSquaredFeature;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
@ -26,6 +27,7 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockData;
|
||||
import com.sk89q.worldedit.command.BiomeCommands;
|
||||
import com.sk89q.worldedit.command.BrushCommands;
|
||||
@ -69,6 +71,7 @@ import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.FuzzyBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskUnion;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||
@ -77,6 +80,7 @@ import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
||||
@ -167,6 +171,8 @@ public class Fawe {
|
||||
*/
|
||||
private final FaweTimer timer;
|
||||
private FaweVersion version;
|
||||
private VisualQueue visualQueue;
|
||||
private Updater updater;
|
||||
|
||||
/**
|
||||
* Get the implementation specific class
|
||||
@ -242,7 +248,7 @@ public class Fawe {
|
||||
* Instance independent stuff
|
||||
*/
|
||||
this.setupMemoryListener();
|
||||
timer = new FaweTimer();
|
||||
this.timer = new FaweTimer();
|
||||
Fawe.this.IMP.setupVault();
|
||||
|
||||
// Delayed worldedit setup
|
||||
@ -250,6 +256,7 @@ public class Fawe {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
visualQueue = new VisualQueue();
|
||||
WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers());
|
||||
WEManager.IMP.managers.add(new PlotSquaredFeature());
|
||||
Fawe.debug("Plugin 'PlotSquared' found. Using it now.");
|
||||
@ -265,7 +272,8 @@ public class Fawe {
|
||||
TaskManager.IMP.repeatAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Updater.update(IMP.getPlatform(), getVersion());
|
||||
updater = new Updater();
|
||||
updater.update(IMP.getPlatform(), getVersion());
|
||||
}
|
||||
}, 36000);
|
||||
}
|
||||
@ -277,6 +285,15 @@ public class Fawe {
|
||||
return isJava8;
|
||||
}
|
||||
|
||||
/**
|
||||
* The FAWE updater class
|
||||
* - Use to get basic update information (changelog/version etc)
|
||||
* @return
|
||||
*/
|
||||
public Updater getUpdater() {
|
||||
return updater;
|
||||
}
|
||||
|
||||
/**
|
||||
* The FaweTimer is a useful class for monitoring TPS
|
||||
* @return FaweTimer
|
||||
@ -285,6 +302,14 @@ public class Fawe {
|
||||
return timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* The visual queue is used to queue visualizations
|
||||
* @return
|
||||
*/
|
||||
public VisualQueue getVisualQueue() {
|
||||
return visualQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The FAWE version
|
||||
* - Unofficial jars may be lacking version information
|
||||
@ -306,6 +331,7 @@ public class Fawe {
|
||||
}
|
||||
|
||||
public void setupConfigs() {
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "de/messages.yml", null);
|
||||
// Setting up config.yml
|
||||
File file = new File(this.IMP.getDirectory(), "config.yml");
|
||||
Settings.IMP.PLATFORM = IMP.getPlatform().replace("\"", "");
|
||||
@ -345,7 +371,7 @@ public class Fawe {
|
||||
Commands.inject(); // Translations
|
||||
EditSession.inject(); // Custom block placer + optimizations
|
||||
EditSessionEvent.inject(); // Add EditSession to event (API)
|
||||
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk
|
||||
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk / brush visualization
|
||||
SessionManager.inject(); // Faster custom session saving + Memory improvements
|
||||
Request.inject(); // Custom pattern extent
|
||||
// Commands
|
||||
@ -381,7 +407,7 @@ public class Fawe {
|
||||
LongRangeBuildTool.inject();
|
||||
AreaPickaxe.inject(); // Fixes
|
||||
RecursivePickaxe.inject(); // Fixes
|
||||
BrushTool.inject(); // Add transform
|
||||
BrushTool.inject(); // Add transform + support for double action brushes + visualizations
|
||||
// Selectors
|
||||
CuboidRegionSelector.inject(); // Translations
|
||||
EllipsoidRegion.inject(); // Optimizations
|
||||
@ -415,13 +441,17 @@ public class Fawe {
|
||||
BlockVector.inject(); // Optimizations
|
||||
Vector.inject(); // Optimizations
|
||||
Vector2D.inject(); // Optimizations
|
||||
// Block
|
||||
BaseBlock.inject(); // Optimizations
|
||||
// Pattern
|
||||
Pattern.inject(); // Simplify API
|
||||
Patterns.inject(); // Optimizations (reduce object creation)
|
||||
RandomPattern.inject(); // Optimizations
|
||||
ClipboardPattern.inject(); // Optimizations
|
||||
HashTagPatternParser.inject(); // Add new patterns
|
||||
DefaultBlockParser.inject(); // Fix block lookups
|
||||
// Mask
|
||||
Mask.inject(); // Extend deprecated mask
|
||||
BlockMask.inject(); // Optimizations
|
||||
SolidBlockMask.inject(); // Optimizations
|
||||
FuzzyBlockMask.inject(); // Optimizations
|
||||
|
@ -14,9 +14,10 @@ import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.CuboidClipboard;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.ImmutableBlock;
|
||||
import com.sk89q.worldedit.blocks.ImmutableDatalessBlock;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.awt.Color;
|
||||
@ -171,34 +172,11 @@ public class FaweCache {
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
int id = i >> 4;
|
||||
int data = i & 0xf;
|
||||
CACHE_BLOCK[i] = new BaseBlock(id, data) {
|
||||
@Override
|
||||
public void setData(int data) {
|
||||
throw new IllegalStateException("Cannot set data");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
throw new IllegalStateException("Cannot set id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock flip() {
|
||||
BaseBlock clone = new BaseBlock(getId(), getData(), getNbtData());
|
||||
return clone.flip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock flip(CuboidClipboard.FlipDirection direction) {
|
||||
BaseBlock clone = new BaseBlock(getId(), getData(), getNbtData());
|
||||
return clone.flip(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWildcardData() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
if (FaweCache.hasData(id)) {
|
||||
CACHE_BLOCK[i] = new ImmutableBlock(id, data);
|
||||
} else {
|
||||
CACHE_BLOCK[i] = new ImmutableDatalessBlock(id);
|
||||
}
|
||||
CACHE_ITEM[i] = new BaseItem(id, (short) data) {
|
||||
|
||||
@Override
|
||||
|
@ -7,12 +7,14 @@ import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.HastebinUtility;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.Updater;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Reload extends FaweCommand {
|
||||
|
||||
@ -23,7 +25,7 @@ public class Reload extends FaweCommand {
|
||||
@Override
|
||||
public boolean execute(final FawePlayer player, final String... args) {
|
||||
if (args.length != 1) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version|debugpaste|threads]");
|
||||
BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version|debugpaste|threads|changelog]");
|
||||
return false;
|
||||
}
|
||||
switch (args[0].toLowerCase()) {
|
||||
@ -54,6 +56,22 @@ public class Reload extends FaweCommand {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "changelog": {
|
||||
try {
|
||||
Updater updater = Fawe.get().getUpdater();
|
||||
String changes = updater != null ? updater.getChanges() : null;
|
||||
if (changes == null) {
|
||||
try (Scanner scanner = new Scanner(new URL("http://boydti.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash)).openStream(), "UTF-8")) {
|
||||
changes = scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
player.sendMessage(BBC.getPrefix() + changes);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case "debugpaste":
|
||||
case "paste": {
|
||||
try {
|
||||
|
@ -123,6 +123,7 @@ public enum BBC {
|
||||
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
||||
BRUSH_BLEND_BALL("Blend ball brush equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_ERODE("Erode brush equipped (%s0). Right click to erode, left click to pull.", "WorldEdit.Brush"),
|
||||
BRUSH_CIRCLE("Circle brush equipped (%s0). Right click to create a circle.", "WorldEdit.Brush"),
|
||||
BRUSH_RECURSIVE("Recursive brush equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_PASTE_NONE("Nothing to paste", "WorldEdit.Brush"),
|
||||
BRUSH_SIZE("Brush size set", "WorldEdit.Brush"),
|
||||
|
@ -2,7 +2,6 @@ package com.boydti.fawe.config;
|
||||
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -26,6 +25,9 @@ public class Settings extends Config {
|
||||
@Final
|
||||
public String PLATFORM; // These values are set from FAWE before loading
|
||||
|
||||
@Comment({"Options: de",
|
||||
"Create a PR to contribute a translation: https://github.com/boy0001/FastAsyncWorldedit/new/master/core/src/main/resources",})
|
||||
public String LANGUAGE = "";
|
||||
@Comment("Allow the plugin to update")
|
||||
public boolean UPDATE = true;
|
||||
@Comment("Send anonymous usage statistics to MCStats.org")
|
||||
@ -330,9 +332,6 @@ public class Settings extends Config {
|
||||
public void reload(File file) {
|
||||
load(file);
|
||||
save(file);
|
||||
if (HISTORY.USE_DISK) {
|
||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
public FaweLimit getLimit(FawePlayer player) {
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.boydti.fawe.example;
|
||||
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
|
||||
public class NullQueueCharFaweChunk extends CharFaweChunk {
|
||||
|
||||
public NullQueueCharFaweChunk(int cx, int cz) {
|
||||
super(null, cx, cz);
|
||||
}
|
||||
|
||||
public NullQueueCharFaweChunk(int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(null, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNewChunk() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
if (shallow) {
|
||||
return new NullQueueCharFaweChunk(getX(), getZ(), ids, count, air, heightMap);
|
||||
} else {
|
||||
return new NullQueueCharFaweChunk(getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -350,9 +350,9 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
if (parent != null) {
|
||||
parentNMS.sendBlockUpdate(blockMap, players);
|
||||
parentNMS.sendBlockUpdate(chunk, players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
@ -146,6 +147,20 @@ public abstract class FaweChunk<T> implements Callable<FaweChunk> {
|
||||
|
||||
public abstract byte[] getBiomeArray();
|
||||
|
||||
public void forEachQueuedBlock(FaweChunkVisitor onEach) {
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int combined = getBlockCombinedId(x, y, z);
|
||||
if (combined == 0) {
|
||||
continue;
|
||||
}
|
||||
onEach.run(x, y, z, combined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public char[][] getCombinedIdArrays() {
|
||||
char[][] ids = new char[HEIGHT >> 4][];
|
||||
for (int y = 0; y < HEIGHT >> 4; y++) {
|
||||
|
@ -209,7 +209,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
try {
|
||||
if (file.exists() && file.length() > 5) {
|
||||
DiskOptimizedClipboard doc = new DiskOptimizedClipboard(file);
|
||||
Player player = getPlayer();
|
||||
Player player = toWorldEditPlayer();
|
||||
LocalSession session = getSession();
|
||||
try {
|
||||
if (session.getClipboard() != null) {
|
||||
@ -331,7 +331,16 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
* Get the WorldEdit player object
|
||||
* @return
|
||||
*/
|
||||
public abstract Player getPlayer();
|
||||
public abstract Player toWorldEditPlayer();
|
||||
|
||||
private Player cachedWorldEditPlayer;
|
||||
|
||||
public Player getPlayer() {
|
||||
if (cachedWorldEditPlayer == null) {
|
||||
cachedWorldEditPlayer = toWorldEditPlayer();
|
||||
}
|
||||
return cachedWorldEditPlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's current selection (or null)
|
||||
@ -382,7 +391,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
* @param selector
|
||||
*/
|
||||
public void setSelection(final RegionSelector selector) {
|
||||
this.getSession().setRegionSelector(getPlayer().getWorld(), selector);
|
||||
this.getSession().setRegionSelector(toWorldEditPlayer().getWorld(), selector);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -422,7 +431,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
public void unregister() {
|
||||
if (Settings.IMP.HISTORY.DELETE_ON_LOGOUT) {
|
||||
session = getSession();
|
||||
WorldEdit.getInstance().removeSession(getPlayer());
|
||||
WorldEdit.getInstance().removeSession(toWorldEditPlayer());
|
||||
session.setClipboard(null);
|
||||
session.clearHistory();
|
||||
}
|
||||
@ -433,7 +442,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
* Get a new EditSession from this player
|
||||
*/
|
||||
public EditSession getNewEditSession() {
|
||||
return WorldEdit.getInstance().getEditSessionFactory().getEditSession(getWorld(), -1, getPlayer());
|
||||
return WorldEdit.getInstance().getEditSessionFactory().getEditSession(getWorld(), -1, toWorldEditPlayer());
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,6 @@ import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
@ -308,7 +307,7 @@ public abstract class FaweQueue implements HasFaweQueue {
|
||||
return count;
|
||||
}
|
||||
|
||||
public abstract void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players);
|
||||
public abstract void sendBlockUpdate(FaweChunk chunk, FawePlayer... players);
|
||||
|
||||
@Deprecated
|
||||
public boolean next() {
|
||||
|
@ -0,0 +1,48 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
|
||||
public class CircleBrush extends VisualBrush {
|
||||
private final Player player;
|
||||
|
||||
public CircleBrush(BrushTool tool, Player player) {
|
||||
super(tool);
|
||||
this.player = LocationMaskedPlayerWrapper.unwrap(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
switch (action) {
|
||||
case PRIMARY:
|
||||
LocalBlockVectorSet set = new LocalBlockVectorSet();
|
||||
int radius = (int) size;
|
||||
Vector normal = position.subtract(player.getPosition());
|
||||
editSession.makeCircle(position, pattern, size, size, size, false, normal);
|
||||
break;
|
||||
case SECONDARY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector any90Rotate(Vector normal) {
|
||||
normal = normal.normalize();
|
||||
if (normal.getX() == 1 || normal.getY() == 1 || normal.getZ() == 1) {
|
||||
return new Vector(normal.getZ(), normal.getX(), normal.getY());
|
||||
}
|
||||
AffineTransform affine = new AffineTransform();
|
||||
affine = affine.rotateX(90);
|
||||
affine = affine.rotateY(90);
|
||||
affine = affine.rotateZ(90);
|
||||
Vector random = affine.apply(normal);
|
||||
return random.cross(normal).normalize();
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
@ -23,14 +24,14 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
|
||||
public class CopyPastaBrush implements DoubleActionBrush {
|
||||
|
||||
private final DoubleActionBrushTool tool;
|
||||
private final BrushTool tool;
|
||||
|
||||
public CopyPastaBrush(DoubleActionBrushTool tool) {
|
||||
public CopyPastaBrush(BrushTool tool) {
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
FawePlayer fp = editSession.getPlayer();
|
||||
LocalSession session = fp.getSession();
|
||||
switch (action) {
|
||||
|
@ -3,8 +3,16 @@ package com.boydti.fawe.object.brush;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public interface DoubleActionBrush {
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException;
|
||||
public interface DoubleActionBrush extends Brush {
|
||||
|
||||
@Override
|
||||
default void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
build(BrushTool.BrushAction.PRIMARY, editSession, position, pattern, size);
|
||||
}
|
||||
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException;
|
||||
}
|
||||
|
@ -1,239 +0,0 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldVector;
|
||||
import com.sk89q.worldedit.command.tool.DoubleActionTraceTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
||||
|
||||
public enum BrushAction {
|
||||
PRIMARY,
|
||||
SECONDARY
|
||||
}
|
||||
|
||||
protected static int MAX_RANGE = 500;
|
||||
protected int range = -1;
|
||||
private Mask mask = null;
|
||||
private Mask sourceMask = null;
|
||||
private ResettableExtent transform = null;
|
||||
private DoubleActionBrush brush = null;
|
||||
@Nullable
|
||||
private Pattern material;
|
||||
private double size = 1;
|
||||
private String permission;
|
||||
|
||||
/**
|
||||
* Construct the tool.
|
||||
*
|
||||
* @param permission the permission to check before use is allowed
|
||||
*/
|
||||
public DoubleActionBrushTool(String permission) {
|
||||
checkNotNull(permission);
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Actor player) {
|
||||
return player.hasPermission(permission);
|
||||
}
|
||||
|
||||
public ResettableExtent getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
public void setTransform(ResettableExtent transform) {
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter.
|
||||
*
|
||||
* @return the filter
|
||||
*/
|
||||
public Mask getMask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter.
|
||||
*
|
||||
* @return the filter
|
||||
*/
|
||||
public Mask getSourceMask() {
|
||||
return sourceMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setMask(Mask filter) {
|
||||
this.mask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setSourceMask(Mask filter) {
|
||||
this.sourceMask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the brush.
|
||||
*
|
||||
* @param brush tbe brush
|
||||
* @param permission the permission
|
||||
*/
|
||||
public void setBrush(DoubleActionBrush brush, String permission) {
|
||||
this.brush = brush;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current brush.
|
||||
*
|
||||
* @return the current brush
|
||||
*/
|
||||
public DoubleActionBrush getBrush() {
|
||||
return brush;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the material.
|
||||
*
|
||||
* @param material the material
|
||||
*/
|
||||
public void setFill(@Nullable Pattern material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material.
|
||||
*
|
||||
* @return the material
|
||||
*/
|
||||
@Nullable public Pattern getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set brush size.
|
||||
*
|
||||
* @return a radius
|
||||
*/
|
||||
public double getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the set brush size.
|
||||
*
|
||||
* @param radius a radius
|
||||
*/
|
||||
public void setSize(double radius) {
|
||||
this.size = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set brush range.
|
||||
*
|
||||
* @return the range of the brush in blocks
|
||||
*/
|
||||
public int getRange() {
|
||||
return (range < 0) ? MAX_RANGE : Math.min(range, MAX_RANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the set brush range.
|
||||
*
|
||||
* @param range the range of the brush in blocks
|
||||
*/
|
||||
public void setRange(int range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
WorldVector target = null;
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
BlockBag bag = session.getBlockBag(player);
|
||||
|
||||
EditSession editSession = session.createEditSession(player);
|
||||
Request.request().setEditSession(editSession);
|
||||
if (mask != null) {
|
||||
Mask existingMask = editSession.getMask();
|
||||
|
||||
if (existingMask == null) {
|
||||
editSession.setMask(mask);
|
||||
} else if (existingMask instanceof MaskIntersection) {
|
||||
((MaskIntersection) existingMask).add(mask);
|
||||
} else {
|
||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||
newMask.add(mask);
|
||||
editSession.setMask(newMask);
|
||||
}
|
||||
}
|
||||
if (sourceMask != null) {
|
||||
Mask existingMask = editSession.getSourceMask();
|
||||
|
||||
if (existingMask == null) {
|
||||
editSession.setSourceMask(sourceMask);
|
||||
} else if (existingMask instanceof MaskIntersection) {
|
||||
((MaskIntersection) existingMask).add(sourceMask);
|
||||
} else {
|
||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||
newMask.add(sourceMask);
|
||||
editSession.setSourceMask(newMask);
|
||||
}
|
||||
}
|
||||
if (transform != null) {
|
||||
editSession.addTransform(transform);
|
||||
}
|
||||
try {
|
||||
brush.build(action, editSession, target, material, size);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached."); // Never happens
|
||||
} finally {
|
||||
if (bag != null) {
|
||||
bag.flushChanges();
|
||||
}
|
||||
session.remember(editSession);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
return act(BrushAction.PRIMARY, server, config, player, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
return act(BrushAction.SECONDARY, server, config, player, session);
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -20,7 +21,7 @@ public class ErodeBrush implements DoubleActionBrush {
|
||||
private static final Vector[] FACES_TO_CHECK = {new Vector(0, 0, 1), new Vector(0, 0, -1), new Vector(0, 1, 0), new Vector(0, -1, 0), new Vector(1, 0, 0), new Vector(-1, 0, 0)};
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
switch (action) {
|
||||
case PRIMARY: {
|
||||
int erodeFaces = 2;
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
@ -12,18 +13,18 @@ import java.io.InputStream;
|
||||
|
||||
public class FlattenBrush extends HeightBrush {
|
||||
|
||||
public FlattenBrush(InputStream stream, int rotation, double yscale, DoubleActionBrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) {
|
||||
public FlattenBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) {
|
||||
super(stream, rotation, yscale, tool, clipboard, shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
int size = (int) sizeDouble;
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||
mask = null;
|
||||
}
|
||||
heightMap.setSize(size);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, action == DoubleActionBrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, true);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, action == BrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, true);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
@ -18,14 +19,13 @@ public class HeightBrush implements DoubleActionBrush {
|
||||
public final ScalableHeightMap heightMap;
|
||||
public final int rotation;
|
||||
public final double yscale;
|
||||
public final DoubleActionBrushTool tool;
|
||||
public final BrushTool tool;
|
||||
|
||||
public HeightBrush(InputStream stream, int rotation, double yscale, DoubleActionBrushTool tool, Clipboard clipboard) {
|
||||
public HeightBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard) {
|
||||
this(stream, rotation, yscale, tool, clipboard, ScalableHeightMap.Shape.CONE);
|
||||
}
|
||||
|
||||
public HeightBrush(InputStream stream, int rotation, double yscale, DoubleActionBrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) {
|
||||
this.tool = tool;
|
||||
public HeightBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) {
|
||||
this.rotation = (rotation / 90) % 4;
|
||||
this.yscale = yscale;
|
||||
if (stream != null) {
|
||||
@ -39,16 +39,17 @@ public class HeightBrush implements DoubleActionBrush {
|
||||
} else {
|
||||
heightMap = ScalableHeightMap.fromShape(shape);
|
||||
}
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
int size = (int) sizeDouble;
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||
mask = null;
|
||||
}
|
||||
heightMap.setSize(size);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, action == DoubleActionBrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, false);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, action == BrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, false);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.brush;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
|
||||
@ -18,7 +19,7 @@ public class LineBrush implements DoubleActionBrush {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
switch (action) {
|
||||
case PRIMARY:
|
||||
if (pos1 == null) {
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
|
||||
public interface MovableBrush {
|
||||
public boolean move(Player player);
|
||||
}
|
@ -3,13 +3,14 @@ package com.boydti.fawe.object.brush;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class RaiseBrush implements DoubleActionBrush {
|
||||
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
switch (action) {
|
||||
case PRIMARY:
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.object.visitor.DFSRecursiveVisitor;
|
||||
@ -9,6 +10,7 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -16,8 +18,6 @@ import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
import com.sk89q.worldedit.math.interpolation.Interpolation;
|
||||
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
||||
import com.sk89q.worldedit.math.interpolation.Node;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import java.util.ArrayList;
|
||||
@ -30,11 +30,11 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
private ArrayList<ArrayList<Vector>> positionSets;
|
||||
private int numSplines;
|
||||
|
||||
private final DoubleActionBrushTool tool;
|
||||
private final BrushTool tool;
|
||||
private final LocalSession session;
|
||||
private final Player player;
|
||||
|
||||
public SplineBrush(Player player, LocalSession session, DoubleActionBrushTool tool) {
|
||||
public SplineBrush(Player player, LocalSession session, BrushTool tool) {
|
||||
this.tool = tool;
|
||||
this.session = session;
|
||||
this.player = player;
|
||||
@ -42,15 +42,20 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, final Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, final Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == null) {
|
||||
mask = new IdMask(editSession);
|
||||
} else {
|
||||
mask = new MaskIntersection(mask, new IdMask(editSession));
|
||||
}
|
||||
boolean visualization = editSession.getExtent() instanceof VisualExtent;
|
||||
if (visualization && positionSets.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int originalSize = numSplines;
|
||||
switch (action) {
|
||||
case PRIMARY: { // Right
|
||||
case PRIMARY: {
|
||||
if (positionSets.size() >= MAX_POINTS) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||
}
|
||||
@ -62,6 +67,17 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
return true;
|
||||
}
|
||||
}, (int) size, 1);
|
||||
Collection<Vector> directions = visitor.getDirections();
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
Vector pos = new Vector(x, y, z);
|
||||
if (!directions.contains(pos)) {
|
||||
directions.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor.visit(position);
|
||||
Operations.completeBlindly(visitor);
|
||||
if (points.size() > numSplines) {
|
||||
@ -69,7 +85,9 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
}
|
||||
this.positionSets.add(points);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY.s());
|
||||
break;
|
||||
if (!visualization) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SECONDARY: {
|
||||
if (positionSets.size() < 2) {
|
||||
@ -88,7 +106,6 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
|
||||
final List<Node> nodes = new ArrayList<Node>(centroids.size());
|
||||
|
||||
final Interpolation interpol = new KochanekBartelsInterpolation();
|
||||
for (final Vector nodevector : centroids) {
|
||||
final Node n = new Node(nodevector);
|
||||
n.setTension(tension);
|
||||
@ -113,8 +130,13 @@ public class SplineBrush implements DoubleActionBrush {
|
||||
editSession.drawSpline(Patterns.wrap(pattern), currentSpline, 0, 0, 0, 10, 0, true);
|
||||
}
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s());
|
||||
positionSets.clear();
|
||||
numSplines = 0;
|
||||
if (visualization) {
|
||||
positionSets.clear();
|
||||
numSplines = 0;
|
||||
} else {
|
||||
numSplines = originalSize;
|
||||
positionSets.remove(positionSets.size() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
public enum TargetMode {
|
||||
TARGET_BLOCK_RANGE,
|
||||
FOWARD_POINT_PITCH,
|
||||
TARGET_POINT_HEIGHT,
|
||||
TARGET_POINT_RANGE,
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
|
||||
public abstract class ScrollAction implements ScrollableBrush {
|
||||
public final BrushTool tool;
|
||||
|
||||
public ScrollAction(BrushTool tool) {
|
||||
this.tool = tool;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
public class ScrollClipboard {
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
|
||||
public class ScrollMask extends ScrollAction {
|
||||
private final Mask[] masks;
|
||||
private int index;
|
||||
|
||||
public ScrollMask(BrushTool tool, Mask... masks) {
|
||||
super(tool);
|
||||
this.masks = masks;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean increment(int amount) {
|
||||
if (masks.length > 1) {
|
||||
tool.setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class ScrollPattern extends ScrollAction {
|
||||
private final Pattern[] patterns;
|
||||
private int index;
|
||||
|
||||
public ScrollPattern(BrushTool tool, Pattern... patterns) {
|
||||
super(tool);
|
||||
this.patterns = patterns;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean increment(int amount) {
|
||||
if (patterns.length > 1) {
|
||||
tool.setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
|
||||
public class ScrollRange extends ScrollAction {
|
||||
public ScrollRange(BrushTool tool) {
|
||||
super(tool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean increment(int amount) {
|
||||
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
|
||||
int newSize = MathMan.wrap(tool.getRange() + amount, (int) (tool.getSize() + 1), max);
|
||||
tool.setRange(newSize);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
|
||||
public class ScrollSize extends ScrollAction {
|
||||
public ScrollSize(BrushTool tool) {
|
||||
super(tool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean increment(int amount) {
|
||||
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
||||
double newSize = Math.max(0, Math.min(max, tool.getSize() + amount));
|
||||
tool.setSize(newSize);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
public interface ScrollableBrush {
|
||||
public boolean increment(int amount);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrush;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class DelegateVisualBrush extends VisualBrush {
|
||||
private final Brush brush;
|
||||
|
||||
public DelegateVisualBrush(BrushTool tool, Brush brush) {
|
||||
super(tool);
|
||||
this.brush = brush;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
switch (action) {
|
||||
case PRIMARY:
|
||||
brush.build(editSession, position, pattern, size);
|
||||
break;
|
||||
case SECONDARY:
|
||||
if (brush instanceof DoubleActionBrush) {
|
||||
((DoubleActionBrush) brush).build(BrushTool.BrushAction.SECONDARY, editSession, position, pattern, size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrush;
|
||||
import com.boydti.fawe.object.brush.MovableBrush;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollableBrush;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public abstract class VisualBrush implements DoubleActionBrush, MovableBrush, ScrollableBrush {
|
||||
|
||||
private Lock lock = new ReentrantLock();
|
||||
private final BrushTool tool;
|
||||
private VisualExtent visualExtent;
|
||||
private TargetMode mode;
|
||||
|
||||
public VisualBrush(BrushTool tool) {
|
||||
this.tool = tool;
|
||||
this.mode = TargetMode.TARGET_POINT_RANGE;
|
||||
}
|
||||
|
||||
public BrushTool getTool() {
|
||||
return tool;
|
||||
}
|
||||
|
||||
public TargetMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void setMode(TargetMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException;
|
||||
|
||||
public Vector getPosition(EditSession editSession, Player player) {
|
||||
switch (mode) {
|
||||
case TARGET_BLOCK_RANGE:
|
||||
return player.getBlockTrace(tool.getRange(), false);
|
||||
case FOWARD_POINT_PITCH: {
|
||||
int d = 0;
|
||||
Location loc = player.getLocation();
|
||||
float pitch = loc.getPitch();
|
||||
pitch = 23 - (pitch / 4);
|
||||
d += (int) (Math.sin(Math.toRadians(pitch)) * 50);
|
||||
final Vector vector = loc.getDirection().setY(0).normalize().multiply(d);
|
||||
vector.add(loc.getX(), loc.getY(), loc.getZ()).toBlockVector();
|
||||
return vector;
|
||||
}
|
||||
case TARGET_POINT_HEIGHT: {
|
||||
Location loc = player.getLocation();
|
||||
final int height = loc.getBlockY();
|
||||
final int x = loc.getBlockX();
|
||||
final int z = loc.getBlockZ();
|
||||
int y;
|
||||
for (y = height; y > 0; y--) {
|
||||
BaseBlock block = editSession.getBlock(x, y, z);
|
||||
if (!FaweCache.isLiquidOrGas(block.getId())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
final int distance = (height - y) + 8;
|
||||
return player.getBlockTrace(distance, true);
|
||||
}
|
||||
case TARGET_POINT_RANGE:
|
||||
return player.getBlockTrace(tool.getRange(), true);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void queueVisualization(FawePlayer player) {
|
||||
Fawe.get().getVisualQueue().queue(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualize the brush action
|
||||
* @deprecated It is preferred to visualize only if a visualization is not in progress
|
||||
* @param action
|
||||
* @param player
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
@Deprecated
|
||||
public synchronized void visualize(BrushTool.BrushAction action, Player player) throws MaxChangedBlocksException {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
EditSession editSession = new EditSessionBuilder(player.getWorld())
|
||||
.player(fp)
|
||||
.allowedRegionsEverywhere()
|
||||
.autoQueue(false)
|
||||
.blockBag(null)
|
||||
.changeSetNull()
|
||||
.combineStages(false)
|
||||
.build();
|
||||
VisualExtent newVisualExtent = new VisualExtent(editSession.getExtent(), editSession.getQueue());
|
||||
editSession.setExtent(newVisualExtent);
|
||||
Vector position = getPosition(editSession, player);
|
||||
if (position != null) {
|
||||
build(BrushTool.BrushAction.PRIMARY, editSession, position, tool.getMaterial(), tool.getSize());
|
||||
}
|
||||
if (visualExtent != null) {
|
||||
// clear old data
|
||||
visualExtent.clear(newVisualExtent, fp);
|
||||
}
|
||||
visualExtent = newVisualExtent;
|
||||
newVisualExtent.visualize(fp);
|
||||
}
|
||||
|
||||
public void clear(Player player) {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
Fawe.get().getVisualQueue().dequeue(fp);
|
||||
if (visualExtent != null) {
|
||||
visualExtent.clear(null, fp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean increment(int amount) {
|
||||
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
|
||||
double newSize = Math.max(0, Math.min(max, tool.getSize() + amount));
|
||||
tool.setSize(newSize);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.collection.SparseBitSet;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* FAWE visualizations display glass (20) as a placeholder
|
||||
* - Using a non transparent block can cause FPS lag
|
||||
*/
|
||||
public class VisualChunk extends FaweChunk<FaweChunk> {
|
||||
|
||||
public static int VISUALIZE_BLOCK = (95 << 4);
|
||||
|
||||
private SparseBitSet add;
|
||||
private SparseBitSet remove;
|
||||
|
||||
/**
|
||||
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
||||
*
|
||||
* @param x
|
||||
* @param z
|
||||
*/
|
||||
public VisualChunk(int x, int z) {
|
||||
super(null, x, z);
|
||||
this.add = new SparseBitSet();
|
||||
this.remove = new SparseBitSet();
|
||||
}
|
||||
|
||||
protected VisualChunk(int x, int z, SparseBitSet add, SparseBitSet remove) {
|
||||
super(null, x, z);
|
||||
this.add = add;
|
||||
this.remove = remove;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return add.cardinality() + remove.cardinality();
|
||||
}
|
||||
|
||||
private final int getIndex(int x, int y, int z) {
|
||||
return MathMan.tripleBlockCoordChar(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitMask() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockCombinedId(int x, int y, int z) {
|
||||
int index = getIndex(x, y, z);
|
||||
if (add.get(index)) {
|
||||
return VISUALIZE_BLOCK;
|
||||
} else if (remove.get(index)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachQueuedBlock(FaweChunkVisitor onEach) {
|
||||
int index = -1;
|
||||
while ((index = add.nextSetBit(index + 1)) != -1) {
|
||||
int x = MathMan.untripleBlockCoordX(index);
|
||||
int y = MathMan.untripleBlockCoordY(index);
|
||||
int z = MathMan.untripleBlockCoordZ(index);
|
||||
onEach.run(x, y, z, VISUALIZE_BLOCK);
|
||||
}
|
||||
index = -1;
|
||||
while ((index = remove.nextSetBit(index + 1)) != -1) {
|
||||
int x = MathMan.untripleBlockCoordX(index);
|
||||
int y = MathMan.untripleBlockCoordY(index);
|
||||
int z = MathMan.untripleBlockCoordZ(index);
|
||||
onEach.run(x, y, z, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBiomeArray() {
|
||||
return new byte[256];
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getChunk() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||
// Unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag entity) {
|
||||
// Unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(UUID uuid) {
|
||||
// Unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int index = getIndex(x, y, z);
|
||||
try {
|
||||
if (id == 0) {
|
||||
add.clear(index);
|
||||
remove.set(index);
|
||||
} else {
|
||||
remove.clear(index);
|
||||
add.set(index);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unset(int x, int y, int z) {
|
||||
int index = getIndex(x, y, z);
|
||||
remove.clear(index);
|
||||
add.clear(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getEntityRemoves() {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Short, CompoundTag> getTiles() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, byte biome) {
|
||||
// Unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk copy(boolean shallow) {
|
||||
if (shallow) {
|
||||
return new VisualChunk(getX(), getZ(), add, remove);
|
||||
} else {
|
||||
return new VisualChunk(getX(), getZ(), add.clone(), remove.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NullQueueCharFaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
|
||||
public class VisualExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final FaweQueue queue;
|
||||
private Long2ObjectMap<VisualChunk> chunks = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
public VisualExtent(Extent parent, FaweQueue queue) {
|
||||
super(parent);
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
|
||||
return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block);
|
||||
}
|
||||
|
||||
public VisualChunk getChunk(int cx, int cz) {
|
||||
return chunks.get(MathMan.pairInt(cx, cz));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
BaseBlock previous = super.getLazyBlock(x, y, z);
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
long chunkPair = MathMan.pairInt(cx, cz);
|
||||
VisualChunk chunk = chunks.get(chunkPair);
|
||||
if (previous.equals(block)) {
|
||||
if (chunk != null) {
|
||||
chunk.unset(x, y, z);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (chunk == null) {
|
||||
chunk = new VisualChunk(cx, cz);
|
||||
chunks.put(chunkPair, chunk);
|
||||
}
|
||||
chunk.setBlock(x, y, z, block.getId(), block.getData());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome biome) {
|
||||
// Do nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clear(VisualExtent other, FawePlayer... players) {
|
||||
ObjectIterator<Long2ObjectMap.Entry<VisualChunk>> iter = chunks.long2ObjectEntrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Long2ObjectMap.Entry<VisualChunk> entry = iter.next();
|
||||
long pair = entry.getLongKey();
|
||||
int cx = MathMan.unpairIntX(pair);
|
||||
int cz = MathMan.unpairIntY(pair);
|
||||
VisualChunk chunk = entry.getValue();
|
||||
final VisualChunk otherChunk = other != null ? other.getChunk(cx, cz) : null;
|
||||
final CharFaweChunk newChunk = new NullQueueCharFaweChunk(cx, cz);
|
||||
final int bx = cx << 4;
|
||||
final int bz = cz << 4;
|
||||
if (otherChunk == null) {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
combined = queue.getCombinedId4Data(bx + localX, y, bz + localZ, 0);
|
||||
newChunk.setBlock(localX, y, localZ, FaweCache.getId(combined), FaweCache.getData(combined));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
if (combined != otherChunk.getBlockCombinedId(localX, y, localZ)) {
|
||||
combined = queue.getCombinedId4Data(bx + localX, y, bz + localZ, 0);
|
||||
newChunk.setBlock(localX, y, localZ, FaweCache.getId(combined), FaweCache.getData(combined));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (newChunk.getTotalCount() != 0) {
|
||||
queue.sendBlockUpdate(newChunk, players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visualize(FawePlayer players) {
|
||||
for (VisualChunk chunk : chunks.values()) {
|
||||
queue.sendBlockUpdate(chunk, players);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
public enum VisualMode {
|
||||
NONE,
|
||||
POINT,
|
||||
OUTLINE
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.boydti.fawe.object.brush.visualization;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.Tool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class VisualQueue {
|
||||
|
||||
private ConcurrentHashMap<FawePlayer, Long> playerMap;
|
||||
|
||||
public VisualQueue() {
|
||||
playerMap = new ConcurrentHashMap<>();
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long allowedTick = Fawe.get().getTimer().getTick() - 1;
|
||||
Iterator<Map.Entry<FawePlayer, Long>> iter = playerMap.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<FawePlayer, Long> entry = iter.next();
|
||||
Long time = entry.getValue();
|
||||
if (time < allowedTick) {
|
||||
FawePlayer fp = entry.getKey();
|
||||
iter.remove();
|
||||
LocalSession session = fp.getSession();
|
||||
Player player = fp.getPlayer();
|
||||
Tool tool = session.getTool(player.getItemInHand());
|
||||
Brush brush;
|
||||
if (tool instanceof BrushTool) {
|
||||
brush = ((BrushTool) tool).getBrush();
|
||||
} else if (tool instanceof VisualBrush) {
|
||||
brush = (Brush) tool;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (brush instanceof VisualBrush) {
|
||||
try {
|
||||
((VisualBrush) brush).visualize(BrushTool.BrushAction.PRIMARY, player);
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskManager.IMP.laterAsync(this, 3);
|
||||
}
|
||||
};
|
||||
TaskManager.IMP.laterAsync(task, 3);
|
||||
}
|
||||
|
||||
public boolean dequeue(FawePlayer player) {
|
||||
return playerMap.remove(player) != null;
|
||||
}
|
||||
|
||||
public void queue(FawePlayer player) {
|
||||
playerMap.put(player, Fawe.get().getTimer().getTick());
|
||||
}
|
||||
}
|
@ -75,19 +75,8 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
|
||||
private void init(UUID uuid, String worldName) {
|
||||
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + worldName + File.separator + uuid);
|
||||
int max = 0;
|
||||
if (folder.exists()) {
|
||||
for (File file : folder.listFiles()) {
|
||||
String name = file.getName().split("\\.")[0];
|
||||
if (name.matches("\\d+")) {
|
||||
int index = Integer.parseInt(name);
|
||||
if (index > max) {
|
||||
max = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
init(uuid, ++max);
|
||||
int max = MainUtil.getMaxFileId(folder);
|
||||
init(uuid, max);
|
||||
}
|
||||
|
||||
public DiskStorageHistory(String world, UUID uuid, int index) {
|
||||
|
@ -69,6 +69,11 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean flushAsync() {
|
||||
return closeAsync();
|
||||
}
|
||||
|
||||
public boolean closeAsync() {
|
||||
waitingAsync.incrementAndGet();
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
|
@ -53,6 +53,7 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
|
||||
final Vector pos = new Vector();
|
||||
if (region instanceof CuboidRegion) {
|
||||
if (air) {
|
||||
((CuboidRegion) region).setUseOldIterator(true);
|
||||
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
||||
@Override
|
||||
public boolean apply(Vector pos) throws WorldEditException {
|
||||
@ -76,27 +77,33 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
|
||||
}, editSession);
|
||||
Operations.completeBlindly(visitor);
|
||||
} else {
|
||||
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
||||
CuboidRegion cuboidEquivalent = new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint());
|
||||
cuboidEquivalent.setUseOldIterator(true);
|
||||
RegionVisitor visitor = new RegionVisitor(cuboidEquivalent, new RegionFunction() {
|
||||
@Override
|
||||
public boolean apply(Vector pos) throws WorldEditException {
|
||||
int x = pos.getBlockX();
|
||||
int y = pos.getBlockY();
|
||||
int z = pos.getBlockZ();
|
||||
BaseBlock block = getBlockAbs(x, y, z);
|
||||
if (block == EditSession.nullBlock) {
|
||||
return false;
|
||||
if (region.contains(pos)) {
|
||||
int x = pos.getBlockX();
|
||||
int y = pos.getBlockY();
|
||||
int z = pos.getBlockZ();
|
||||
BaseBlock block = getBlockAbs(x, y, z);
|
||||
pos.mutX(x - mx);
|
||||
pos.mutY(y - my);
|
||||
pos.mutZ(z - mz);
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("x", new IntTag(pos.getBlockX()));
|
||||
values.put("y", new IntTag(pos.getBlockY()));
|
||||
values.put("z", new IntTag(pos.getBlockZ()));
|
||||
}
|
||||
task.run(pos, block);
|
||||
} else {
|
||||
pos.mutX(pos.getBlockX() - mx);
|
||||
pos.mutY(pos.getBlockY() - my);
|
||||
pos.mutZ(pos.getBlockZ() - mz);
|
||||
task.run(pos, EditSession.nullBlock);
|
||||
}
|
||||
pos.mutX(x - mx);
|
||||
pos.mutY(y - my);
|
||||
pos.mutZ(z - mz);
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("x", new IntTag(pos.getBlockX()));
|
||||
values.put("y", new IntTag(pos.getBlockY()));
|
||||
values.put("z", new IntTag(pos.getBlockZ()));
|
||||
}
|
||||
task.run(pos, block);
|
||||
return true;
|
||||
}
|
||||
}, editSession);
|
||||
|
43
core/src/main/java/com/boydti/fawe/object/io/PGZIPBlock.java
Normal file
43
core/src/main/java/com/boydti/fawe/object/io/PGZIPBlock.java
Normal file
@ -0,0 +1,43 @@
|
||||
package com.boydti.fawe.object.io;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class PGZIPBlock implements Callable<byte[]> {
|
||||
public PGZIPBlock(final PGZIPOutputStream parent) {
|
||||
STATE = new PGZIPThreadLocal(parent);
|
||||
}
|
||||
|
||||
/** This ThreadLocal avoids the recycling of a lot of memory, causing lumpy performance. */
|
||||
protected final ThreadLocal<PGZIPState> STATE;
|
||||
public static final int SIZE = 64 * 1024;
|
||||
// private final int index;
|
||||
protected final byte[] in = new byte[SIZE];
|
||||
protected int in_length = 0;
|
||||
|
||||
/*
|
||||
public Block(@Nonnegative int index) {
|
||||
this.index = index;
|
||||
}
|
||||
*/
|
||||
// Only on worker thread
|
||||
@Override
|
||||
public byte[] call() throws Exception {
|
||||
// LOG.info("Processing " + this + " on " + Thread.currentThread());
|
||||
|
||||
PGZIPState state = STATE.get();
|
||||
// ByteArrayOutputStream buf = new ByteArrayOutputStream(in.length); // Overestimate output size required.
|
||||
// DeflaterOutputStream def = newDeflaterOutputStream(buf);
|
||||
state.def.reset();
|
||||
state.buf.reset();
|
||||
state.str.write(in, 0, in_length);
|
||||
state.str.flush();
|
||||
|
||||
// return Arrays.copyOf(in, in_length);
|
||||
return state.buf.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Block" /* + index */ + "(" + in_length + "/" + in.length + " bytes)";
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@ public class PGZIPOutputStream extends FilterOutputStream {
|
||||
private int strategy = Deflater.HUFFMAN_ONLY;
|
||||
|
||||
@Nonnull
|
||||
private Deflater newDeflater() {
|
||||
protected Deflater newDeflater() {
|
||||
Deflater def = new Deflater(level, true);
|
||||
def.setStrategy(strategy);
|
||||
return def;
|
||||
@ -52,63 +52,16 @@ public class PGZIPOutputStream extends FilterOutputStream {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static DeflaterOutputStream newDeflaterOutputStream(@Nonnull OutputStream out, @Nonnull Deflater deflater) {
|
||||
protected static DeflaterOutputStream newDeflaterOutputStream(@Nonnull OutputStream out, @Nonnull Deflater deflater) {
|
||||
return new DeflaterOutputStream(out, deflater, 512, true);
|
||||
}
|
||||
|
||||
private class Block implements Callable<byte[]> {
|
||||
|
||||
private class State {
|
||||
|
||||
private final Deflater def = newDeflater();
|
||||
private final ByteArrayOutputStream buf = new ByteArrayOutputStream(SIZE);
|
||||
private final DeflaterOutputStream str = newDeflaterOutputStream(buf, def);
|
||||
}
|
||||
/** This ThreadLocal avoids the recycling of a lot of memory, causing lumpy performance. */
|
||||
private final ThreadLocal<State> STATE = new ThreadLocal<State>() {
|
||||
@Override
|
||||
protected State initialValue() {
|
||||
return new State();
|
||||
}
|
||||
};
|
||||
public static final int SIZE = 64 * 1024;
|
||||
// private final int index;
|
||||
private final byte[] in = new byte[SIZE];
|
||||
private int in_length = 0;
|
||||
|
||||
/*
|
||||
public Block(@Nonnegative int index) {
|
||||
this.index = index;
|
||||
}
|
||||
*/
|
||||
// Only on worker thread
|
||||
@Override
|
||||
public byte[] call() throws Exception {
|
||||
// LOG.info("Processing " + this + " on " + Thread.currentThread());
|
||||
|
||||
State state = STATE.get();
|
||||
// ByteArrayOutputStream buf = new ByteArrayOutputStream(in.length); // Overestimate output size required.
|
||||
// DeflaterOutputStream def = newDeflaterOutputStream(buf);
|
||||
state.def.reset();
|
||||
state.buf.reset();
|
||||
state.str.write(in, 0, in_length);
|
||||
state.str.flush();
|
||||
|
||||
// return Arrays.copyOf(in, in_length);
|
||||
return state.buf.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Block" /* + index */ + "(" + in_length + "/" + in.length + " bytes)";
|
||||
}
|
||||
}
|
||||
// TODO: Share, daemonize.
|
||||
private final ExecutorService executor;
|
||||
private final int nthreads;
|
||||
private final CRC32 crc = new CRC32();
|
||||
private final BlockingQueue<Future<byte[]>> emitQueue;
|
||||
private Block block = new Block(/* 0 */);
|
||||
private PGZIPBlock block = new PGZIPBlock(this/* 0 */);
|
||||
/** Used as a sentinel for 'closed'. */
|
||||
private int bytesWritten = 0;
|
||||
|
||||
@ -201,7 +154,7 @@ public class PGZIPOutputStream extends FilterOutputStream {
|
||||
private void submit() throws IOException {
|
||||
emitUntil(nthreads - 1);
|
||||
emitQueue.add(executor.submit(block));
|
||||
block = new Block(/* block.index + 1 */);
|
||||
block = new PGZIPBlock(this/* block.index + 1 */);
|
||||
}
|
||||
|
||||
// Emit If Available - submit always
|
||||
|
19
core/src/main/java/com/boydti/fawe/object/io/PGZIPState.java
Normal file
19
core/src/main/java/com/boydti/fawe/object/io/PGZIPState.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.boydti.fawe.object.io;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
public class PGZIPState {
|
||||
protected final DeflaterOutputStream str;
|
||||
protected final ByteArrayOutputStream buf;
|
||||
protected final Deflater def;
|
||||
|
||||
public PGZIPState(PGZIPOutputStream parent) {
|
||||
this.def = parent.newDeflater();
|
||||
this.buf = new ByteArrayOutputStream(PGZIPBlock.SIZE);
|
||||
this.str = parent.newDeflaterOutputStream(buf, def);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.boydti.fawe.object.io;
|
||||
|
||||
public class PGZIPThreadLocal extends ThreadLocal<PGZIPState> {
|
||||
|
||||
private final PGZIPOutputStream parent;
|
||||
|
||||
public PGZIPThreadLocal(PGZIPOutputStream parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PGZIPState initialValue() {
|
||||
return new PGZIPState(parent);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.boydti.fawe.object.visitor;
|
||||
|
||||
public abstract class FaweChunkVisitor {
|
||||
/**
|
||||
* The will run for each set block in the chunk
|
||||
* @param localX The x position in the chunk (0-15)
|
||||
* @param y The y position (0 - 255)
|
||||
* @param localZ The z position in the chunk (0-15)
|
||||
* @param combined The combined id
|
||||
*/
|
||||
public abstract void run(int localX, int y, int localZ, int combined);
|
||||
}
|
@ -16,7 +16,6 @@ import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
@ -222,8 +221,8 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
parent.sendBlockUpdate(blockMap, players);
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
parent.sendBlockUpdate(chunk, players);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
@ -56,6 +56,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
@ -180,6 +181,29 @@ public class MainUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMaxFileId(File folder) {
|
||||
final AtomicInteger max = new AtomicInteger();
|
||||
if (folder.exists()) {
|
||||
MainUtil.traverse(folder.toPath(), new RunnableVal2<Path, BasicFileAttributes>() {
|
||||
@Override
|
||||
public void run(Path path, BasicFileAttributes attr) {
|
||||
try {
|
||||
String file = path.getFileName().toString();
|
||||
int index = file.indexOf('.');
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
int id = Integer.parseInt(file.substring(0, index));
|
||||
if (id > max.get()) {
|
||||
max.set(id);
|
||||
}
|
||||
} catch (NumberFormatException ignore){}
|
||||
}
|
||||
});
|
||||
}
|
||||
return max.get() + 1;
|
||||
}
|
||||
|
||||
public static File getFile(File base, String path) {
|
||||
if (Paths.get(path).isAbsolute()) {
|
||||
return new File(path);
|
||||
|
@ -43,6 +43,20 @@ public class MathMan {
|
||||
253, 254, 254, 255
|
||||
};
|
||||
|
||||
public static final int wrap(int value, int min, int max) {
|
||||
if (max <= min) {
|
||||
return value;
|
||||
}
|
||||
int diff = max - min + 1;
|
||||
if (value < min) {
|
||||
return max - ((min - value) % diff);
|
||||
} else if (value > max) {
|
||||
return min + ((value - min) % diff);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static final long inverseRound(double val) {
|
||||
long round = Math.round(val);
|
||||
return (long) (round + Math.signum(val - round));
|
||||
@ -84,6 +98,22 @@ public class MathMan {
|
||||
return (short) ((x & 15) << 12 | (z & 15) << 8 | y);
|
||||
}
|
||||
|
||||
public static final char tripleBlockCoordChar(int x, int y, int z) {
|
||||
return (char) ((x & 15) << 12 | (z & 15) << 8 | y);
|
||||
}
|
||||
|
||||
public static final int untripleBlockCoordX(int triple) {
|
||||
return (triple >> 12) & 0xF;
|
||||
}
|
||||
|
||||
public static final int untripleBlockCoordY(int triple) {
|
||||
return (triple & 0xFF);
|
||||
}
|
||||
|
||||
public static final int untripleBlockCoordZ(int triple) {
|
||||
return (triple >> 8) & 0xF;
|
||||
}
|
||||
|
||||
public static int tripleSearchCoords(int x, int y, int z) {
|
||||
byte b1 = (byte) y;
|
||||
byte b3 = (byte) (x);
|
||||
|
@ -4,15 +4,21 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweVersion;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Updater {
|
||||
private static FaweVersion newVersion = null;
|
||||
private FaweVersion newVersion;
|
||||
private String changes = "N/A";
|
||||
|
||||
public static void update(String platform, FaweVersion currentVersion) {
|
||||
public String getChanges() throws IOException {
|
||||
return changes;
|
||||
}
|
||||
|
||||
public void update(String platform, FaweVersion currentVersion) {
|
||||
if (currentVersion == null || platform == null) {
|
||||
return;
|
||||
}
|
||||
@ -42,7 +48,11 @@ public class Updater {
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
Fawe.debug("Updated FAWE to " + versionString);
|
||||
MainUtil.sendAdmin("Restart to update FAWE with these changes: " + "http://boydti.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash));
|
||||
Scanner scanner = new Scanner(new URL("http://boydti.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash)).openStream(), "UTF-8");
|
||||
changes = scanner.useDelimiter("\\A").next();
|
||||
scanner.close();
|
||||
MainUtil.sendAdmin("&7Restart to update FAWE with these changes: &c/fawe changelog &7or&c " + "http://boydti.com/fawe/cl?" + Integer.toHexString(currentVersion.hash));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class FakePlayer extends LocalPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return FakePlayer.this;
|
||||
}
|
||||
};
|
||||
|
@ -84,6 +84,10 @@ public class BlockVector extends Vector {
|
||||
|
||||
}
|
||||
|
||||
public boolean equals(BlockVector obj) {
|
||||
return obj.getBlockX() == this.getBlockX() && obj.getBlockY() == this.getBlockY() && obj.getBlockZ() == this.getBlockZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((int) getX() ^ ((int) getZ() << 16)) ^ ((int) getY() << 30);
|
||||
|
@ -454,14 +454,14 @@ public class CuboidClipboard {
|
||||
}
|
||||
if (reverse) {
|
||||
for (int i = 0; i < numRotations; ++i) {
|
||||
if (block.hasWildcardData()) {
|
||||
if (block.isImmutable()) {
|
||||
block = new BaseBlock(block);
|
||||
}
|
||||
block.rotate90Reverse();
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < numRotations; ++i) {
|
||||
if (block.hasWildcardData()) {
|
||||
if (block.isImmutable()) {
|
||||
block = new BaseBlock(block);
|
||||
}
|
||||
block.rotate90();
|
||||
|
@ -415,6 +415,22 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
return traverser == null ? null : traverser.get();
|
||||
}
|
||||
|
||||
public Extent getBypassAll() {
|
||||
return bypassAll;
|
||||
}
|
||||
|
||||
public Extent getBypassHistory() {
|
||||
return bypassHistory;
|
||||
}
|
||||
|
||||
public Extent getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
public void setExtent(AbstractDelegateExtent extent) {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FawePlayer or null
|
||||
* @return
|
||||
@ -2151,20 +2167,26 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
final double invRadiusX = 1 / radiusX;
|
||||
final double invRadiusZ = 1 / radiusZ;
|
||||
|
||||
int px = pos.getBlockX();
|
||||
int py = pos.getBlockY();
|
||||
int pz = pos.getBlockZ();
|
||||
MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||
|
||||
double dx, dxz, dz;
|
||||
double nextXn = 0;
|
||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
nextXn = (x + 1) * invRadiusX;
|
||||
double nextZn = 0;
|
||||
dx = xn * xn;
|
||||
forZ: for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
nextZn = (z + 1) * invRadiusZ;
|
||||
|
||||
final double distanceSq = this.lengthSq(xn, zn);
|
||||
if (distanceSq > 1) {
|
||||
dz = zn * zn;
|
||||
dxz = dx + dz;
|
||||
if (dxz > 1) {
|
||||
if (z == 0) {
|
||||
break forX;
|
||||
}
|
||||
@ -2172,16 +2194,16 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
}
|
||||
|
||||
if (!filled) {
|
||||
if ((this.lengthSq(nextXn, zn) <= 1) && (this.lengthSq(xn, nextZn) <= 1)) {
|
||||
if ((dz + nextXn * nextXn <= 1) && (nextZn * nextZn + dx <= 1)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
this.setBlock(pos.add(x, y, z), block);
|
||||
this.setBlock(pos.add(-x, y, z), block);
|
||||
this.setBlock(pos.add(x, y, -z), block);
|
||||
this.setBlock(pos.add(-x, y, -z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py + y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py + y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py + y, pz - z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py + y, pz - z), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2189,6 +2211,82 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
return this.changes;
|
||||
}
|
||||
|
||||
public int makeCircle(Vector pos, final Pattern block, double radiusX, double radiusY, double radiusZ, boolean filled, Vector normal) throws MaxChangedBlocksException {
|
||||
radiusX += 0.5;
|
||||
radiusY += 0.5;
|
||||
radiusZ += 0.5;
|
||||
|
||||
normal = normal.normalize();
|
||||
double nx = normal.getX();
|
||||
double ny = normal.getY();
|
||||
double nz = normal.getZ();
|
||||
|
||||
|
||||
final double invRadiusX = 1 / radiusX;
|
||||
final double invRadiusY = 1 / radiusY;
|
||||
final double invRadiusZ = 1 / radiusZ;
|
||||
|
||||
int px = pos.getBlockX();
|
||||
int py = pos.getBlockY();
|
||||
int pz = pos.getBlockZ();
|
||||
MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||
final int ceilRadiusY = (int) Math.ceil(radiusY);
|
||||
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||
|
||||
double threshold = 0.5;
|
||||
|
||||
LocalBlockVectorSet set = new LocalBlockVectorSet();
|
||||
|
||||
double nextXn = 0;
|
||||
double dx, dy, dz, dxy, dxyz;
|
||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
dx = xn * xn;
|
||||
nextXn = (x + 1) * invRadiusX;
|
||||
double nextYn = 0;
|
||||
forY: for (int y = 0; y <= ceilRadiusY; ++y) {
|
||||
final double yn = nextYn;
|
||||
dy = yn * yn;
|
||||
dxy = dx + dy;
|
||||
nextYn = (y + 1) * invRadiusY;
|
||||
double nextZn = 0;
|
||||
forZ: for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
dz = zn * zn;
|
||||
dxyz = dxy + dz;
|
||||
nextZn = (z + 1) * invRadiusZ;
|
||||
if (dxyz > 1) {
|
||||
if (z == 0) {
|
||||
if (y == 0) {
|
||||
break forX;
|
||||
}
|
||||
break forY;
|
||||
}
|
||||
break forZ;
|
||||
}
|
||||
if (!filled) {
|
||||
if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs((x) * nx + (y) * ny + (z) * nz) < threshold) setBlock(mutable.setComponents(px + x, py + y, pz + z), block);
|
||||
if (Math.abs((-x) * nx + (y) * ny + (z) * nz) < threshold) setBlock(mutable.setComponents(px - x, py + y, pz + z), block);
|
||||
if (Math.abs((x) * nx + (-y) * ny + (z) * nz) < threshold) setBlock(mutable.setComponents(px + x, py - y, pz + z), block);
|
||||
if (Math.abs((x) * nx + (y) * ny + (-z) * nz) < threshold) setBlock(mutable.setComponents(px + x, py + y, pz - z), block);
|
||||
if (Math.abs((-x) * nx + (-y) * ny + (z) * nz) < threshold) setBlock(mutable.setComponents(px - x, py - y, pz + z), block);
|
||||
if (Math.abs((x) * nx + (-y) * ny + (-z) * nz) < threshold) setBlock(mutable.setComponents(px + x, py - y, pz - z), block);
|
||||
if (Math.abs((-x) * nx + (y) * ny + (-z) * nz) < threshold) setBlock(mutable.setComponents(px - x, py + y, pz - z), block);
|
||||
if (Math.abs((-x) * nx + (-y) * ny + (-z) * nz) < threshold) setBlock(mutable.setComponents(px - x, py - y, pz - z), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a sphere.
|
||||
*
|
||||
@ -2224,25 +2322,34 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
final double invRadiusY = 1 / radiusY;
|
||||
final double invRadiusZ = 1 / radiusZ;
|
||||
|
||||
int px = pos.getBlockX();
|
||||
int py = pos.getBlockY();
|
||||
int pz = pos.getBlockZ();
|
||||
MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||
final int ceilRadiusY = (int) Math.ceil(radiusY);
|
||||
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||
|
||||
double nextXn = 0;
|
||||
double dx, dy, dz, dxy, dxyz;
|
||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
dx = xn * xn;
|
||||
nextXn = (x + 1) * invRadiusX;
|
||||
double nextYn = 0;
|
||||
forY: for (int y = 0; y <= ceilRadiusY; ++y) {
|
||||
final double yn = nextYn;
|
||||
dy = yn * yn;
|
||||
dxy = dx + dy;
|
||||
nextYn = (y + 1) * invRadiusY;
|
||||
double nextZn = 0;
|
||||
forZ: for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
dz = zn * zn;
|
||||
dxyz = dxy + dz;
|
||||
nextZn = (z + 1) * invRadiusZ;
|
||||
|
||||
final double distanceSq = this.lengthSq(xn, yn, zn);
|
||||
if (distanceSq > 1) {
|
||||
if (dxyz > 1) {
|
||||
if (z == 0) {
|
||||
if (y == 0) {
|
||||
break forX;
|
||||
@ -2253,19 +2360,19 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
}
|
||||
|
||||
if (!filled) {
|
||||
if ((this.lengthSq(nextXn, yn, zn) <= 1) && (this.lengthSq(xn, nextYn, zn) <= 1) && (this.lengthSq(xn, yn, nextZn) <= 1)) {
|
||||
if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1 ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.setBlock(pos.add(x, y, z), block);
|
||||
this.setBlock(pos.add(-x, y, z), block);
|
||||
this.setBlock(pos.add(x, -y, z), block);
|
||||
this.setBlock(pos.add(x, y, -z), block);
|
||||
this.setBlock(pos.add(-x, -y, z), block);
|
||||
this.setBlock(pos.add(x, -y, -z), block);
|
||||
this.setBlock(pos.add(-x, y, -z), block);
|
||||
this.setBlock(pos.add(-x, -y, -z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py + y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py + y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py - y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py + y, pz - z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py - y, pz + z), block);
|
||||
this.setBlock(mutable.setComponents(px + x, py - y, pz - z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py + y, pz - z), block);
|
||||
this.setBlock(mutable.setComponents(px - x, py - y, pz - z), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2960,9 +3067,11 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
}
|
||||
|
||||
private Set<Vector> getBallooned(final Set<Vector> vset, final double radius) {
|
||||
if (radius < 1) {
|
||||
return vset;
|
||||
}
|
||||
final Set returnset = new LocalBlockVectorSet();
|
||||
final int ceilrad = (int) Math.ceil(radius);
|
||||
|
||||
for (final Vector v : vset) {
|
||||
final int tipx = v.getBlockX(), tipy = v.getBlockY(), tipz = v.getBlockZ();
|
||||
for (int loopx = tipx - ceilrad; loopx <= (tipx + ceilrad); loopx++) {
|
||||
@ -2979,6 +3088,9 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
}
|
||||
|
||||
private Set<Vector> getStretched(final Set<Vector> vset, final double radius) {
|
||||
if (radius < 1) {
|
||||
return vset;
|
||||
}
|
||||
final Set returnset = new LocalBlockVectorSet();
|
||||
final int ceilrad = (int) Math.ceil(radius);
|
||||
for (final Vector v : vset) {
|
||||
|
@ -25,7 +25,7 @@ import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrushTool;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
@ -42,6 +42,7 @@ import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||
import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
||||
import com.sk89q.worldedit.command.tool.Tool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
@ -440,6 +441,9 @@ public class LocalSession {
|
||||
}
|
||||
|
||||
public synchronized void remember(final EditSession editSession, final boolean append, final boolean sendMessage, int limitMb) {
|
||||
if (Settings.IMP.HISTORY.USE_DISK) {
|
||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||
}
|
||||
// It should have already been flushed, but just in case!
|
||||
editSession.flushQueue();
|
||||
if (editSession == null || editSession.getChangeSet() == null || limitMb == 0 || ((historySize >> 20) > limitMb && !append)) {
|
||||
@ -953,6 +957,14 @@ public class LocalSession {
|
||||
return tools.get(item);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tool getTool(Player player) {
|
||||
if (tools.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return getTool(player.getItemInHand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the brush tool assigned to the item. If there is no tool assigned
|
||||
* or the tool is not assigned, the slot will be replaced with the
|
||||
@ -963,36 +975,20 @@ public class LocalSession {
|
||||
* @throws InvalidToolBindException if the item can't be bound to that item
|
||||
*/
|
||||
public BrushTool getBrushTool(int item) throws InvalidToolBindException {
|
||||
return getBrushTool(item, null);
|
||||
}
|
||||
|
||||
public BrushTool getBrushTool(int item, Player player) throws InvalidToolBindException {
|
||||
Tool tool = getTool(item);
|
||||
|
||||
if (tool == null || !(tool instanceof BrushTool)) {
|
||||
tool = new BrushTool("worldedit.brush.sphere");
|
||||
setTool(item, tool);
|
||||
setTool(item, tool, player);
|
||||
}
|
||||
|
||||
return (BrushTool) tool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the brush tool assigned to the item. If there is no tool assigned
|
||||
* or the tool is not assigned, the slot will be replaced with the
|
||||
* brush tool.
|
||||
*
|
||||
* @param item the item type ID
|
||||
* @return the tool, or {@code null}
|
||||
* @throws InvalidToolBindException if the item can't be bound to that item
|
||||
*/
|
||||
public DoubleActionBrushTool getDoubleActionBrushTool(int item) throws InvalidToolBindException {
|
||||
Tool tool = getTool(item);
|
||||
|
||||
if (tool == null || !(tool instanceof DoubleActionBrushTool)) {
|
||||
tool = new DoubleActionBrushTool("worldedit.brush.sphere");
|
||||
setTool(item, tool);
|
||||
}
|
||||
|
||||
return (DoubleActionBrushTool) tool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tool.
|
||||
*
|
||||
@ -1001,6 +997,10 @@ public class LocalSession {
|
||||
* @throws InvalidToolBindException if the item can't be bound to that item
|
||||
*/
|
||||
public void setTool(int item, @Nullable Tool tool) throws InvalidToolBindException {
|
||||
setTool(item, tool, null);
|
||||
}
|
||||
|
||||
public void setTool(int item, @Nullable Tool tool, Player player) throws InvalidToolBindException {
|
||||
if (item > 0 && item < 255) {
|
||||
throw new InvalidToolBindException(item, "Blocks can't be used");
|
||||
} else if (item == config.wandItem) {
|
||||
@ -1008,8 +1008,17 @@ public class LocalSession {
|
||||
} else if (item == config.navigationWand) {
|
||||
throw new InvalidToolBindException(item, "Already used for the navigation wand");
|
||||
}
|
||||
|
||||
this.tools.put(item, tool);
|
||||
Tool previous = this.tools.put(item, tool);
|
||||
if (player != null) {
|
||||
if (previous instanceof BrushTool) {
|
||||
Brush brush = ((BrushTool) previous).getBrush();
|
||||
if (brush instanceof VisualBrush) {
|
||||
((VisualBrush) brush).clear(player);
|
||||
}
|
||||
} else if (previous instanceof VisualBrush) {
|
||||
((VisualBrush) tool).clear(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,17 @@
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
public class MutableBlockVector extends BlockVector {
|
||||
private static ThreadLocal<MutableBlockVector> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector>() {
|
||||
@Override
|
||||
protected MutableBlockVector initialValue() {
|
||||
return new MutableBlockVector();
|
||||
}
|
||||
};
|
||||
|
||||
public static Vector get(int x, int y, int z) {
|
||||
return MUTABLE_CACHE.get().setComponents(x, y, z);
|
||||
}
|
||||
|
||||
private int x,y,z;
|
||||
|
||||
public MutableBlockVector(Vector v) {
|
||||
|
421
core/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java
Normal file
421
core/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java
Normal file
@ -0,0 +1,421 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.blocks;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
|
||||
import com.sk89q.worldedit.foundation.Block;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents a mutable "snapshot" of a block.
|
||||
*
|
||||
* <p>An instance of this block contains all the information needed to
|
||||
* accurately reproduce the block, provided that the instance was
|
||||
* made correctly. In some implementations, it may not be possible to get a
|
||||
* snapshot of blocks correctly, so, for example, the NBT data for a block
|
||||
* may be missing.</p>
|
||||
*
|
||||
* <p>This class identifies blocks using an integer ID. However, IDs for
|
||||
* a given block may differ between worlds so it is important that users of
|
||||
* this class convert the ID from one "world space" to another "world space,"
|
||||
* a task that that is assisted with by working with the source and
|
||||
* destination {@link WorldData} instances. Numeric IDs are utilized because
|
||||
* they are more space efficient to store, and it also implies that internal
|
||||
* uses of this class (i.e. history, etc.) do not need to worry about
|
||||
* interning block string IDs.</p>
|
||||
*
|
||||
* <p>A peculiar detail of this class is that it accepts {@code -1} as a
|
||||
* valid data value. This is due to legacy reasons: WorldEdit uses -1
|
||||
* as a "wildcard" block value, even though a {@link Mask} would be
|
||||
* more appropriate.</p>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BaseBlock extends Block implements TileEntityBlock {
|
||||
|
||||
/**
|
||||
* Indicates the highest possible block ID (inclusive) that can be used.
|
||||
* This value is subject to change depending on the implementation, but
|
||||
* internally this class only supports a range of 4096 IDs (for space
|
||||
* reasons), which coincides with the number of possible IDs that official
|
||||
* Minecraft supports as of version 1.7.
|
||||
*/
|
||||
public static final int MAX_ID = 4095;
|
||||
|
||||
/**
|
||||
* Indicates the maximum data value (inclusive) that can be used. A future
|
||||
* version of Minecraft may abolish block data values.
|
||||
*/
|
||||
public static final int MAX_DATA = 15;
|
||||
|
||||
// Instances of this class should be _as small as possible_ because there will
|
||||
// be millions of instances of this object.
|
||||
|
||||
private short id;
|
||||
private short data;
|
||||
@Nullable
|
||||
private CompoundTag nbtData;
|
||||
|
||||
/**
|
||||
* Construct a block with the given ID and a data value of 0.
|
||||
*
|
||||
* @param id ID value
|
||||
* @see #setId(int)
|
||||
*/
|
||||
public BaseBlock(int id) {
|
||||
internalSetId(id);
|
||||
internalSetData(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a block with the given ID and data value.
|
||||
*
|
||||
* @param id ID value
|
||||
* @param data data value
|
||||
* @see #setId(int)
|
||||
* @see #setData(int)
|
||||
*/
|
||||
public BaseBlock(int id, int data) {
|
||||
internalSetId(id);
|
||||
internalSetData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a block with the given ID, data value and NBT data structure.
|
||||
*
|
||||
* @param id ID value
|
||||
* @param data data value
|
||||
* @param nbtData NBT data, which may be null
|
||||
*/
|
||||
public BaseBlock(int id, int data, @Nullable CompoundTag nbtData) {
|
||||
setId(id);
|
||||
setData(data);
|
||||
setNbtData(nbtData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of another block.
|
||||
*
|
||||
* @param other the other block
|
||||
*/
|
||||
public BaseBlock(BaseBlock other) {
|
||||
this(other.getId(), other.getData(), other.getNbtData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the block.
|
||||
*
|
||||
* @return ID (between 0 and {@link #MAX_ID})
|
||||
*/
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block ID.
|
||||
*
|
||||
* @param id block id (between 0 and {@link #MAX_ID}).
|
||||
*/
|
||||
protected final void internalSetId(int id) {
|
||||
if (id > MAX_ID) {
|
||||
throw new IllegalArgumentException("Can't have a block ID above "
|
||||
+ MAX_ID + " (" + id + " given)");
|
||||
}
|
||||
|
||||
if (id < 0) {
|
||||
throw new IllegalArgumentException("Can't have a block ID below 0");
|
||||
}
|
||||
|
||||
this.id = (short) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block ID.
|
||||
*
|
||||
* @param id block id (between 0 and {@link #MAX_ID}).
|
||||
*/
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
internalSetId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block's data value.
|
||||
*
|
||||
* @return data value (0-15)
|
||||
*/
|
||||
@Override
|
||||
public int getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block's data value.
|
||||
*
|
||||
* @param data block data value (between 0 and {@link #MAX_DATA}).
|
||||
*/
|
||||
protected final void internalSetData(int data) {
|
||||
if (data > MAX_DATA) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't have a block data value above " + MAX_DATA + " ("
|
||||
+ data + " given)");
|
||||
}
|
||||
|
||||
if (data < -1) {
|
||||
throw new IllegalArgumentException("Can't have a block data value below -1");
|
||||
}
|
||||
|
||||
this.data = (short) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block's data value.
|
||||
*
|
||||
* @param data block data value (between 0 and {@link #MAX_DATA}).
|
||||
*/
|
||||
@Override
|
||||
public void setData(int data) {
|
||||
internalSetData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both the block's ID and data value.
|
||||
*
|
||||
* @param id ID value
|
||||
* @param data data value
|
||||
* @see #setId(int)
|
||||
* @see #setData(int)
|
||||
*/
|
||||
@Override
|
||||
public void setIdAndData(int id, int data) {
|
||||
setId(id);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the data value is -1, indicating that this block is to be
|
||||
* used as a wildcard matching block.
|
||||
*
|
||||
* @return true if the data value is -1
|
||||
*/
|
||||
@Override
|
||||
public boolean hasWildcardData() {
|
||||
return getData() == -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbtData() {
|
||||
return getNbtData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNbtId() {
|
||||
CompoundTag nbtData = getNbtData();
|
||||
if (nbtData == null) {
|
||||
return "";
|
||||
}
|
||||
Tag idTag = nbtData.getValue().get("id");
|
||||
if (idTag != null && idTag instanceof StringTag) {
|
||||
return ((StringTag) idTag).getValue();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundTag getNbtData() {
|
||||
return nbtData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNbtData(@Nullable CompoundTag nbtData) {
|
||||
this.nbtData = nbtData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of block.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public int getType() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of block.
|
||||
*
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(int type) {
|
||||
setId(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it's air.
|
||||
*
|
||||
* @return if air
|
||||
*/
|
||||
public boolean isAir() {
|
||||
return getType() == BlockID.AIR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate this block 90 degrees.
|
||||
*
|
||||
* @return new data value
|
||||
* @deprecated Use {@link BlockData#rotate90(int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public int rotate90() {
|
||||
int newData = BlockData.rotate90(getType(), getData());
|
||||
setData(newData);
|
||||
return newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate this block -90 degrees.
|
||||
*
|
||||
* @return new data value
|
||||
* @deprecated Use {@link BlockData#rotate90Reverse(int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public int rotate90Reverse() {
|
||||
int newData = BlockData.rotate90Reverse(getType(), getData());
|
||||
setData((short) newData);
|
||||
return newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycle the damage value of the block forward or backward
|
||||
*
|
||||
* @param increment 1 for forward, -1 for backward
|
||||
* @return new data value
|
||||
* @deprecated Use {@link BlockData#cycle(int, int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public int cycleData(int increment) {
|
||||
int newData = BlockData.cycle(getType(), getData(), increment);
|
||||
setData((short) newData);
|
||||
return newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip this block.
|
||||
*
|
||||
* @return this block
|
||||
* @deprecated Use {@link BlockData#flip(int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BaseBlock flip() {
|
||||
setData((short) BlockData.flip(getType(), getData()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip this block.
|
||||
*
|
||||
* @param direction direction to flip in
|
||||
* @return this block
|
||||
* @deprecated Use {@link BlockData#flip(int, int, FlipDirection)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BaseBlock flip(FlipDirection direction) {
|
||||
setData((short) BlockData.flip(getType(), getData(), direction));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the type ID and data value are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof BaseBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BaseBlock otherBlock = (BaseBlock) o;
|
||||
|
||||
return getType() == otherBlock.getType() && getData() == otherBlock.getData();
|
||||
|
||||
}
|
||||
|
||||
public boolean equals(BaseBlock block) {
|
||||
return block.getId() == this.getId() && block.getData() == this.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the type is the same, and if data is the same if only data != -1.
|
||||
*
|
||||
* @param o other block
|
||||
* @return true if equal
|
||||
*/
|
||||
public boolean equalsFuzzy(BaseBlock o) {
|
||||
return (getType() == o.getType()) && (getData() == o.getData() || getData() == -1 || o.getData() == -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method is silly, use {@link #containsFuzzy(java.util.Collection, BaseBlock)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean inIterable(Iterable<BaseBlock> iter) {
|
||||
for (BaseBlock block : iter) {
|
||||
if (block.equalsFuzzy(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Blocks#containsFuzzy(Collection, BaseBlock)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean containsFuzzy(Collection<BaseBlock> collection, BaseBlock o) {
|
||||
return Blocks.containsFuzzy(collection, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int ret = getId() << 3;
|
||||
if (getData() != (byte) -1) ret |= getData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Block{ID:" + getId() + ", Data: " + getData() + "}";
|
||||
}
|
||||
|
||||
public boolean isImmutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Class<BaseBlock> inject() {
|
||||
return BaseBlock.class;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.sk89q.worldedit.blocks;
|
||||
|
||||
import com.sk89q.worldedit.CuboidClipboard;
|
||||
|
||||
public class ImmutableBlock extends BaseBlock {
|
||||
public ImmutableBlock(int id, int data) {
|
||||
super(id, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(int data) {
|
||||
throw new IllegalStateException("Cannot set data");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
throw new IllegalStateException("Cannot set id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock flip() {
|
||||
BaseBlock clone = new BaseBlock(getId(), getData(), getNbtData());
|
||||
return clone.flip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock flip(CuboidClipboard.FlipDirection direction) {
|
||||
BaseBlock clone = new BaseBlock(getId(), getData(), getNbtData());
|
||||
return clone.flip(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.sk89q.worldedit.blocks;
|
||||
|
||||
public class ImmutableDatalessBlock extends ImmutableBlock {
|
||||
public ImmutableDatalessBlock(int id) {
|
||||
super(id, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getData() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(BaseBlock block) {
|
||||
return block.getId() == this.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof BaseBlock) {
|
||||
return ((BaseBlock) o).getId() == this.getId();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -25,9 +25,9 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.BlendBall;
|
||||
import com.boydti.fawe.object.brush.CircleBrush;
|
||||
import com.boydti.fawe.object.brush.CommandBrush;
|
||||
import com.boydti.fawe.object.brush.CopyPastaBrush;
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrushTool;
|
||||
import com.boydti.fawe.object.brush.ErodeBrush;
|
||||
import com.boydti.fawe.object.brush.FlattenBrush;
|
||||
import com.boydti.fawe.object.brush.HeightBrush;
|
||||
@ -106,9 +106,9 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.blendball")
|
||||
public void blendBallBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new BlendBall(), "worldedit.brush.blendball");
|
||||
tool.setBrush(new BlendBall(), "worldedit.brush.blendball", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_BLEND_BALL.f(radius));
|
||||
}
|
||||
|
||||
@ -123,12 +123,30 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.erode")
|
||||
public void erodeBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new ErodeBrush(), "worldedit.brush.erode");
|
||||
tool.setBrush(new ErodeBrush(), "worldedit.brush.erode", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "circle" },
|
||||
usage = "<pattern> [radius]",
|
||||
desc = "Choose the circle brush",
|
||||
help = "Chooses the circle brush.",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.sphere")
|
||||
public void circleBrush(Player player, LocalSession session, Pattern fill, @Optional("5") double radius, @Switch('h') boolean hollow) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setFill(fill);
|
||||
tool.setBrush(new CircleBrush(tool, player), "worldedit.brush.circle", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_CIRCLE.f(radius));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "recursive", "recurse", "r" },
|
||||
usage = "<pattern-to> [radius]",
|
||||
@ -141,9 +159,9 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.recursive")
|
||||
public void recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("2") double radius, @Switch('d') boolean depthFirst) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new RecurseBrush(tool, depthFirst), "worldedit.brush.recursive");
|
||||
tool.setBrush(new RecurseBrush(tool, depthFirst), "worldedit.brush.recursive", player);
|
||||
tool.setMask(new IdMask(editSession));
|
||||
tool.setFill(fill);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_RECURSIVE.f(radius));
|
||||
@ -165,10 +183,10 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.line")
|
||||
public void lineBrush(Player player, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new LineBrush(shell, select, flat), "worldedit.brush.line");
|
||||
tool.setBrush(new LineBrush(shell, select, flat), "worldedit.brush.line", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_LINE.f(radius));
|
||||
}
|
||||
|
||||
@ -183,10 +201,10 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.spline")
|
||||
public void splineBrush(Player player, LocalSession session, Pattern fill, @Optional("25") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new SplineBrush(player, session, tool), "worldedit.brush.spline");
|
||||
tool.setBrush(new SplineBrush(player, session, tool), "worldedit.brush.spline", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
|
||||
}
|
||||
|
||||
@ -205,14 +223,14 @@ public class BrushCommands {
|
||||
public void sphereBrush(Player player, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
|
||||
if (hollow) {
|
||||
tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere");
|
||||
tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere", player);
|
||||
} else {
|
||||
tool.setBrush(new SphereBrush(), "worldedit.brush.sphere");
|
||||
tool.setBrush(new SphereBrush(), "worldedit.brush.sphere", player);
|
||||
}
|
||||
if (fill instanceof BlockPattern) {
|
||||
BaseBlock block = ((BlockPattern) fill).getBlock();
|
||||
@ -245,14 +263,14 @@ public class BrushCommands {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
worldEdit.checkMaxBrushRadius(height);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
|
||||
if (hollow) {
|
||||
tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder");
|
||||
tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder", player);
|
||||
} else {
|
||||
tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder");
|
||||
tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder", player);
|
||||
}
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPHERE.f(radius, height));
|
||||
}
|
||||
@ -279,8 +297,8 @@ public class BrushCommands {
|
||||
worldEdit.checkMaxBrushRadius(size.getBlockY());
|
||||
worldEdit.checkMaxBrushRadius(size.getBlockZ());
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin), "worldedit.brush.clipboard");
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin), "worldedit.brush.clipboard", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_CLIPBOARD.s());
|
||||
}
|
||||
|
||||
@ -305,9 +323,9 @@ public class BrushCommands {
|
||||
FawePlayer fp = FawePlayer.wrap(player);
|
||||
FaweLimit limit = Settings.IMP.getLimit(fp);
|
||||
iterations = Math.min(limit.MAX_ITERATIONS, iterations);
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new SmoothBrush(iterations, naturalBlocksOnly), "worldedit.brush.smooth");
|
||||
tool.setBrush(new SmoothBrush(iterations, naturalBlocksOnly), "worldedit.brush.smooth", player);
|
||||
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SMOOTH.f(radius, iterations, (naturalBlocksOnly ? "natural blocks only" : "any block")));
|
||||
}
|
||||
@ -323,12 +341,12 @@ public class BrushCommands {
|
||||
public void extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
Pattern fill = new BlockPattern(new BaseBlock(0));
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setMask(new BlockMask(editSession, new BaseBlock(BlockID.FIRE)));
|
||||
tool.setBrush(new SphereBrush(), "worldedit.brush.ex");
|
||||
tool.setBrush(new SphereBrush(), "worldedit.brush.ex", player);
|
||||
BBC.BRUSH_EXTINGUISHER.send(player, radius);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_EXTINGUISHER.f(radius));
|
||||
}
|
||||
@ -349,9 +367,9 @@ public class BrushCommands {
|
||||
public void gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new GravityBrush(fromMaxY, tool), "worldedit.brush.gravity");
|
||||
tool.setBrush(new GravityBrush(fromMaxY, tool), "worldedit.brush.gravity", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_GRAVITY.f(radius));
|
||||
}
|
||||
|
||||
@ -431,19 +449,19 @@ public class BrushCommands {
|
||||
}
|
||||
}
|
||||
|
||||
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
if (flat) {
|
||||
try {
|
||||
tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape), "worldedit.brush.height");
|
||||
tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape), "worldedit.brush.height", player);
|
||||
} catch (EmptyClipboardException ignore) {
|
||||
tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, null, shape), "worldedit.brush.height");
|
||||
tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, null, shape), "worldedit.brush.height", player);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null), "worldedit.brush.height");
|
||||
tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null), "worldedit.brush.height", player);
|
||||
} catch (EmptyClipboardException ignore) {
|
||||
tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, null), "worldedit.brush.height");
|
||||
tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, null), "worldedit.brush.height", player);
|
||||
}
|
||||
}
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_HEIGHT.f(radius));
|
||||
@ -464,9 +482,9 @@ public class BrushCommands {
|
||||
@CommandPermissions("worldedit.brush.copy")
|
||||
public void copy(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new CopyPastaBrush(tool), "worldedit.brush.copy");
|
||||
tool.setBrush(new CopyPastaBrush(tool), "worldedit.brush.copy", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
|
||||
}
|
||||
|
||||
@ -481,9 +499,9 @@ public class BrushCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.command")
|
||||
public void command(Player player, LocalSession session, @Optional("5") double radius, CommandContext args) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
String cmd = args.getJoinedStrings(1);
|
||||
tool.setBrush(new CommandBrush(tool, cmd, radius), "worldedit.brush.copy");
|
||||
tool.setBrush(new CommandBrush(tool, cmd, radius), "worldedit.brush.copy", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_COMMAND.f(cmd));
|
||||
}
|
||||
|
||||
@ -526,9 +544,9 @@ public class BrushCommands {
|
||||
CreatureButcher flags = new CreatureButcher(player);
|
||||
flags.fromCommand(args);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher");
|
||||
tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_BUTCHER.f(radius));
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class ToolCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.tool.inspect")
|
||||
public void inspectBrush(Player player, LocalSession session, @Optional("1") double radius) throws WorldEditException {
|
||||
session.setTool(player.getItemInHand(), new InspectBrush());
|
||||
session.setTool(player.getItemInHand(), new InspectBrush(), player);
|
||||
BBC.TOOL_INSPECT.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ public class ToolCommands {
|
||||
max = 0
|
||||
)
|
||||
public void none(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
session.setTool(player.getItemInHand(), null);
|
||||
session.setTool(player.getItemInHand(), null, player);
|
||||
BBC.TOOL_NONE.send(player);
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ public class ToolCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.tool.info")
|
||||
public void info(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
session.setTool(player.getItemInHand(), new QueryTool());
|
||||
session.setTool(player.getItemInHand(), new QueryTool(), player);
|
||||
BBC.TOOL_INFO.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ public class ToolCommands {
|
||||
return;
|
||||
}
|
||||
|
||||
session.setTool(player.getItemInHand(), new TreePlanter(new TreeGenerator(type)));
|
||||
session.setTool(player.getItemInHand(), new TreePlanter(new TreeGenerator(type)), player);
|
||||
BBC.TOOL_TREE.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ public class ToolCommands {
|
||||
@CommandPermissions("worldedit.tool.replacer")
|
||||
public void repl(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BaseBlock targetBlock = we.getBlock(player, args.getString(0));
|
||||
session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock));
|
||||
session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock), player);
|
||||
BBC.TOOL_REPL.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ public class ToolCommands {
|
||||
@CommandPermissions("worldedit.tool.data-cycler")
|
||||
public void cycler(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
|
||||
session.setTool(player.getItemInHand(), new BlockDataCyler());
|
||||
session.setTool(player.getItemInHand(), new BlockDataCyler(), player);
|
||||
BBC.TOOL_CYCLER.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ public class ToolCommands {
|
||||
}
|
||||
|
||||
Pattern pattern = we.getBlockPattern(player, args.getString(0));
|
||||
session.setTool(player.getItemInHand(), new FloodFillTool(range, pattern));
|
||||
session.setTool(player.getItemInHand(), new FloodFillTool(range, pattern), player);
|
||||
BBC.TOOL_FLOOD_FILL.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ public class ToolCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.tool.deltree")
|
||||
public void deltree(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
session.setTool(player.getItemInHand(), new FloatingTreeRemover());
|
||||
session.setTool(player.getItemInHand(), new FloatingTreeRemover(), player);
|
||||
BBC.TOOL_DELTREE.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ public class ToolCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.tool.farwand")
|
||||
public void farwand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
session.setTool(player.getItemInHand(), new DistanceWand());
|
||||
session.setTool(player.getItemInHand(), new DistanceWand(), player);
|
||||
BBC.TOOL_FARWAND.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ public class ToolCommands {
|
||||
|
||||
BaseBlock secondary = we.getBlock(player, args.getString(0));
|
||||
BaseBlock primary = we.getBlock(player, args.getString(1));
|
||||
session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary));
|
||||
session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary), player);
|
||||
BBC.TOOL_LRBUILD_BOUND.send(player, ItemType.toHeldName(player.getItemInHand()));
|
||||
BBC.TOOL_LRBUILD_INFO.send(player, ItemType.toName(secondary.getType()), ItemType.toName(primary.getType()));
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrushTool;
|
||||
import com.boydti.fawe.object.extent.DefaultTransformParser;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
@ -77,8 +76,6 @@ public class ToolUtilCommands {
|
||||
if (context == null || context.argsLength() == 0) {
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setMask(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setMask(null);
|
||||
}
|
||||
BBC.BRUSH_MASK_DISABLED.send(player);
|
||||
} else {
|
||||
@ -90,8 +87,6 @@ public class ToolUtilCommands {
|
||||
Mask mask = we.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setMask(mask);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setMask(mask);
|
||||
}
|
||||
BBC.BRUSH_MASK.send(player);
|
||||
}
|
||||
@ -114,8 +109,6 @@ public class ToolUtilCommands {
|
||||
if (context == null || context.argsLength() == 0) {
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setSourceMask(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setMask(null);
|
||||
}
|
||||
BBC.BRUSH_SOURCE_MASK_DISABLED.send(player);
|
||||
} else {
|
||||
@ -127,8 +120,6 @@ public class ToolUtilCommands {
|
||||
Mask mask = we.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setSourceMask(mask);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setSourceMask(mask);
|
||||
}
|
||||
BBC.BRUSH_SOURCE_MASK.send(player);
|
||||
}
|
||||
@ -150,8 +141,6 @@ public class ToolUtilCommands {
|
||||
if (context == null || context.argsLength() == 0) {
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setTransform(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setTransform(null);
|
||||
}
|
||||
BBC.BRUSH_TRANSFORM_DISABLED.send(player);
|
||||
} else {
|
||||
@ -163,8 +152,6 @@ public class ToolUtilCommands {
|
||||
ResettableExtent transform = transformParser.parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setTransform(transform);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setTransform(transform);
|
||||
}
|
||||
BBC.BRUSH_TRANSFORM.send(player);
|
||||
}
|
||||
@ -181,9 +168,7 @@ public class ToolUtilCommands {
|
||||
public void material(Player player, LocalSession session, Pattern pattern) throws WorldEditException {
|
||||
Tool tool = session.getTool(player.getItemInHand());
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setMask(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setFill(pattern);
|
||||
((BrushTool) tool).setFill(pattern);
|
||||
}
|
||||
BBC.BRUSH_MATERIAL.send(player);
|
||||
}
|
||||
@ -197,12 +182,10 @@ public class ToolUtilCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.options.range")
|
||||
public void range(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
int range = args.getInteger(0);
|
||||
int range = Math.max(0, Math.min(256, args.getInteger(0)));
|
||||
Tool tool = session.getTool(player.getItemInHand());
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setMask(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setRange(range);
|
||||
((BrushTool) tool).setRange(range);
|
||||
}
|
||||
BBC.BRUSH_RANGE.send(player);
|
||||
}
|
||||
@ -222,9 +205,7 @@ public class ToolUtilCommands {
|
||||
|
||||
Tool tool = session.getTool(player.getItemInHand());
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).setMask(null);
|
||||
} else if (tool instanceof DoubleActionBrushTool) {
|
||||
((DoubleActionBrushTool) tool).setSize(radius);
|
||||
((BrushTool) tool).setSize(radius);
|
||||
}
|
||||
BBC.BRUSH_SIZE.send(player);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.sk89q.worldedit.command.tool;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.brush.DoubleActionBrush;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
@ -8,7 +10,6 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldVector;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.command.tool.brush.SphereBrush;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
@ -22,17 +23,19 @@ import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Builds a shape at the place being looked at.
|
||||
*/
|
||||
public class BrushTool implements TraceTool {
|
||||
public class BrushTool implements DoubleActionTraceTool {
|
||||
|
||||
public enum BrushAction {
|
||||
PRIMARY,
|
||||
SECONDARY
|
||||
}
|
||||
|
||||
protected static int MAX_RANGE = 500;
|
||||
protected int range = -1;
|
||||
private Mask mask = null;
|
||||
private Mask sourceMask = null;
|
||||
private ResettableExtent transform = null;
|
||||
private Brush brush = new SphereBrush();
|
||||
private Brush brush = null;
|
||||
@Nullable
|
||||
private Pattern material;
|
||||
private double size = 1;
|
||||
@ -70,15 +73,6 @@ public class BrushTool implements TraceTool {
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setMask(Mask filter) {
|
||||
this.mask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter.
|
||||
*
|
||||
@ -88,6 +82,15 @@ public class BrushTool implements TraceTool {
|
||||
return sourceMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setMask(Mask filter) {
|
||||
this.mask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
@ -104,6 +107,13 @@ public class BrushTool implements TraceTool {
|
||||
* @param permission the permission
|
||||
*/
|
||||
public void setBrush(Brush brush, String permission) {
|
||||
setBrush(brush, permission, null);
|
||||
}
|
||||
|
||||
public void setBrush(Brush brush, String permission, Player player) {
|
||||
if (player != null && brush instanceof VisualBrush) {
|
||||
((VisualBrush) brush).clear(player);
|
||||
}
|
||||
this.brush = brush;
|
||||
this.permission = permission;
|
||||
}
|
||||
@ -171,8 +181,10 @@ public class BrushTool implements TraceTool {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
if (action == BrushAction.SECONDARY && !(brush instanceof DoubleActionBrush)) {
|
||||
return false;
|
||||
}
|
||||
WorldVector target = null;
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
|
||||
@ -199,7 +211,7 @@ public class BrushTool implements TraceTool {
|
||||
}
|
||||
}
|
||||
if (sourceMask != null) {
|
||||
Mask existingMask = editSession.getMask();
|
||||
Mask existingMask = editSession.getSourceMask();
|
||||
|
||||
if (existingMask == null) {
|
||||
editSession.setSourceMask(sourceMask);
|
||||
@ -215,7 +227,11 @@ public class BrushTool implements TraceTool {
|
||||
editSession.addTransform(transform);
|
||||
}
|
||||
try {
|
||||
brush.build(editSession, target, material, size);
|
||||
if (brush instanceof DoubleActionBrush) {
|
||||
((DoubleActionBrush) brush).build(action, editSession, target, material, size);
|
||||
} else {
|
||||
brush.build(editSession, target, material, size);
|
||||
}
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached."); // Never happens
|
||||
} finally {
|
||||
@ -224,11 +240,20 @@ public class BrushTool implements TraceTool {
|
||||
}
|
||||
session.remember(editSession);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
return act(BrushAction.PRIMARY, server, config, player, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
return act(BrushAction.SECONDARY, server, config, player, session);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return BrushTool.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -447,14 +447,18 @@ public class PlatformManager {
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
|
||||
} else {
|
||||
actor.printError("Please report this error: [See console]");
|
||||
actor.printRaw(e.getClass().getName() + ": " + e.getMessage());
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
handleThrowable(e, actor);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleThrowable(Throwable e, Actor actor) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
|
||||
} else {
|
||||
actor.printError("Please report this error: [See console]");
|
||||
actor.printRaw(e.getClass().getName() + ": " + e.getMessage());
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
if (value != null && value.getDirection() != null) {
|
||||
StateValue newValue = getNewStateValue(state, transform, value.getDirection());
|
||||
if (newValue != null) {
|
||||
if (changedBlock.hasWildcardData()) {
|
||||
if (changedBlock.isImmutable()) {
|
||||
changedBlock = new BaseBlock(changedBlock.getId(), changedBlock.getData(), changedBlock.getNbtData());
|
||||
}
|
||||
newValue.set(changedBlock);
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Tests whether a given vector meets a criteria.
|
||||
*/
|
||||
public interface Mask extends com.sk89q.worldedit.masks.Mask {
|
||||
|
||||
/**
|
||||
* Returns true if the criteria is met.
|
||||
*
|
||||
* @param vector the vector to test
|
||||
* @return true if the criteria is met
|
||||
*/
|
||||
boolean test(Vector vector);
|
||||
|
||||
/**
|
||||
* Get the 2D version of this mask if one exists.
|
||||
*
|
||||
* @return a 2D mask version or {@code null} if this mask can't be 2D
|
||||
*/
|
||||
@Nullable
|
||||
Mask2D toMask2D();
|
||||
|
||||
default void prepare(LocalSession session, LocalPlayer player, Vector target) {}
|
||||
|
||||
default boolean matches(EditSession editSession, Vector position) {
|
||||
return test(position);
|
||||
}
|
||||
|
||||
public static Class<Mask> inject() {
|
||||
return Mask.class;
|
||||
}
|
||||
}
|
@ -17,39 +17,36 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.patterns;
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
|
||||
/**
|
||||
* @deprecated See {@link com.sk89q.worldedit.function.pattern.Pattern}
|
||||
* Returns a {@link BaseBlock} for a given position.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Pattern { //extends com.sk89q.worldedit.function.pattern.Pattern {
|
||||
public interface Pattern extends com.sk89q.worldedit.patterns.Pattern {
|
||||
|
||||
/**
|
||||
* Get a block for a position. This return value of this method does
|
||||
* not have to be consistent for the same position.
|
||||
* Return a {@link BaseBlock} for the given position.
|
||||
*
|
||||
* @param position the position where a block is needed
|
||||
* @param position the position
|
||||
* @return a block
|
||||
*/
|
||||
public BaseBlock next(Vector position);
|
||||
BaseBlock apply(Vector position);
|
||||
|
||||
/**
|
||||
* Get a block for a position. This return value of this method does
|
||||
* not have to be consistent for the same position.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param y the Y coordinate
|
||||
* @param z the Z coordinate
|
||||
* @return a block
|
||||
*/
|
||||
public BaseBlock next(int x, int y, int z);
|
||||
@Override
|
||||
default BaseBlock next(Vector position) {
|
||||
return apply(position);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// default BaseBlock apply(Vector position) {
|
||||
// return next(position);
|
||||
// }
|
||||
@Override
|
||||
default BaseBlock next(int x, int y, int z) {
|
||||
return apply(MutableBlockVector.get(x, y, z));
|
||||
}
|
||||
|
||||
public static Class<Pattern> inject() {
|
||||
return Pattern.class;
|
||||
}
|
||||
}
|
@ -22,6 +22,9 @@ public final class Patterns {
|
||||
* @return a new-style pattern
|
||||
*/
|
||||
public static Pattern wrap(final com.sk89q.worldedit.patterns.Pattern pattern) {
|
||||
if (pattern instanceof Pattern) {
|
||||
return (Pattern) pattern;
|
||||
}
|
||||
checkNotNull(pattern);
|
||||
return new Pattern() {
|
||||
@Override
|
||||
|
@ -14,11 +14,22 @@ import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BreadthFirstSearch implements Operation {
|
||||
|
||||
public static Vector[] DEFAULT_DIRECTIONS = new Vector[6];
|
||||
static {
|
||||
DEFAULT_DIRECTIONS[0] = (new MutableBlockVector(0, -1, 0));
|
||||
DEFAULT_DIRECTIONS[1] = (new MutableBlockVector(0, 1, 0));
|
||||
DEFAULT_DIRECTIONS[2] = (new MutableBlockVector(-1, 0, 0));
|
||||
DEFAULT_DIRECTIONS[3] = (new MutableBlockVector(1, 0, 0));
|
||||
DEFAULT_DIRECTIONS[4] = (new MutableBlockVector(0, 0, -1));
|
||||
DEFAULT_DIRECTIONS[5] = (new MutableBlockVector(0, 0, 1));
|
||||
}
|
||||
|
||||
private final RegionFunction function;
|
||||
private final List<Vector> directions = new ArrayList<>();
|
||||
private BlockVectorSet visited;
|
||||
@ -41,12 +52,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
this.queue = new BlockVectorSet();
|
||||
this.visited = new BlockVectorSet();
|
||||
this.function = function;
|
||||
this.directions.add(new Vector(0, -1, 0));
|
||||
this.directions.add(new Vector(0, 1, 0));
|
||||
this.directions.add(new Vector(-1, 0, 0));
|
||||
this.directions.add(new Vector(1, 0, 0));
|
||||
this.directions.add(new Vector(0, 0, -1));
|
||||
this.directions.add(new Vector(0, 0, 1));
|
||||
this.directions.addAll(Arrays.asList(DEFAULT_DIRECTIONS));
|
||||
this.maxDepth = maxDepth;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ public class RegionVisitor implements Operation {
|
||||
public final Iterable<? extends Vector> iterable;
|
||||
public final RegionFunction function;
|
||||
private final MappedFaweQueue queue;
|
||||
private boolean useCuboidIterator = false;
|
||||
public int affected = 0;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
private Vector pos1;
|
||||
private Vector pos2;
|
||||
private boolean useOldIterator;
|
||||
private int minX,minY,minZ,maxX,maxY,maxZ;
|
||||
|
||||
/**
|
||||
@ -80,6 +81,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
recalculate();
|
||||
}
|
||||
|
||||
public void setUseOldIterator(boolean useOldIterator) {
|
||||
this.useOldIterator = useOldIterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first cuboid-defining corner.
|
||||
*
|
||||
@ -400,7 +405,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
@Override
|
||||
public Iterator<BlockVector> iterator() {
|
||||
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9) {
|
||||
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) {
|
||||
return iterator_old();
|
||||
}
|
||||
return new Iterator<BlockVector>() {
|
||||
@ -445,7 +450,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
y = by;
|
||||
if (x > tx) {
|
||||
x = bx;
|
||||
if (z >= tz) {
|
||||
if (z > tz) {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("End of iterator") {
|
||||
@Override
|
||||
@ -494,10 +499,11 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
private int nextX = min.getBlockX();
|
||||
private int nextY = min.getBlockY();
|
||||
private int nextZ = min.getBlockZ();
|
||||
private boolean hasNext = true;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return (nextZ != Integer.MIN_VALUE);
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -507,10 +513,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
mutable.mutZ(nextZ);
|
||||
if (++nextX > max.getBlockX()) {
|
||||
nextX = min.getBlockX();
|
||||
if (++nextY > max.getBlockY()) {
|
||||
nextY = min.getBlockY();
|
||||
if (++nextZ > max.getBlockZ()) {
|
||||
if (nextZ == Integer.MIN_VALUE) {
|
||||
if (++nextZ > max.getBlockZ()) {
|
||||
nextZ = min.getBlockZ();
|
||||
if (++nextY > max.getBlockY()) {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("End of iterator") {
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
@ -519,8 +525,9 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
};
|
||||
}
|
||||
nextX = max.getBlockX();
|
||||
nextZ = max.getBlockZ();
|
||||
nextY = max.getBlockY();
|
||||
nextZ = Integer.MIN_VALUE;
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
311
core/src/main/resources/de/messages.yml
Normal file
311
core/src/main/resources/de/messages.yml
Normal file
@ -0,0 +1,311 @@
|
||||
info:
|
||||
prefix: '&4&lFAWE:&f&7'
|
||||
schematic_pasting: '&7Das Schematic wird eingefügt. Dies kann nicht rückgängig gemacht
|
||||
werden.'
|
||||
updated_lighting_selection: '&7Updates des Lichts werden in %s0 chunks durchgeführt.
|
||||
(Es kann einige Sekunden dauern bis die Pakete gesendet wurden.)'
|
||||
set_region: '&7Markierung wurde auf aktuelle WorldEdit Region übertragen.'
|
||||
worldedit_command_limit: '&7Bitte warte bist deine momentane Aktion fertig gestellt
|
||||
wurde.'
|
||||
worldedit_delayed: '&7Bitte warte während wir deine aktuelle WorldEdit Aktion durchführen...'
|
||||
worldedit_run: '&7Entschuldige die Verzögerung. Nun führen wir folgende Aktion von
|
||||
dir aus: %s'
|
||||
worldedit_complete: '&7WorldEdit Aktion fertiggestellt..'
|
||||
require_selection_in_mask: '&7%s deiner Auswahl ist nicht innerhalb deiner Maske.
|
||||
Du kannst du innerhalb erlaubter Regionen Veränderungen durchführen.'
|
||||
worldedit_volume: '&7Du kannst keine %current% verändern. Die maximale Anzahl an
|
||||
Blöcken die du verändern kannst ist %max%.'
|
||||
worldedit_iterations: '&7Du kannst keine Aktion %current% Mal wiederholen. Die maximale
|
||||
Anzahl an erlaubten Wiederholungen ist %max%.'
|
||||
worldedit_unsafe: '&7Der Zugang zu diesem Befehl wurde verboten.'
|
||||
worldedit_dangerous_worldedit: '&cFAWE führt unsicher WorldEdit Aktionen aus! Position:
|
||||
%s0 Username: %s1'
|
||||
worldedit_bypass: '&7&oUm deine Beschränkungen zu ignorieren nutze &c/wea'
|
||||
worldedit_bypassed: '&7Beschränkungen werden nun ignoriert.'
|
||||
worldedit_unmasked: '&6Deine WorldEdit Beschränkungen sind nun aufgehoben.'
|
||||
worldedit_restricted: '&6Deine WorldEdit Beschränkungen sind nun aktiv.'
|
||||
worldedit_oom_admin: |-
|
||||
&cPossible options:
|
||||
&8 - &7//fast
|
||||
&8 - &7Do smaller edits
|
||||
&8 - &7Allocate more memory
|
||||
&8 - &7Disable this safeguard
|
||||
compressed: WorldEdit Verlauf komprimiert. Saved ~ %s0b (%s1x smaller)
|
||||
action_complete: Aktion fertiggestellt in %s0 Sekunden
|
||||
lighting_propogate_selection: '&7Licht wurde berechnet in %s0 Chunks. (Info: Um
|
||||
Licht zu entfernen nutze //removelight)'
|
||||
worldedit_toggle_tips_on: '&7WorldEdit Tipps deaktiviert.'
|
||||
worldedit_toggle_tips_off: '&7WorldEdit Tipps aktiviert.'
|
||||
error:
|
||||
worldedit_extend: '&cDeine WorldEdit Aktion überschreitet die erlaubte Region'
|
||||
command_syntax: '&cBenutzung: &7%s0'
|
||||
no_perm: '&cDir fehlt die Berechtigung: %s0'
|
||||
setting_disable: '&cFehlende Einstellung: %s0'
|
||||
schematic_not_found: '&cSchematic nicht gefunden: &7%s0'
|
||||
no_region: '&cDu hast keine aktive WorldEdit Markierung'
|
||||
no_mask: '&cDu hast keine Mask gesetzt'
|
||||
not_player: '&cDieser Befehl kann nur von Spielern ausgeführt werden!'
|
||||
player_not_found: '&cSpieler nicht gefunden:&7 %s0'
|
||||
oom: |-
|
||||
&8[&cCritical&8] &cDetected low memory i.e. < 1%. FAWE will take the following actions:
|
||||
&8 - &7Terminate WE block placement
|
||||
&8 - &7Clear WE history
|
||||
&8 - &7Unload non essential chunks
|
||||
&8 - &7Kill entities
|
||||
&8 - &7Garbage collect
|
||||
&cIgnore this if trying to crash server.
|
||||
&7Note: Low memory is likely (but not necessarily) caused by WE
|
||||
worldedit_some_fails: '&c%s0 Blöcke wurden nicht platziert, da sie ausserhalb der
|
||||
erlaubten Region sind.'
|
||||
worldedit_some_fails_blockbag: '&cFehlende Blöcke: %s0'
|
||||
web:
|
||||
generating_link: Upload %s, Bitte warten...
|
||||
generating_link_failed: '&cErstellung eines Download-Links fehlgeschlagen!'
|
||||
download_link: '%s'
|
||||
worldedit:
|
||||
general:
|
||||
mask_disabled: Globale Maske deaktiviert
|
||||
mask: Globale Maske gesetzt
|
||||
transform_disabled: Globale Transformation deaktiviert
|
||||
transform: Globale Transformation gesetzt
|
||||
source_mask_disabled: Globale Quell-Maske deaktiviert
|
||||
source_mask: Global Quell-Maske gesetzt
|
||||
fast_enabled: Fast-Modus aktiviert. Verlauf und Beschränkungen werden ignoriert.
|
||||
fast_disabled: Fast-Modus deaktiviert
|
||||
place_enabled: 'Platziere nun an Pos. #1.'
|
||||
place_disabled: Platziere nun an dem Block in dem du stehst.
|
||||
copy:
|
||||
command_copy: '%s0 Blöcke kopiert'
|
||||
cut:
|
||||
command_cut_slow: |-
|
||||
%s0 blocks were cut.
|
||||
Tip: lazycut is safer
|
||||
command_cut_lazy: '%s0 Blöcke werden beim einfügen entfernt'
|
||||
paste:
|
||||
command_paste: Zwischenablage wurde bei Position %s0 eingefügt
|
||||
rotate:
|
||||
command_rotate: Zwischenablage wurde gedreht
|
||||
flip:
|
||||
command_flipped: Zwischenablage wurde gespiegelt
|
||||
regen:
|
||||
command_regen_0: |-
|
||||
Region regenerated.
|
||||
Tip: Use a biome with /regen [biome]
|
||||
command_regen_1: |-
|
||||
Region regenerated.
|
||||
Tip: Use a seed with /regen [biome] [seed]
|
||||
command_regen_2: Region regeneriert.
|
||||
tree:
|
||||
command_tree: '%s0 Bäume erstellt.'
|
||||
command_pumpkin: '%s0 Kürbis-Patch erstellt.'
|
||||
flora:
|
||||
command_flora: '%s0 Pflanzen erstellt.'
|
||||
history:
|
||||
command_history_clear: Verlauf gelöscht
|
||||
command_redo_success: Redo erfolgreich.
|
||||
command_undo_success: Undo erfolgreich.
|
||||
command_redo_error: Nothing left to redo. (See also `/inspect` and `/frb`)
|
||||
command_undo_error: Nothing left to undo. (See also `/inspect` and `/frb`)
|
||||
command_history_other_error: WorldEdit Verlauf für %s0 konnte nicht gefunden werden.
|
||||
operation:
|
||||
operation: Operation wird durchgeführt (%s0)
|
||||
selection:
|
||||
selection_wand: 'Linksklick: Markiere Position #1; Rechtsklick: Markiere Position
|
||||
#2'
|
||||
selection_wand_disable: Bearbeitungs-Tool deaktiviert.
|
||||
selection_wand_enable: Bearbeitungs-Tool aktiviert.
|
||||
selection_chunk: Chunk ausgewählt (%s0)
|
||||
selection_chunks: Chunks ausgewählt (%s0) - (%s1)
|
||||
selection_contract: Markierung verkleinert um %s0 Blöcke.
|
||||
selection_count: '%s0 Blöcke wurden gezählt.'
|
||||
selection_distr: '# Gesamtanzahl Blöcke: %s0'
|
||||
selection_expand: Markierung erweitert um %s0 Blöcke
|
||||
selection_expand_vert: Markierung erweitert um %s0 Blöcke (Maximaler Baubereich)
|
||||
selection_inset: Markierung verkleinert
|
||||
selection_outset: Markierung vergößert
|
||||
selection_shift: Region verschoben
|
||||
selection_cleared: Auswahl gelöscht
|
||||
brush:
|
||||
brush_butcher: Butcher Pinsel ausgerüstet (%s0)
|
||||
brush_clipboard: Clipboard Pinsel Format ausgerüstet
|
||||
brush_cylinder: Cylinder Pinsel Format ausgerüstet (%s0 by %s1).
|
||||
brush_extinguisher: Extinguisher ausgerüstet (%s0).
|
||||
brush_gravity: Gravity Pinsel ausgerüstet (%s0)
|
||||
brush_height: Height Pinsel ausgerüstet (%s0)
|
||||
brush_copy: Copy Pinsel ausgerüstet (%s0)
|
||||
brush_command: Command Pinsel ausgerüstet (%s0)
|
||||
brush_height_invalid: Invalid height map file (%s0)
|
||||
brush_smooth: Smooth Pinsel ausgerüstet (%s0 x %s1 using %s2).
|
||||
brush_sphere: Sphere Pinsel Format ausgerüstet (%s0).
|
||||
brush_line: Linien Pinsel Format ausgerüstet (%s0).
|
||||
brush_spline: Linien Pinsel Format ausgerüstet (%s0). Rechstklicke ein Ende um ein Format hinzuzufügen
|
||||
brush_spline_primary: Position hinzugefügt, Linksklick zum verbinden!
|
||||
brush_spline_secondary_error: Nicht genügend Positionen gesetzt!
|
||||
brush_spline_secondary: Kurve erstellt
|
||||
brush_blend_ball: Blend ball Pinsel ausgerüstet (%s0).
|
||||
brush_erode: Erode Pinsel ausgerüstet (%s0).
|
||||
brush_paste_none: Zwischenablage leer! Nichts zum einfügen!
|
||||
brush_size: Pinsel Größe gesetzt
|
||||
brush_range: Pinsel Größe gesetzt
|
||||
brush_mask_disabled: Pinsel Maske deaktiviert
|
||||
brush_mask: Pinsel Maske gesetzt
|
||||
brush_transform_disabled: Pinsel Transformation deaktiviert
|
||||
brush_transform: Pinsel Transformation gesetzt
|
||||
brush_material: Pinsel Material gesetzt
|
||||
brush_recursive: Rekursiver Pinsel ausgerüstet (%s0).
|
||||
brush_try_other: |-
|
||||
&cFAWE adds other, more suitable brushes e.g.
|
||||
&8 - &7//br height [radius=5] [#clipboard|file=null] [rotation=0] [yscale=1.00]
|
||||
brush_none: You aren't holding a brush!
|
||||
brush_source_mask_disabled: Pinsel Quell-Maske deaktiviert
|
||||
brush_source_mask: Pinsel Quell-Maske gesetzt
|
||||
rollback:
|
||||
rollback_element: annullierend %s0
|
||||
tool:
|
||||
tool_inspect: Inpektions-Tool gebunden an %s0.
|
||||
tool_inspect_info: '&7%s0 änderte %s1 zu %s2 %s3 zuvor'
|
||||
tool_inspect_info_footer: '&6Total: &7%s0 Änderungen'
|
||||
tool_none: Tool vom aktuellen Item entfernt.
|
||||
tool_info: Info-Tool gebunden an %s0.
|
||||
tool_tree: Tree-Tool gebunden an %s0.
|
||||
tool_tree_error: Baum Typ %s0 ist unbekannt.
|
||||
tool_repl: Block Replacer-Tool gebunden an %s0.
|
||||
tool_cycler: Block Data Cycler-Tool gebunden an %s0.
|
||||
tool_flood_fill: Block Flood Fill-Tool gebunden an %s0.
|
||||
tool_deltree: Floating Tree Remover-Tool gebunden an %s0.
|
||||
tool_farwand: Far Wand-Tool gebunden an%s0.
|
||||
tool_lrbuild_bound: Long-range Building-Tool gebunden an %s0.
|
||||
tool_lrbuild_info: 'Linksklick: Setze Position %s0; Rechtsklick: Setze Position
|
||||
%s1'
|
||||
superpickaxe_enabled: Super Pickaxe aktiviert.
|
||||
superpickaxe_disabled: Super Pickaxe deaktiviert.
|
||||
tool_range_error: 'Maximale Reichweite: %s0.'
|
||||
tool_radius_error: 'Maximal erlaubter Pinsel Radius: %s0.'
|
||||
superpickaxe_area_enabled: Modus geändert. Linksklick mit einer Spitzhacke. // zum deaktivieren.
|
||||
schematic:
|
||||
schematic_delete: Schematic %s0 wurde gelöscht.
|
||||
schematic_format: 'Verfügbare Zwischenspeicher Formate (Name: Suche Namen)'
|
||||
schematic_loaded: Schematic %s0 geladen. Platziere es mit //paste
|
||||
schematic_saved: Schematic %s0 gespeichert.
|
||||
schematic_page: Seite muss %s sein
|
||||
schematic_none: Keine Schematics gefunden.
|
||||
schematic_list: 'Verfügbare Schematics (Filename: Format) [%s0/%s1]:'
|
||||
clipboard:
|
||||
clipboard_cleared: Zwischenablage geleert
|
||||
clipboard_invalid_format: 'Unbekanntes Zwischenspeicher Format: %s0'
|
||||
visitor:
|
||||
visitor_block: '%s0 Blöcke betroffen'
|
||||
visitor_entity: '%s0 Entities betroffen'
|
||||
visitor_flat: '%s0 Rubriken betroffen'
|
||||
selector:
|
||||
selector_cuboid_pos1: Pos 1 gesetzt %s0 %s1.
|
||||
selector_cuboid_pos2: Pos 2 gesetzt %s0 %s1.
|
||||
selector_invalid_coordinates: Ungültige Koordinaten %s0
|
||||
selector_already_set: Position bereits gesetzt.
|
||||
selector_fuzzy_pos1: Region gesetzt und expandiert von %s0 %s1.
|
||||
selector_fuzzy_pos2: Erweiterung hinzugefügt um %s0 %s1.
|
||||
selector_set_default: Dein Standard Auswahl-Tool ist nun %s0.
|
||||
command:
|
||||
command_invalid_syntax: The command was not used properly (no more help available).
|
||||
snapshot:
|
||||
snapshot_loaded: Snapshot '%s0' loaded; now restoring...
|
||||
snapshot_set: 'Snapshot set to: %s0'
|
||||
snapshot_newest: Now using newest snapshot.
|
||||
snapshot_list_header: 'Snapshots for world (%s0):'
|
||||
snapshot_list_footer: Use /snap use [snapshot] or /snap use latest.
|
||||
biome:
|
||||
biome_list_header: 'Biome (page %s0/%s1):'
|
||||
biome_changed: Biome wurden geändert in %s0 Bezirken.
|
||||
utility:
|
||||
kill_success: '%s0 Entities in einem Radius von %s1 getötet.'
|
||||
timezone:
|
||||
timezone_set: 'Zeitzone für diese Sitzung gesetzt auf: %s0'
|
||||
timezone_display: 'Aktuelle Zeit in dieser Zeitzone: %s0'
|
||||
progress:
|
||||
progress_message: '[ Zwischenspeicher: %s0 | Erledigt: %s1 ]'
|
||||
progress_finished: '[ Fertiggestellt! ]'
|
||||
cancel:
|
||||
worldedit_cancel_count: '&c%s0 Veränderungen abgebrochen.'
|
||||
worldedit_cancel_reason: '&cDeine WorldEdit Aktion wurde abgebrochen:&7 %s0&c.'
|
||||
worldedit_cancel_reason_manual: Manueller Abbruch
|
||||
worldedit_cancel_reason_low_memory: Zu wenig Speicher
|
||||
worldedit_cancel_reason_max_changes: Zu viele Blöcke bearbeitet
|
||||
worldedit_cancel_reason_max_checks: Zu viele Blöcke gecheckt
|
||||
worldedit_cancel_reason_max_tiles: Zu viele Blockstatus
|
||||
worldedit_cancel_reason_max_entities: Zu viele Entities
|
||||
worldedit_cancel_reason_max_iterations: Maximale Wiederholungen
|
||||
worldedit_cancel_reason_max_fails: Ausserhalb erlaubter Regionen (Bypass mit /wea)
|
||||
worldedit_cancel_reason_no_region: Keine erlaubte Region (Bypass mit /wea)
|
||||
worldedit_failed_load_chunk: '&cÜberspringe das Laden von Chunk: &7%s0;%s1&c. Versuche
|
||||
chunk-wait zu erhöhen.'
|
||||
history:
|
||||
loading_clipboard: Lade Zwischenablage bitte warten.
|
||||
indexing_history: Indiziere %s Verlauf auf der Platte, Bitte warten.
|
||||
indexing_complete: 'Indizierung vollständig. Dauer: %s Sekunden!'
|
||||
navigation:
|
||||
ascend_fail: Kein freier Platz über dir gefunden.
|
||||
ascended_plural: '%s0 Schichten aufgestiegen.'
|
||||
ascended_singular: Eine Schicht aufgestiegen.
|
||||
unstuck: Auf gehts!
|
||||
descend_fail: Kein freier Platz unter dir gefunden.
|
||||
descend_plural: '%s0 Schichten abgestiegen.'
|
||||
descend_singular: Eine Schicht abgestiegen.
|
||||
whoosh: Whoosh!
|
||||
poof: Poof!
|
||||
thru_fail: Kein freier Platz vor dir gefunden.
|
||||
up_fail: Du würdest einen Block treffen!
|
||||
no_block: Kein Block in Sichweite! (oder zu weit entfernt)
|
||||
selection:
|
||||
sel_cuboid: 'Quader: Linksklick für Position1, Rechtsklick für Position2'
|
||||
sel_cuboid_extend: 'Quader: Linksklick für einen Startpunkt, Rechtsklick zum erweitern'
|
||||
sel_2d_polygon: '2D Polygon Selektierer: Links/Rechtsklick um eine Markierung hinzuzufügen.'
|
||||
sel_ellipsiod: 'Ellipsen Selektierer: Linksklick=Mitte, Rechtsklick zum erweitern'
|
||||
sel_sphere: 'Kugel Selektierer : Linksklick=Mitte, Rechtsklick um den Radius zu
|
||||
setzen'
|
||||
sel_cylindrical: 'Zylinder Selektierer: Linksklick=Mitte, Rechtsklick zum erweitern'
|
||||
sel_max: '%s0 Punkte maximal.'
|
||||
sel_fuzzy: 'Fuzzy Selektierer: Linksklick um alle verbundenen Blöcke zu markieren,
|
||||
Rechtsklick zum hinzufügen'
|
||||
sel_convex_polyhedral: 'Convex polyhedral selector: Left click=First vertex, right
|
||||
click to add more.'
|
||||
sel_list: Für eine Liste der Selektoren nutze:&c //sel
|
||||
sel_modes: 'Wähle einen der unten aufgelisteten Modi:'
|
||||
tips:
|
||||
tip_cancel: 'Tip: Du kannst eine Aktion abbrechen mit `//cancel`'
|
||||
tip_download: 'Tip: Du kannst deinen Zwischenspeicher mit`//download` herunterladen'
|
||||
tip_sel_list: 'Tip: Liste die verschiedenen Selektoren auf mit &c//sel list'
|
||||
tip_select_connected: 'Tip: Wähle alle verbundenen Blöcke mit //sel fuzzy'
|
||||
tip_set_pos1: 'Tip: Nutze pos1 als Muster &c//set pos1'
|
||||
tip_farwand: 'Tip: Markiere entferne Blöcke mit &c//farwand'
|
||||
tip_fast: '&7Tip: Platziere schnell und ohne Undo-Historie &c//fast'
|
||||
tip_mask: '&7Tip: Setze eine Globale Zielmaske mit &c/gmask'
|
||||
tip_mask_angle: 'Tip: Ersetze aufwärts Steigungen von 3-20 Blöcken mit&c //replace
|
||||
/-20:-3 bedrock'
|
||||
tip_set_linear: '&7Tip: Setze Blöcke linear mit&c //set #l3d:wood,bedrock'
|
||||
tip_surface_spread: '&7Tip: Streue einen flachen Untergrund mit&c //set #surfacespread:5:0:5:#existing'
|
||||
tip_set_hand: '&7Tip: Setze das Item in deiner Hand mit&c//set hand'
|
||||
tip_replace_id: '&7Tip: Ersetze nur die Block-ID:&c //replace woodenstair #id:cobblestair'
|
||||
tip_replace_light: 'Tip: Entferne Licht-Quellen&c //replace #brightness:1:15 0'
|
||||
tip_tab_complete: 'Tip: Der Replace-Befehl unterstützt Tab-Vervollständigung'
|
||||
tip_flip: 'Tip: Spiegeln mit &c//flip'
|
||||
tip_deform: 'Tip: Forme um mit &c//deform'
|
||||
tip_transform: 'Tip: Platziere eine Umformung mit &c//gtransform'
|
||||
tip_copypaste: 'Tip: Füge durch Klick ein mit &c//br copypaste'
|
||||
tip_source_mask: 'Tip: Setze eine Quell-Maske &c/gsmask <mask>&7'
|
||||
tip_replace_marker: 'Tip: Ersetze einen Block mit deinem vollständigen Zwischenspeicher
|
||||
mit &c//replace wool #fullcopy'
|
||||
tip_paste: 'Tip: Füge deine Zwischeneinlage mit &c//paste ein'
|
||||
tip_lazycopy: 'Tip: lazycopy ist schneller'
|
||||
tip_rotate: 'Tip: Ausrichten mit &c//rotate'
|
||||
tip_copy_pattern: 'Tip: Um ein Muster zu verwenden nutze &c#copy'
|
||||
tip_brush_spline: '&7Tip Der spline &c//brush &7verbindet multiple Formen miteinander'
|
||||
tip_brush_height: '&7Tip: Der Höhe &c//brush &7erhöht oder senkt Terrain sanft'
|
||||
tip_brush_copy: '&7Tip: Der copypaste &c//brush &7erlaubt dir leichtes kopieren
|
||||
und einfügen von Objekten.'
|
||||
tip_brush_mask: '&7Tip: Setze eine brush Ziel-Maske mit &c/mask'
|
||||
tip_brush_mask_source: '&7Tip: Setze eine brush Quell-Maske mit &c/smask'
|
||||
tip_brush_transform: '&7Tip: Setze eine brush Transformation mit &c/transform'
|
||||
tip_brush_relative: '&7Tip: Nutze ein relatives Zwischenspeicher-Muster mit //br
|
||||
sphere #~:#copy'
|
||||
tip_brush_command: '&7Tip: Probiere den Befehl &c//br cmd <radius> <cmd1;cmd2>'
|
||||
tip_lazycut: '&7Tip: Es ist sicherer den Befehl &c//lazycut zu verwenden.'
|
@ -21,9 +21,6 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
|
@ -71,7 +71,7 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return PlayerWrapper.wrap(ForgeWorldEdit.inst.wrap(this.parent));
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,6 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
|
@ -71,7 +71,7 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return PlayerWrapper.wrap(ForgeWorldEdit.inst.wrap(this.parent));
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,6 @@ dependencies {
|
||||
compile 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
|
@ -73,7 +73,7 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return ForgeWorldEdit.inst.wrap(this.parent);
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,6 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
|
@ -74,7 +74,7 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return PlayerWrapper.wrap(ForgeWorldEdit.inst.wrap(this.parent));
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,6 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
|
@ -22,10 +22,12 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
|
||||
@Override
|
||||
public void sendTitle(String head, String sub) { // Not supported
|
||||
Settings.IMP.QUEUE.PROGRESS.DISPLAY = "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTitle() { // Not supported
|
||||
Settings.IMP.QUEUE.PROGRESS.DISPLAY = "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,7 +73,7 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
public Player toWorldEditPlayer() {
|
||||
return PlayerWrapper.wrap(ForgeWorldEdit.inst.wrap(this.parent));
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
@ -30,6 +31,7 @@ public class FaweNukkit implements IFawe, Listener {
|
||||
public FaweNukkit(NukkitWorldEdit mod) {
|
||||
this.plugin = mod;
|
||||
FaweChunk.HEIGHT = 256;
|
||||
VisualChunk.VISUALIZE_BLOCK = 241 << 4;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class FaweNukkitPlayer extends FawePlayer<Player> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sk89q.worldedit.entity.Player getPlayer() {
|
||||
public com.sk89q.worldedit.entity.Player toWorldEditPlayer() {
|
||||
return new NukkitPlayer((NukkitPlatform) Fawe.<FaweNukkit> imp().getPlugin().getPlatform(), parent);
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,6 @@ dependencies {
|
||||
compile name: 'worldedit-core-6.1.7-SNAPSHOT-dist'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
minecraft {
|
||||
version = "1.11"
|
||||
mappings = "snapshot_20161116"
|
||||
|
@ -73,7 +73,7 @@ public class SpongePlayer extends FawePlayer<Player> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sk89q.worldedit.entity.Player getPlayer() {
|
||||
public com.sk89q.worldedit.entity.Player toWorldEditPlayer() {
|
||||
if (WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.USER_COMMANDS) != null) {
|
||||
for (Platform platform : WorldEdit.getInstance().getPlatformManager().getPlatforms()) {
|
||||
return platform.matchPlayer(new FakePlayer(getName(), getUUID(), null));
|
||||
|
Loading…
Reference in New Issue
Block a user