diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java index 29ff0ed7..c7946850 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/BrushListener.java @@ -1,22 +1,18 @@ 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.boydti.fawe.object.brush.MovableTool; +import com.boydti.fawe.object.brush.ResettableTool; +import com.boydti.fawe.object.brush.scroll.ScrollTool; 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.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerMoveEvent; @@ -40,39 +36,25 @@ public class BrushListener implements Listener { 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 (tool instanceof ScrollTool) { + } - 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); - } - } - } + 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; + } + ScrollTool scrollable = (ScrollTool) tool; + if (scrollable.increment(player, 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(); } } } @@ -88,21 +70,8 @@ public class BrushListener implements Listener { 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); - } - } - } - } + if (tool instanceof MovableTool) { + ((MovableTool) tool).move(player); } } } @@ -110,26 +79,21 @@ public class BrushListener implements Listener { @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 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(); - } + Player bukkitPlayer = event.getPlayer(); + if (bukkitPlayer.isSneaking()) { + if (event.getAction() == Action.PHYSICAL) { + return; + } + FawePlayer 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 instanceof ResettableTool) { + if (((ResettableTool) tool).reset()) { + event.setCancelled(true); } + } } } } diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index cc3c80f2..58b7e370 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -79,6 +79,7 @@ import com.sk89q.worldedit.function.mask.SolidBlockMask; 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.BlockPattern; import com.sk89q.worldedit.function.pattern.ClipboardPattern; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Patterns; @@ -450,6 +451,7 @@ public class Fawe { ClipboardPattern.inject(); // Optimizations HashTagPatternParser.inject(); // Add new patterns DefaultBlockParser.inject(); // Fix block lookups + BlockPattern.inject(); // Optimization // Mask Mask.inject(); // Extend deprecated mask BlockMask.inject(); // Optimizations diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index da2ac025..72606a01 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -48,6 +48,7 @@ public enum BBC { WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable `max-memory-percent`", "Info"), COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"), + WEB_UNAUTHORIZED("Only links from the configured web host is allowed: %s0", "Error"), ACTION_COMPLETE("Action completed in %s0 seconds", "Info"), GENERATING_LINK("Uploading %s, please wait...", "Web"), GENERATING_LINK_FAILED("&cFailed to generate download link!", "Web"), @@ -104,6 +105,9 @@ public enum BBC { SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"), BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"), + BRUSH_SCROLL_ACTION_SET("Set scroll action to %s0", "WorldEdit.Brush"), + BRUSH_VISUAL_MODE_SET("Set visual mode to %s0", "WorldEdit.Brush"), + BRUSH_TARGET_MODE_SET("Set target mode to %s0", "WorldEdit.Brush"), BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"), BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"), BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "WorldEdit.Brush"), @@ -117,15 +121,14 @@ public enum BBC { BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2. Note: Use the blend brush if you want to smooth overhangs or caves.).", "WorldEdit.Brush"), BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"), BRUSH_LINE("Line brush shape equipped (%s0).", "WorldEdit.Brush"), - BRUSH_SPLINE("Line brush shape equipped (%s0). Right click an end to add a shape", "WorldEdit.Brush"), - BRUSH_SPLINE_PRIMARY("Added position, left click to spline them together!", "WorldEdit.Brush"), + BRUSH_SPLINE("Spline brush shape equipped (%s0). Right click an end to add a shape", "WorldEdit.Brush"), + BRUSH_SPLINE_PRIMARY("Added position, Click the same spot to join!", "WorldEdit.Brush"), BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"), BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"), - BRUSH_BLEND_BALL("Blend ball brush equipped (%s0).", "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"), BRUSH_RANGE("Brush size set", "WorldEdit.Brush"), BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"), diff --git a/core/src/main/java/com/boydti/fawe/object/PseudoRandom.java b/core/src/main/java/com/boydti/fawe/object/PseudoRandom.java index dfd32f66..1b1bdee3 100644 --- a/core/src/main/java/com/boydti/fawe/object/PseudoRandom.java +++ b/core/src/main/java/com/boydti/fawe/object/PseudoRandom.java @@ -31,7 +31,7 @@ public class PseudoRandom { } public double nextDouble() { - return Math.max(0, Math.min(1, Math.abs(nextLong() / Long.MAX_VALUE))); + return Math.max(0, Math.min(1, Math.abs((double) nextLong() / Long.MAX_VALUE))); } public int random(final int n) { diff --git a/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java b/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java new file mode 100644 index 00000000..38a84cc8 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java @@ -0,0 +1,19 @@ +package com.boydti.fawe.object.brush; + +import com.boydti.fawe.object.brush.scroll.ScrollAction; +import com.boydti.fawe.object.extent.ResettableExtent; +import com.sk89q.worldedit.command.tool.brush.Brush; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.pattern.Pattern; + +public class BrushSettings { + public Brush brush = null; + + public Mask mask = null; + public Mask sourceMask = null; + public ResettableExtent transform = null; + public Pattern material; + public double size = 1; + public String permission; + public ScrollAction scrollAction; +} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java index d2ff316e..11a454da 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java @@ -1,39 +1,31 @@ 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.command.tool.brush.Brush; 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 { +public class CircleBrush implements Brush { private final Player player; + private final BrushTool tool; public CircleBrush(BrushTool tool, Player player) { - super(tool); + this.tool = 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; - } + public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + Vector normal = position.subtract(player.getPosition()); + editSession.makeCircle(position, pattern, size, size, size, false, normal); } - private static Vector any90Rotate(Vector normal) { + private 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()); diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java index af05b651..c80f4fa2 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java @@ -51,7 +51,7 @@ public class CommandBrush implements Brush { String[] cmds = replaced.split(";"); for (String cmd : cmds) { CommandEvent event = new CommandEvent(wePlayer, cmd); - CommandManager.getInstance().handleCommand(event); + CommandManager.getInstance().handleCommandOnCurrentThread(event); } } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java index efa81ceb..8d9eb668 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java @@ -2,16 +2,17 @@ package com.boydti.fawe.object.brush; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.brush.visualization.VisualExtent; import com.boydti.fawe.object.clipboard.ResizableClipboardBuilder; import com.boydti.fawe.object.function.NullRegionFunction; import com.boydti.fawe.object.function.mask.AbstractDelegateMask; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EmptyClipboardException; 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.command.tool.brush.Brush; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; @@ -22,70 +23,74 @@ import com.sk89q.worldedit.function.visitor.RecursiveVisitor; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; -public class CopyPastaBrush implements DoubleActionBrush { +public class CopyPastaBrush implements Brush, ResettableTool { private final BrushTool tool; + private final LocalSession session; - public CopyPastaBrush(BrushTool tool) { + public CopyPastaBrush(BrushTool tool, LocalSession session) { this.tool = tool; + session.setClipboard(null); + this.session = session; } @Override - public void build(BrushTool.BrushAction action, final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + public boolean reset() { + session.setClipboard(null); + return true; + } + + @Override + public void build(final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { FawePlayer fp = editSession.getPlayer(); - LocalSession session = fp.getSession(); - switch (action) { - case SECONDARY: { - Mask mask = tool.getMask(); - if (mask == null) { - mask = Masks.alwaysTrue(); - } - final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld()); - final int size2 = (int) (size * size); - final int minY = position.getBlockY(); - mask = new AbstractDelegateMask(mask) { - @Override - public boolean test(Vector vector) { - if (super.test(vector) && vector.getBlockY() >= minY) { - BaseBlock block = editSession.getLazyBlock(vector); - if (block != EditSession.nullBlock) { - builder.add(vector, EditSession.nullBlock, block); - return true; - } - } - return false; - } - }; - // Add origin - mask.test(position); - RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction(), (int) size, editSession); - visitor.visit(position); - Operations.completeBlindly(visitor); - // Build the clipboard - Clipboard clipboard = builder.build(); - clipboard.setOrigin(position); - ClipboardHolder holder = new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()); - session.setClipboard(holder); - int blocks = builder.size(); - BBC.COMMAND_COPY.send(fp, blocks); + ClipboardHolder clipboard = session.getExistingClipboard(); + if (clipboard == null) { + if (editSession.getExtent() instanceof VisualExtent) { return; } - case PRIMARY: { - try { - ClipboardHolder holder = session.getClipboard(); - Clipboard clipboard = holder.getClipboard(); - Region region = clipboard.getRegion(); - Vector centerOffset = region.getCenter().subtract(clipboard.getOrigin()); - Operation operation = holder - .createPaste(editSession, editSession.getWorld().getWorldData()) - .to(position.add(0, 1, 0)) - .ignoreAirBlocks(true) - .build(); - Operations.completeLegacy(operation); - } catch (EmptyClipboardException e) { - BBC.BRUSH_PASTE_NONE.send(fp); - } + Mask mask = tool.getMask(); + if (mask == null) { + mask = Masks.alwaysTrue(); } + final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld()); + final int size2 = (int) (size * size); + final int minY = position.getBlockY(); + mask = new AbstractDelegateMask(mask) { + @Override + public boolean test(Vector vector) { + if (super.test(vector) && vector.getBlockY() >= minY) { + BaseBlock block = editSession.getLazyBlock(vector); + if (block != EditSession.nullBlock) { + builder.add(vector, EditSession.nullBlock, block); + return true; + } + } + return false; + } + }; + // Add origin + mask.test(position); + RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction(), (int) size, editSession); + visitor.visit(position); + Operations.completeBlindly(visitor); + // Build the clipboard + Clipboard newClipboard = builder.build(); + newClipboard.setOrigin(position); + ClipboardHolder holder = new ClipboardHolder(newClipboard, editSession.getWorld().getWorldData()); + session.setClipboard(holder); + int blocks = builder.size(); + BBC.COMMAND_COPY.send(fp, blocks); + return; + } else { + Clipboard faweClip = clipboard.getClipboard(); + Region region = faweClip.getRegion(); + Vector centerOffset = region.getCenter().subtract(faweClip.getOrigin()); + Operation operation = clipboard + .createPaste(editSession, editSession.getWorld().getWorldData()) + .to(position.add(0, 1, 0)) + .ignoreAirBlocks(true) + .build(); + Operations.completeLegacy(operation); } } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/DoubleActionBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/DoubleActionBrush.java deleted file mode 100644 index d2fd753b..00000000 --- a/core/src/main/java/com/boydti/fawe/object/brush/DoubleActionBrush.java +++ /dev/null @@ -1,18 +0,0 @@ -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 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; -} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java index fb35cfc4..1e323682 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java @@ -10,39 +10,22 @@ 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.command.tool.brush.Brush; import com.sk89q.worldedit.function.pattern.Pattern; import java.util.Arrays; -public class ErodeBrush implements DoubleActionBrush { +public class ErodeBrush implements Brush { private PseudoRandom rand = new PseudoRandom(); 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(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { - switch (action) { - case PRIMARY: { - int erodeFaces = 2; - int erodeRec = 1; - int fillFaces = 5; - int fillRec = 1; - this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size); - break; - } - case SECONDARY: { - int erodeFaces = 6; - int erodeRec = 0; - int fillFaces = 1; - int fillRec = 1; - this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size); - break; - } - } + public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + this.erosion(editSession, 2, 1, 5, 1, position, size); } - protected void erosion(final EditSession es, int erodeFaces, int erodeRec, int fillFaces, int fillRec, Vector target, double size) { + public void erosion(final EditSession es, int erodeFaces, int erodeRec, int fillFaces, int fillRec, Vector target, double size) { int brushSize = (int) size + 1; int brushSizeSquared = (int) (size * size); int dimension = brushSize * 2 + 1; @@ -86,7 +69,7 @@ public class ErodeBrush implements DoubleActionBrush { }, true); } - private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces, FaweClipboard current, FaweClipboard target) { + public void fillIteration(int brushSize, int brushSizeSquared, int fillFaces, FaweClipboard current, FaweClipboard target) { int[] frequency = null; for (int x = -brushSize; x <= brushSize; x++) { int x2 = x * x; @@ -130,7 +113,7 @@ public class ErodeBrush implements DoubleActionBrush { } } - private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, FaweClipboard current, FaweClipboard target) { + public void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, FaweClipboard current, FaweClipboard target) { int[] frequency = null; for (int x = -brushSize; x <= brushSize; x++) { int x2 = x * x; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java index ed8e1a32..ddc66722 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java @@ -18,13 +18,13 @@ public class FlattenBrush extends HeightBrush { } @Override - public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException { + public void build(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 == BrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, true); + heightMap.apply(editSession, mask, position, size, rotation, yscale, true, true); } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java index a5288a7b..8708ed79 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java @@ -7,6 +7,7 @@ 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.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; @@ -14,7 +15,7 @@ import com.sk89q.worldedit.function.pattern.Pattern; import java.io.IOException; import java.io.InputStream; -public class HeightBrush implements DoubleActionBrush { +public class HeightBrush implements Brush { public final ScalableHeightMap heightMap; public final int rotation; @@ -43,13 +44,13 @@ public class HeightBrush implements DoubleActionBrush { } @Override - public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException { + public void build(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 == BrushTool.BrushAction.PRIMARY ? yscale : -yscale, true, false); + heightMap.apply(editSession, mask, position, size, rotation, yscale, true, false); } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/LineBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/LineBrush.java index 12c717e6..f9f21c48 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/LineBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/LineBrush.java @@ -3,11 +3,11 @@ 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; import com.sk89q.worldedit.function.pattern.Patterns; -public class LineBrush implements DoubleActionBrush { +public class LineBrush implements Brush, ResettableTool { private final boolean shell, select, flat; private Vector pos1; @@ -19,20 +19,21 @@ public class LineBrush implements DoubleActionBrush { } @Override - public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException { - switch (action) { - case PRIMARY: - if (pos1 == null) { - pos1 = position; - return; - } - editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat); - if (!select) { - return; - } - case SECONDARY: - pos1 = position; - return; + public void build(EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException { + if (pos1 == null) { + pos1 = position; + return; + } + editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat); + if (!select) { + pos1 = null; + return; } } + + @Override + public boolean reset() { + pos1 = null; + return true; + } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/MovableBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/MovableTool.java similarity index 79% rename from core/src/main/java/com/boydti/fawe/object/brush/MovableBrush.java rename to core/src/main/java/com/boydti/fawe/object/brush/MovableTool.java index b1bde41a..4c063296 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/MovableBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/MovableTool.java @@ -2,6 +2,6 @@ package com.boydti.fawe.object.brush; import com.sk89q.worldedit.entity.Player; -public interface MovableBrush { +public interface MovableTool { public boolean move(Player player); } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/RaiseBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/RaiseBrush.java index dc7c72f1..7e7bd283 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/RaiseBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/RaiseBrush.java @@ -3,19 +3,11 @@ 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 { - - +public class RaiseBrush extends ErodeBrush { @Override - public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { - switch (action) { - case PRIMARY: - break; - case SECONDARY: - break; - } + public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + this.erosion(editSession, 6, 0, 1, 1, position, size); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/brush/ResettableTool.java b/core/src/main/java/com/boydti/fawe/object/brush/ResettableTool.java new file mode 100644 index 00000000..53d5859e --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/ResettableTool.java @@ -0,0 +1,5 @@ +package com.boydti.fawe.object.brush; + +public interface ResettableTool { + boolean reset(); +} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java index 71f9bbe5..7717293c 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java @@ -11,6 +11,7 @@ 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.command.tool.brush.Brush; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.mask.Mask; @@ -22,9 +23,11 @@ import com.sk89q.worldedit.math.interpolation.Node; import com.sk89q.worldedit.math.transform.AffineTransform; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.List; -public class SplineBrush implements DoubleActionBrush { +public class SplineBrush implements Brush { public static int MAX_POINTS = 15; private ArrayList> positionSets; @@ -33,6 +36,7 @@ public class SplineBrush implements DoubleActionBrush { private final BrushTool tool; private final LocalSession session; private final Player player; + private Vector position; public SplineBrush(Player player, LocalSession session, BrushTool tool) { this.tool = tool; @@ -42,7 +46,7 @@ public class SplineBrush implements DoubleActionBrush { } @Override - public void build(BrushTool.BrushAction action, EditSession editSession, final Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + public void build(EditSession editSession, final Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { Mask mask = tool.getMask(); if (mask == null) { mask = new IdMask(editSession); @@ -54,91 +58,100 @@ public class SplineBrush implements DoubleActionBrush { return; } int originalSize = numSplines; - switch (action) { - case PRIMARY: { + boolean newPos = this.position == null || !position.equals(this.position); + this.position = position; + if (newPos) { if (positionSets.size() >= MAX_POINTS) { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } final ArrayList points = new ArrayList<>(); - DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, new RegionFunction() { - @Override - public boolean apply(Vector p) throws WorldEditException { - points.add(new Vector(p)); - return true; - } - }, (int) size, 1); - Collection 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); + if (tool.getSize() > 0) { + DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, new RegionFunction() { + @Override + public boolean apply(Vector p) throws WorldEditException { + points.add(new Vector(p)); + return true; + } + }, (int) size, 1); + List directions = visitor.getDirections(); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if (x != 0 || y != 0 && z != 0) { + Vector pos = new Vector(x, y, z); + if (!directions.contains(pos)) { + directions.add(pos); + } + } } } } - } - visitor.visit(position); - Operations.completeBlindly(visitor); - if (points.size() > numSplines) { - numSplines = points.size(); + Collections.sort(directions, new Comparator() { + @Override + public int compare(Vector o1, Vector o2) { + return (int) Math.signum(o1.lengthSq() - o2.lengthSq()); + } + }); + visitor.visit(position); + Operations.completeBlindly(visitor); + if (points.size() > numSplines) { + numSplines = points.size(); + } + } else { + points.add(position); } this.positionSets.add(points); player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY.s()); if (!visualization) { - break; - } - } - case SECONDARY: { - if (positionSets.size() < 2) { - player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY_ERROR.s()); return; } - List centroids = new ArrayList<>(); - for (List points : positionSets) { - centroids.add(getCentroid(points)); - } - - double tension = 0; - double bias = 0; - double continuity = 0; - double quality = 10; - - final List nodes = new ArrayList(centroids.size()); - - for (final Vector nodevector : centroids) { - final Node n = new Node(nodevector); - n.setTension(tension); - n.setBias(bias); - n.setContinuity(continuity); - nodes.add(n); - } - - Vector up = new Vector(0, 1, 0); - AffineTransform transform = new AffineTransform(); - - // TODO index offset based on transform - - int samples = numSplines; - for (int i = 0; i < numSplines; i++) { - List currentSpline = new ArrayList<>(); - for (ArrayList points : positionSets) { - int listSize = points.size(); - int index = (int) (i * listSize / (double) (numSplines)); - currentSpline.add(points.get(index)); - } - editSession.drawSpline(Patterns.wrap(pattern), currentSpline, 0, 0, 0, 10, 0, true); - } - player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s()); - if (visualization) { - positionSets.clear(); - numSplines = 0; - } else { - numSplines = originalSize; - positionSets.remove(positionSets.size() - 1); - } - break; } + if (positionSets.size() < 2) { + player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY_ERROR.s()); + return; + } + List centroids = new ArrayList<>(); + for (List points : positionSets) { + centroids.add(getCentroid(points)); + } + + double tension = 0; + double bias = 0; + double continuity = 0; + double quality = 10; + + final List nodes = new ArrayList(centroids.size()); + + for (final Vector nodevector : centroids) { + final Node n = new Node(nodevector); + n.setTension(tension); + n.setBias(bias); + n.setContinuity(continuity); + nodes.add(n); + } + + Vector up = new Vector(0, 1, 0); + AffineTransform transform = new AffineTransform(); + + // TODO index offset based on transform + + int samples = numSplines; + for (int i = 0; i < numSplines; i++) { + List currentSpline = new ArrayList<>(); + for (ArrayList points : positionSets) { + int listSize = points.size(); + int index = (int) (i * listSize / (double) (numSplines)); + currentSpline.add(points.get(index)); + } + editSession.drawSpline(Patterns.wrap(pattern), currentSpline, 0, 0, 0, 10, 0, true); + } + player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s()); + if (visualization) { + positionSets.clear(); + numSplines = 0; + } else { + numSplines = originalSize; + positionSets.remove(positionSets.size() - 1); } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/TargetMode.java b/core/src/main/java/com/boydti/fawe/object/brush/TargetMode.java index eb3732c4..84a3547e 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/TargetMode.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/TargetMode.java @@ -4,5 +4,5 @@ public enum TargetMode { TARGET_BLOCK_RANGE, FOWARD_POINT_PITCH, TARGET_POINT_HEIGHT, - TARGET_POINT_RANGE, + TARGET_FACE_RANGE, } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java index 4b61cc0a..704078c1 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java @@ -2,7 +2,7 @@ package com.boydti.fawe.object.brush.scroll; import com.sk89q.worldedit.command.tool.BrushTool; -public abstract class ScrollAction implements ScrollableBrush { +public abstract class ScrollAction implements ScrollTool { public final BrushTool tool; public ScrollAction(BrushTool tool) { diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollClipboard.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollClipboard.java index f7c3409d..7bfe77a3 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollClipboard.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollClipboard.java @@ -1,4 +1,27 @@ package com.boydti.fawe.object.brush.scroll; -public class ScrollClipboard { +import com.boydti.fawe.util.MathMan; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.session.ClipboardHolder; + +public class ScrollClipboard extends ScrollAction { + private final ClipboardHolder[] clipboards; + private final LocalSession session; + int index = 0; + + public ScrollClipboard(BrushTool tool, LocalSession session, ClipboardHolder[] clipboards) { + super(tool); + this.clipboards = clipboards; + this.session = session; + } + + @Override + public boolean increment(Player player, int amount) { + index = MathMan.wrap(index + amount, 0, clipboards.length - 1); + ClipboardHolder clipboard = clipboards[index]; + session.setClipboard(clipboard); + return true; + } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java index 531232a3..b2777e55 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java @@ -2,6 +2,7 @@ package com.boydti.fawe.object.brush.scroll; import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.mask.Mask; public class ScrollMask extends ScrollAction { @@ -15,7 +16,7 @@ public class ScrollMask extends ScrollAction { @Override - public boolean increment(int amount) { + public boolean increment(Player player, int amount) { if (masks.length > 1) { tool.setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]); return true; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java index 3cd0bfbe..f5536b9c 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java @@ -2,6 +2,7 @@ package com.boydti.fawe.object.brush.scroll; import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.pattern.Pattern; public class ScrollPattern extends ScrollAction { @@ -15,7 +16,7 @@ public class ScrollPattern extends ScrollAction { @Override - public boolean increment(int amount) { + public boolean increment(Player player, int amount) { if (patterns.length > 1) { tool.setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]); return true; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java index 066f0766..d491b9c4 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java @@ -3,6 +3,7 @@ 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; +import com.sk89q.worldedit.entity.Player; public class ScrollRange extends ScrollAction { public ScrollRange(BrushTool tool) { @@ -10,7 +11,7 @@ public class ScrollRange extends ScrollAction { } @Override - public boolean increment(int amount) { + public boolean increment(Player player, int amount) { int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius; int newSize = MathMan.wrap(tool.getRange() + amount, (int) (tool.getSize() + 1), max); tool.setRange(newSize); diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java index d10a9415..78b0e9f0 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java @@ -2,6 +2,7 @@ package com.boydti.fawe.object.brush.scroll; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.entity.Player; public class ScrollSize extends ScrollAction { public ScrollSize(BrushTool tool) { @@ -9,7 +10,7 @@ public class ScrollSize extends ScrollAction { } @Override - public boolean increment(int amount) { + public boolean increment(Player player, int amount) { int max = WorldEdit.getInstance().getConfiguration().maxRadius; double newSize = Math.max(0, Math.min(max, tool.getSize() + amount)); tool.setSize(newSize); diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java new file mode 100644 index 00000000..da68eb74 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java @@ -0,0 +1,22 @@ +package com.boydti.fawe.object.brush.scroll; + +import com.boydti.fawe.object.brush.TargetMode; +import com.boydti.fawe.util.MathMan; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.entity.Player; + +public class ScrollTarget extends ScrollAction { + public ScrollTarget(BrushTool tool) { + super(tool); + } + + @Override + public boolean increment(Player player, int amount) { + TargetMode mode = tool.getTargetMode(); + int index = mode.ordinal() + amount; + TargetMode[] modes = TargetMode.values(); + TargetMode newMode = modes[MathMan.wrap(index, 0, modes.length - 1)]; + tool.setTargetMode(newMode); + return true; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTool.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTool.java new file mode 100644 index 00000000..865f2c2a --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTool.java @@ -0,0 +1,7 @@ +package com.boydti.fawe.object.brush.scroll; + +import com.sk89q.worldedit.entity.Player; + +public interface ScrollTool { + public boolean increment(Player player, int amount); +} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollableBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollableBrush.java deleted file mode 100644 index d04a9af5..00000000 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollableBrush.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.boydti.fawe.object.brush.scroll; - -public interface ScrollableBrush { - public boolean increment(int amount); -} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/visualization/DelegateVisualBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/visualization/DelegateVisualBrush.java deleted file mode 100644 index adddc602..00000000 --- a/core/src/main/java/com/boydti/fawe/object/brush/visualization/DelegateVisualBrush.java +++ /dev/null @@ -1,32 +0,0 @@ -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; - } - } -} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualBrush.java deleted file mode 100644 index 94a63abf..00000000 --- a/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualBrush.java +++ /dev/null @@ -1,142 +0,0 @@ -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 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 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; - } -} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java b/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java index 9affa8f8..2537a4fc 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java @@ -35,17 +35,13 @@ public class VisualQueue { 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); + BrushTool brushTool = (BrushTool) tool; + if (brushTool.getVisualMode() != VisualMode.NONE) { + try { + brushTool.visualize(BrushTool.BrushAction.PRIMARY, player); + } catch (Throwable e) { + WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player); + } } } } diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.java new file mode 100644 index 00000000..f14844ae --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.java @@ -0,0 +1,100 @@ +package com.boydti.fawe.object.clipboard; + +import com.sk89q.worldedit.EditSession; +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.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +public class EmptyClipboard implements Clipboard { + + public static final EmptyClipboard INSTANCE = new EmptyClipboard(); + + private EmptyClipboard() {} + + @Override + public Region getRegion() { + return new CuboidRegion(new Vector(), new Vector()); + } + + @Override + public Vector getDimensions() { + return new Vector(); + } + + @Override + public Vector getOrigin() { + return new Vector(); + } + + @Override + public void setOrigin(Vector origin) {} + + @Override + public Vector getMinimumPoint() { + return new Vector(); + } + + @Override + public Vector getMaximumPoint() { + return new Vector(); + } + + @Override + public List getEntities(Region region) { + return new ArrayList<>(); + } + + @Override + public List getEntities() { + return new ArrayList<>(); + } + + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity) { + return null; + } + + @Override + public BaseBlock getBlock(Vector position) { + return EditSession.nullBlock; + } + + @Override + public BaseBlock getLazyBlock(Vector position) { + return EditSession.nullBlock; + } + + @Override + public BaseBiome getBiome(Vector2D position) { + return EditSession.nullBiome; + } + + @Override + public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException { + return false; + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return false; + } + + @Nullable + @Override + public Operation commit() { + return null; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/LazyClipboardHolder.java b/core/src/main/java/com/boydti/fawe/object/clipboard/LazyClipboardHolder.java new file mode 100644 index 00000000..c3b68d14 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/LazyClipboardHolder.java @@ -0,0 +1,54 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.object.schematic.StructureFormat; +import com.google.common.io.ByteSource; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; +import com.sk89q.worldedit.extent.clipboard.io.SchematicReader; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.registry.WorldData; +import java.io.InputStream; +import java.util.UUID; + +public class LazyClipboardHolder extends ClipboardHolder { + private final ByteSource source; + private final ClipboardFormat format; + private final UUID uuid; + private Clipboard clipboard; + + /** + * Create a new instance with the given clipboard. + * + * @param worldData the mapping of blocks, entities, and so on + */ + public LazyClipboardHolder(ByteSource source, ClipboardFormat format, WorldData worldData, UUID uuid) { + super(EmptyClipboard.INSTANCE, worldData); + this.source = source; + this.format = format; + this.uuid = uuid != null ? uuid : UUID.randomUUID(); + } + + + @Override + public Clipboard getClipboard() { + if (clipboard == null) { + try { + try (InputStream in = source.openBufferedStream()) { + final ClipboardReader reader = format.getReader(in); + final Clipboard clipboard; + if (reader instanceof SchematicReader) { + this.clipboard = ((SchematicReader) reader).read(getWorldData(), uuid); + } else if (reader instanceof StructureFormat) { + this.clipboard = ((StructureFormat) reader).read(getWorldData(), uuid); + } else { + this.clipboard = reader.read(getWorldData()); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + return clipboard; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java b/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java index e285cbd1..edce4ad5 100644 --- a/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java +++ b/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java @@ -16,13 +16,18 @@ import java.util.Set; public class LocalBlockVectorSet implements Set { private int offsetX, offsetZ; private final SparseBitSet set; - private BlockVector mVec = new BlockVector(0, 0, 0); public LocalBlockVectorSet() { offsetX = offsetZ = Integer.MAX_VALUE; this.set = new SparseBitSet(); } + public LocalBlockVectorSet(int x, int z, SparseBitSet set) { + this.offsetX = x; + this.offsetZ = z; + this.set = set; + } + public SparseBitSet getBitSet() { return set; } @@ -50,6 +55,38 @@ public class LocalBlockVectorSet implements Set { return false; } + @Override + public LocalBlockVectorSet clone() { + return new LocalBlockVectorSet(offsetX, offsetZ, set.clone()); + } + + public boolean containsRadius(int x, int y, int z, int radius) { + int length = radius * 2; + if (size() < length * length * length) { + int index = -1; + while ((index = set.nextSetBit(index + 1)) != -1) { + int b1 = (index & 0xFF); + int b2 = ((byte) (index >> 8)) & 0x7F; + int b3 = ((byte)(index >> 15)) & 0xFF; + int b4 = ((byte) (index >> 23)) & 0xFF; + if (Math.abs((offsetX + (((b3 + ((MathMan.unpair8x(b2)) << 8)) << 21) >> 21)) - x) <= radius && Math.abs((offsetZ + (((b4 + ((MathMan.unpair8y(b2)) << 8)) << 21) >> 21)) - z) <= radius && Math.abs((b1) - y) <= radius) { + return true; + } + } + return false; + } + for (int xx = -radius; xx <= radius; xx++) { + for (int yy = -radius; yy <= radius; yy++) { + for (int zz = -radius; zz <= radius; zz++) { + if (contains(x + xx, y + yy, z + zz)) { + return true; + } + } + } + } + return false; + } + public void addOffset(int x, int z) { this.offsetX += x; this.offsetZ += z; @@ -134,9 +171,12 @@ public class LocalBlockVectorSet implements Set { throw new UnsupportedOperationException("LocalVectorSet can only contain vectors from y elem:[0,255]"); } int index = getIndex(x, y, z); - boolean value = set.get(index); - set.set(index); - return !value; + if (set.get(index)) { + return false; + } else { + set.set(index); + return true; + } } @Override @@ -196,9 +236,10 @@ public class LocalBlockVectorSet implements Set { public boolean retainAll(Collection c) { boolean result = false; int size = size(); - int index = 0; + int index = -1; + Vector mVec = MutableBlockVector.get(0, 0, 0); for (int i = 0; i < size; i++) { - index = set.nextSetBit(index); + index = set.nextSetBit(index + 1); int b1 = (index & 0xFF); int b2 = ((byte) (index >> 8)) & 0x7F; int b3 = ((byte)(index >> 15)) & 0xFF; @@ -210,7 +251,6 @@ public class LocalBlockVectorSet implements Set { result = true; set.clear(index); } - index++; } return result; } @@ -224,6 +264,27 @@ public class LocalBlockVectorSet implements Set { return result; } + public void forEach(BlockVectorSetVisitor visitor) { + int size = size(); + int index = -1; + Vector mVec = MutableBlockVector.get(0, 0, 0); + for (int i = 0; i < size; i++) { + index = set.nextSetBit(index + 1); + int b1 = (index & 0xFF); + int b2 = ((byte) (index >> 8)) & 0x7F; + int b3 = ((byte)(index >> 15)) & 0xFF; + int b4 = ((byte) (index >> 23)) & 0xFF; + int x = offsetX + (((b3 + ((MathMan.unpair8x(b2)) << 8)) << 21) >> 21); + int y = b1; + int z = offsetZ + (((b4 + ((MathMan.unpair8y(b2)) << 8)) << 21) >> 21); + visitor.run(x, y, z, index); + } + } + + public static abstract class BlockVectorSetVisitor { + public abstract void run(int x, int y, int z, int index); + } + @Override public void clear() { set.clear(); diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/BlockPattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/BlockPattern.java new file mode 100644 index 00000000..a2e9ffe5 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/pattern/BlockPattern.java @@ -0,0 +1,55 @@ +package com.sk89q.worldedit.function.pattern; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.function.pattern.AbstractPattern; + + +import static com.google.common.base.Preconditions.checkNotNull; + +public class BlockPattern extends AbstractPattern { + + private BaseBlock block; + + public BlockPattern(BaseBlock block) { + this.block = block; + } + + @Override + public BaseBlock apply(Vector position) { + return block; + } + + @Override + public BaseBlock next(int x, int y, int z) { + return block; + } + + @Override + public BaseBlock next(Vector position) { + return block; + } + + /** + * Get the block. + * + * @return the block that is always returned + */ + public BaseBlock getBlock() { + return block; + } + + /** + * Set the block that is returned. + * + * @param block the block + */ + public void setBlock(BaseBlock block) { + checkNotNull(block); + this.block = block; + } + + public static Class inject() { + return BlockPattern.class; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java b/core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java index 1a777dd5..03bcd940 100644 --- a/core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java +++ b/core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java @@ -10,7 +10,6 @@ import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -50,7 +49,7 @@ public abstract class DFSVisitor implements Operation { public abstract boolean isVisitable(Vector from, Vector to); - public Collection getDirections() { + public List getDirections() { return this.directions; } diff --git a/core/src/main/java/com/boydti/fawe/util/MainUtil.java b/core/src/main/java/com/boydti/fawe/util/MainUtil.java index 09af0afd..68fe1877 100644 --- a/core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -523,6 +523,10 @@ public class MainUtil { } return newFile; } + File parent = newFile.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } newFile.createNewFile(); try (FileOutputStream fos = new FileOutputStream(newFile)) { int len; diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 97dbd95a..b2331d01 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -1150,6 +1150,15 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting } } + public boolean setBlock(int x, int y, int z, Pattern pattern) { + this.changes++; + try { + return this.extent.setBlock(x, y, z, pattern.next(x, y, z)); + } catch (WorldEditException e) { + throw new RuntimeException("Unexpected exception", e); + } + } + @Override public boolean setBlock(final Vector position, final BaseBlock block, final boolean ignorePhysics) throws MaxChangedBlocksException { return setBlockFast(position, block); diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 742e30b3..12696ab9 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -25,7 +25,6 @@ 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.visualization.VisualBrush; import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; @@ -42,7 +41,6 @@ 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; @@ -777,6 +775,11 @@ public class LocalSession { return clipboard; } + @Nullable + public ClipboardHolder getExistingClipboard() { + return clipboard; + } + /** * Sets the clipboard. * @@ -979,11 +982,19 @@ public class LocalSession { } public BrushTool getBrushTool(int item, Player player) throws InvalidToolBindException { + return getBrushTool(item, player, true); + } + + public BrushTool getBrushTool(int item, Player player, boolean create) throws InvalidToolBindException { Tool tool = getTool(item); - if (tool == null || !(tool instanceof BrushTool)) { - tool = new BrushTool("worldedit.brush.sphere"); - setTool(item, tool, player); + if ((tool == null || !(tool instanceof BrushTool))) { + if (create) { + tool = new BrushTool("worldedit.brush.sphere"); + setTool(item, tool, player); + } else { + return null; + } } return (BrushTool) tool; @@ -1011,12 +1022,8 @@ public class LocalSession { 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); + BrushTool brushTool = (BrushTool) previous; + brushTool.clear(player); } } } diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 0d089368..465dc6c5 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -32,10 +32,24 @@ import com.boydti.fawe.object.brush.ErodeBrush; import com.boydti.fawe.object.brush.FlattenBrush; import com.boydti.fawe.object.brush.HeightBrush; import com.boydti.fawe.object.brush.LineBrush; +import com.boydti.fawe.object.brush.RaiseBrush; import com.boydti.fawe.object.brush.RecurseBrush; import com.boydti.fawe.object.brush.SplineBrush; +import com.boydti.fawe.object.brush.TargetMode; import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap; +import com.boydti.fawe.object.brush.scroll.ScrollClipboard; +import com.boydti.fawe.object.brush.scroll.ScrollMask; +import com.boydti.fawe.object.brush.scroll.ScrollPattern; +import com.boydti.fawe.object.brush.scroll.ScrollRange; +import com.boydti.fawe.object.brush.scroll.ScrollSize; +import com.boydti.fawe.object.brush.scroll.ScrollTarget; +import com.boydti.fawe.object.brush.visualization.VisualMode; +import com.boydti.fawe.object.clipboard.LazyClipboardHolder; +import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.mask.IdMask; +import com.boydti.fawe.util.MathMan; +import com.google.common.io.ByteSource; +import com.google.common.io.Files; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; @@ -59,14 +73,21 @@ import com.sk89q.worldedit.command.tool.brush.SmoothBrush; import com.sk89q.worldedit.command.tool.brush.SphereBrush; import com.sk89q.worldedit.command.util.CreatureButcher; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.event.platform.CommandEvent; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.world.registry.WorldData; import java.io.File; +import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -74,6 +95,10 @@ import java.io.InputStream; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import static com.google.common.base.Preconditions.checkNotNull; @@ -95,6 +120,227 @@ public class BrushCommands { this.worldEdit = worldEdit; } + @Command( + aliases = { "primary" }, + usage = "[brush arguments]", + desc = "Set the right click brush", + help = "Set the right click brush", + min = 1 + ) + public void primary(Player player, LocalSession session, CommandContext args) throws WorldEditException { + int item = player.getItemInHand(); + BrushTool tool = session.getBrushTool(item, player, false); + session.setTool(item, null); + String cmd = "brush " + args.getJoinedStrings(0); + CommandEvent event = new CommandEvent(player, cmd); + CommandManager.getInstance().handleCommandOnCurrentThread(event); + BrushTool newTool = session.getBrushTool(item, player, false); + if (newTool != null && tool != null) { + newTool.setSecondary(tool.getSecondary()); + } + } + + @Command( + aliases = { "secondary" }, + usage = "[brush arguments]", + desc = "Set the left click brush", + help = "Set the left click brush", + min = 1 + ) + public void secondary(Player player, LocalSession session, CommandContext args) throws WorldEditException { + int item = player.getItemInHand(); + BrushTool tool = session.getBrushTool(item, player, false); + session.setTool(item, null); + String cmd = "brush " + args.getJoinedStrings(0); + CommandEvent event = new CommandEvent(player, cmd); + CommandManager.getInstance().handleCommandOnCurrentThread(event); + BrushTool newTool = session.getBrushTool(item, player, false); + if (newTool != null && tool != null) { + newTool.setPrimary(tool.getPrimary()); + } + } + + @Command( + aliases = { "visualize", "visual", "vis" }, + usage = "[mode]", + desc = "Toggle between different visualization modes", + min = 0, + max = 1 + ) + public void visual(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException { + int item = player.getItemInHand(); + BrushTool tool = session.getBrushTool(item, player, false); + if (tool == null) { + BBC.BRUSH_NONE.send(player); + return; + } + VisualMode[] modes = VisualMode.values(); + VisualMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)]; + tool.setVisualMode(newMode); + BBC.BRUSH_VISUAL_MODE_SET.send(player, newMode); + } + + @Command( + aliases = { "target", "tar" }, + usage = "[mode]", + desc = "Toggle between different target modes", + min = 0, + max = 1 + ) + public void target(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException { + int item = player.getItemInHand(); + BrushTool tool = session.getBrushTool(item, player, false); + if (tool == null) { + BBC.BRUSH_NONE.send(player); + return; + } + TargetMode[] modes = TargetMode.values(); + TargetMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)]; + tool.setTargetMode(newMode); + BBC.BRUSH_TARGET_MODE_SET.send(player, newMode); + } + + + @Command( + aliases = { "scroll" }, + usage = "[none|clipboard|mask|pattern|range|size|visual|target]", + desc = "Toggle between different target modes", + min = 1, + max = -1 + ) + public void scroll(Player player, EditSession editSession, LocalSession session, CommandContext args) throws WorldEditException { + int item = player.getItemInHand(); + BrushTool tool = session.getBrushTool(item, player, false); + if (tool == null) { + BBC.BRUSH_NONE.send(player); + return; + } + ParserContext parserContext = new ParserContext(); + parserContext.setActor(player); + parserContext.setWorld(player.getWorld()); + parserContext.setSession(session); + parserContext.setExtent(editSession); + final LocalConfiguration config = this.worldEdit.getConfiguration(); + switch (args.getString(0).toLowerCase()) { + case "none": + tool.setScrollAction(null); + break; + case "clipboard": + if (args.argsLength() != 2) { + BBC.COMMAND_SYNTAX.send(player, "clipboard [file]"); + return; + } + String filename = args.getString(1); + try { + WorldData worldData = player.getWorld().getWorldData(); + if (filename.startsWith("http")) { + URL url = new URL(filename); + URL webInterface = new URL(Settings.IMP.WEB.URL); + if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) { + BBC.WEB_UNAUTHORIZED.send(player, url); + return; + } + List clipboards = new ArrayList<>(); + try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) { + try (InputStream in = Channels.newInputStream(rbc)) { + try (ZipInputStream zip = new ZipInputStream(in)) { + ZipEntry entry; + byte[] buffer = new byte[8192]; + while ((entry = zip.getNextEntry()) != null) { + if (entry.getName().endsWith(".schematic")) { + FastByteArrayOutputStream out = new FastByteArrayOutputStream(); + int len = 0; + while ((len = zip.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + byte[] array = out.toByteArray(); + ByteSource source = ByteSource.wrap(array); + LazyClipboardHolder clipboard = new LazyClipboardHolder(source, ClipboardFormat.SCHEMATIC, worldData, null); + clipboards.add(clipboard); + } + } + } + } + } + tool.setScrollAction(new ScrollClipboard(tool, session, clipboards.toArray(new LazyClipboardHolder[clipboards.size()]))); + } else { + if (filename.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) { + BBC.NO_PERM.send(player, "worldedit.schematic.load.other"); + return; + } + File dir = new File(this.worldEdit.getWorkingDirectoryFile(config.saveDir), player.getUniqueId() + File.separator + filename); + if (!dir.exists()) { + if (!filename.contains("/") && !filename.contains("\\")) { + dir = new File(this.worldEdit.getWorkingDirectoryFile(config.saveDir), filename); + } + } + if (!dir.exists() || !dir.isDirectory()) { + BBC.SCHEMATIC_NOT_FOUND.send(player, filename); + return; + } + File[] files = dir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getName().endsWith(".schematic"); + } + }); + if (files.length < 1) { + BBC.SCHEMATIC_NOT_FOUND.send(player, filename); + return; + } + LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length]; + for (int i = 0; i < files.length; i++) { + File file = files[i]; + ByteSource source = Files.asByteSource(file); + clipboards[i] = new LazyClipboardHolder(source, ClipboardFormat.SCHEMATIC, worldData, null); + } + tool.setScrollAction(new ScrollClipboard(tool, session, clipboards)); + } + break; + } catch (IOException e) { + throw new RuntimeException(e); + } + case "mask": + if (args.argsLength() < 2) { + BBC.COMMAND_SYNTAX.send(player, "mask [mask 1] [mask 2] [mask 3]..."); + return; + } + Mask[] masks = new Mask[args.argsLength() - 1]; + for (int i = 1; i < args.argsLength(); i++) { + String arg = args.getString(i); + masks[i - 1] = worldEdit.getMaskFactory().parseFromInput(arg, parserContext); + } + tool.setScrollAction(new ScrollMask(tool, masks)); + break; + case "pattern": + if (args.argsLength() < 2) { + BBC.COMMAND_SYNTAX.send(player, "pattern [pattern 1] [pattern 2] [pattern 3]..."); + return; + } + Pattern[] patterns = new Pattern[args.argsLength() - 1]; + for (int i = 1; i < args.argsLength(); i++) { + String arg = args.getString(i); + patterns[i - 1] = worldEdit.getPatternFactory().parseFromInput(arg, parserContext); + } + tool.setScrollAction(new ScrollPattern(tool, patterns)); + break; + case "range": + tool.setScrollAction(new ScrollRange(tool)); + break; + case "size": + tool.setScrollAction(new ScrollSize(tool)); + break; + case "target": + tool.setScrollAction(new ScrollTarget(tool)); + break; + default: + BBC.COMMAND_SYNTAX.send(player, "[none|clipboard|mask|pattern|range|size|visual|target]"); + return; + + } + BBC.BRUSH_SCROLL_ACTION_SET.send(player, args.getJoinedStrings(0)); + } + @Command( aliases = { "blendball", "bb", "blend" }, usage = "[radius]", @@ -129,6 +375,23 @@ public class BrushCommands { player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius)); } + @Command( + aliases = { "raise" }, + usage = "[radius]", + desc = "Choose the raise brush", + help = "Chooses the raise brush", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.raise") + public void raiseBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + BrushTool tool = session.getBrushTool(player.getItemInHand(), player); + tool.setSize(radius); + tool.setBrush(new RaiseBrush(), "worldedit.brush.erode", player); + player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius)); + } + @Command( aliases = { "circle" }, usage = " [radius]", @@ -191,7 +454,7 @@ public class BrushCommands { } @Command( - aliases = { "spline", "spl" }, + aliases = { "spline", "spl", "curve" }, usage = "", desc = "Choose the spline brush", help = "Chooses the spline brush", @@ -246,6 +509,28 @@ public class BrushCommands { if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) BBC.TIP_BRUSH_COMMAND.or(BBC.TIP_BRUSH_RELATIVE, BBC.TIP_BRUSH_TRANSFORM, BBC.TIP_BRUSH_MASK_SOURCE, BBC.TIP_BRUSH_MASK, BBC.TIP_BRUSH_COPY, BBC.TIP_BRUSH_HEIGHT, BBC.TIP_BRUSH_SPLINE).send(player); } +// @Command( +// aliases = { "test" }, +// usage = " [radius] [count] [distance]", +// flags = "h", +// desc = "Choose the sphere brush", +// help = +// "Chooses the sphere brush.\n" + +// "The -h flag creates hollow spheres instead.", +// min = 1, +// max = -1 +// ) +// @CommandPermissions("worldedit.brush.test") +// public void testBrush(Player player, LocalSession session, Pattern fill, @Optional("10") double radius, @Optional("10") int count, @Optional("10") int distance) throws WorldEditException { +// worldEdit.checkMaxBrushRadius(radius); +// +// BrushTool tool = session.getBrushTool(player.getItemInHand(), player); +// tool.setFill(fill); +// tool.setSize(radius); +// tool.setBrush(new Test(count), "worldedit.brush.test"); +// player.print("equiped"); +// } + @Command( aliases = { "cylinder", "cyl", "c" }, usage = " [radius] [height]", @@ -484,7 +769,7 @@ public class BrushCommands { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player.getItemInHand(), player); tool.setSize(radius); - tool.setBrush(new CopyPastaBrush(tool), "worldedit.brush.copy", player); + tool.setBrush(new CopyPastaBrush(tool, session), "worldedit.brush.copy", player); player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius)); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index fc4a390d..caa83c78 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -73,7 +73,7 @@ public class HistoryCommands { } @Command( - aliases = { "/frb", "frb", "fawerollback", "/fawerollback" }, + aliases = { "/frb", "frb", "fawerollback", "/fawerollback", "/rollback" }, usage = "