mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Various
Improved web integrated clipboard Fully fledged brush visualization (modes 0-2): //br vis Brush targeting modes (0-3): //br target Brush scroll actions: //br scroll - change clipboard from directory or web - change mask - change pattern - change range - change size - change target mode Build multi-brushes (choose the brush for left click and right click individually) - //br primary - //br secondary - Changing the pattern/mask will affect the currently selected brush, not both Changes to brush behavior - spline connects by clicking the same spot twice - line/copy brush tweaks Schematics now default per user - To save/load globally use "../" before the filename Easily save a schematic to a directory - `//schem save folder/` will choose save a the next lowest free number Improved block parsing Add resettable brushes - e.g. line brush resets points by shift + left click
This commit is contained in:
parent
9c74d0b981
commit
04603b7cee
@ -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<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();
|
||||
}
|
||||
Player bukkitPlayer = event.getPlayer();
|
||||
if (bukkitPlayer.isSneaking()) {
|
||||
if (event.getAction() == Action.PHYSICAL) {
|
||||
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 instanceof ResettableTool) {
|
||||
if (((ResettableTool) tool).reset()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
public interface ResettableTool {
|
||||
boolean reset();
|
||||
}
|
@ -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<ArrayList<Vector>> 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<Vector> 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<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);
|
||||
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<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++) {
|
||||
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<Vector>() {
|
||||
@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<Vector> centroids = new ArrayList<>();
|
||||
for (List<Vector> points : positionSets) {
|
||||
centroids.add(getCentroid(points));
|
||||
}
|
||||
|
||||
double tension = 0;
|
||||
double bias = 0;
|
||||
double continuity = 0;
|
||||
double quality = 10;
|
||||
|
||||
final List<Node> nodes = new ArrayList<Node>(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<Vector> currentSpline = new ArrayList<>();
|
||||
for (ArrayList<Vector> 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<Vector> centroids = new ArrayList<>();
|
||||
for (List<Vector> points : positionSets) {
|
||||
centroids.add(getCentroid(points));
|
||||
}
|
||||
|
||||
double tension = 0;
|
||||
double bias = 0;
|
||||
double continuity = 0;
|
||||
double quality = 10;
|
||||
|
||||
final List<Node> nodes = new ArrayList<Node>(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<Vector> currentSpline = new ArrayList<>();
|
||||
for (ArrayList<Vector> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,5 +4,5 @@ public enum TargetMode {
|
||||
TARGET_BLOCK_RANGE,
|
||||
FOWARD_POINT_PITCH,
|
||||
TARGET_POINT_HEIGHT,
|
||||
TARGET_POINT_RANGE,
|
||||
TARGET_FACE_RANGE,
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
public interface ScrollableBrush {
|
||||
public boolean increment(int amount);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<? extends Entity> getEntities(Region region) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -16,13 +16,18 @@ import java.util.Set;
|
||||
public class LocalBlockVectorSet implements Set<Vector> {
|
||||
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<Vector> {
|
||||
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<Vector> {
|
||||
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<Vector> {
|
||||
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<Vector> {
|
||||
result = true;
|
||||
set.clear(index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -224,6 +264,27 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
||||
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();
|
||||
|
@ -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<BlockPattern> inject() {
|
||||
return BlockPattern.class;
|
||||
}
|
||||
}
|
@ -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<Vector> getDirections() {
|
||||
public List<Vector> getDirections() {
|
||||
return this.directions;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<LazyClipboardHolder> 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 = "<pattern> [radius]",
|
||||
@ -191,7 +454,7 @@ public class BrushCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "spline", "spl" },
|
||||
aliases = { "spline", "spl", "curve" },
|
||||
usage = "<pattern>",
|
||||
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 = "<pattern> [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 = "<block> [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));
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public class HistoryCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/frb", "frb", "fawerollback", "/fawerollback" },
|
||||
aliases = { "/frb", "frb", "fawerollback", "/fawerollback", "/rollback" },
|
||||
usage = "<user> <radius> <time>",
|
||||
desc = "Undo edits within a radius",
|
||||
min = 1,
|
||||
|
@ -257,7 +257,7 @@ public class RegionCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/curve" },
|
||||
aliases = { "/curve", "/spline" },
|
||||
usage = "<block> [thickness]",
|
||||
desc = "Draws a spline through selected points",
|
||||
help =
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
@ -114,12 +115,31 @@ public class SchematicCommands {
|
||||
BBC.NO_PERM.send(player, "worldedit.clipboard.load");
|
||||
return;
|
||||
}
|
||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
final File f = this.worldEdit.getSafeOpenFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
if (!f.exists()) {
|
||||
player.printError("Schematic " + filename + " does not exist!");
|
||||
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().toString());
|
||||
File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
if (f.getName().replaceAll("." + format.getExtension(), "").isEmpty()) {
|
||||
File directory = f.getParentFile();
|
||||
if (directory.exists()) {
|
||||
int max = MainUtil.getMaxFileId(directory) - 1;
|
||||
f = new File(directory, max + "." + format.getExtension());
|
||||
} else {
|
||||
f = new File(directory, "1." + format.getExtension());
|
||||
}
|
||||
}
|
||||
if (!f.exists()) {
|
||||
if (!filename.contains("/") && !filename.contains("\\")) {
|
||||
dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
}
|
||||
if (!f.exists()) {
|
||||
player.printError("Schematic " + filename + " does not exist!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final String filePath = f.getCanonicalPath();
|
||||
final String dirPath = dir.getCanonicalPath();
|
||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||
@ -156,16 +176,28 @@ public class SchematicCommands {
|
||||
@Command(aliases = { "save" }, usage = "[<format>] <filename>", desc = "Save a schematic into your clipboard")
|
||||
@Deprecated
|
||||
@CommandPermissions({ "worldedit.clipboard.save", "worldedit.schematic.save" })
|
||||
public void save(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws CommandException, WorldEditException {
|
||||
public void save(final Player player, final LocalSession session, @Optional("schematic") final String formatName, String filename) throws CommandException, WorldEditException {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
player.printError("Unknown schematic format: " + formatName);
|
||||
return;
|
||||
}
|
||||
|
||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
if (filename.contains("../") && !player.hasPermission("worldedit.schematic.save.other")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.schematic.save.other");
|
||||
return;
|
||||
}
|
||||
final File dir = new File(this.worldEdit.getWorkingDirectoryFile(config.saveDir), player.getUniqueId().toString());
|
||||
File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
if (f.getName().replaceAll("." + format.getExtension(), "").isEmpty()) {
|
||||
File directory = f.getParentFile();
|
||||
if (directory.exists()) {
|
||||
int max = MainUtil.getMaxFileId(directory);
|
||||
f = new File(directory, max + "." + format.getExtension());
|
||||
} else {
|
||||
f = new File(directory, "1." + format.getExtension());
|
||||
}
|
||||
}
|
||||
final File parent = f.getParentFile();
|
||||
if ((parent != null) && !parent.exists()) {
|
||||
if (!parent.mkdirs()) {
|
||||
|
@ -1,14 +1,26 @@
|
||||
package com.sk89q.worldedit.command.tool;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
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.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.BrushSettings;
|
||||
import com.boydti.fawe.object.brush.MovableTool;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollAction;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollTool;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
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.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
@ -18,12 +30,15 @@ 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 com.sk89q.worldedit.util.Location;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BrushTool implements DoubleActionTraceTool {
|
||||
public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool {
|
||||
|
||||
public enum BrushAction {
|
||||
PRIMARY,
|
||||
@ -32,14 +47,12 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
|
||||
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 = null;
|
||||
@Nullable
|
||||
private Pattern material;
|
||||
private double size = 1;
|
||||
private String permission;
|
||||
private VisualMode visualMode = VisualMode.NONE;
|
||||
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||
|
||||
private BrushSettings context = new BrushSettings();
|
||||
private BrushSettings primary = context;
|
||||
private BrushSettings secondary = context;
|
||||
|
||||
/**
|
||||
* Construct the tool.
|
||||
@ -48,20 +61,41 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
*/
|
||||
public BrushTool(String permission) {
|
||||
checkNotNull(permission);
|
||||
this.permission = permission;
|
||||
this.context.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Actor player) {
|
||||
return player.hasPermission(permission);
|
||||
if (primary == secondary) {
|
||||
return player.hasPermission(context.permission);
|
||||
}
|
||||
return player.hasPermission(primary.permission) && player.hasPermission(secondary.permission);
|
||||
}
|
||||
|
||||
public ResettableExtent getTransform() {
|
||||
return transform;
|
||||
return context.transform;
|
||||
}
|
||||
|
||||
public BrushSettings getPrimary() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
public BrushSettings getSecondary() {
|
||||
return secondary;
|
||||
}
|
||||
|
||||
public void setPrimary(BrushSettings primary) {
|
||||
checkNotNull(primary);
|
||||
this.primary = primary;
|
||||
}
|
||||
|
||||
public void setSecondary(BrushSettings secondary) {
|
||||
checkNotNull(secondary);
|
||||
this.secondary = secondary;
|
||||
}
|
||||
|
||||
public void setTransform(ResettableExtent transform) {
|
||||
this.transform = transform;
|
||||
this.context.transform = transform;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +104,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @return the filter
|
||||
*/
|
||||
public Mask getMask() {
|
||||
return mask;
|
||||
return context.mask;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +113,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @return the filter
|
||||
*/
|
||||
public Mask getSourceMask() {
|
||||
return sourceMask;
|
||||
return context.sourceMask;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +122,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setMask(Mask filter) {
|
||||
this.mask = filter;
|
||||
this.context.mask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +131,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @param filter the filter to set
|
||||
*/
|
||||
public void setSourceMask(Mask filter) {
|
||||
this.sourceMask = filter;
|
||||
this.context.sourceMask = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,11 +145,10 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
}
|
||||
|
||||
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;
|
||||
if (player != null) clear(player);
|
||||
BrushSettings current = context;
|
||||
current.brush = brush;
|
||||
current.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,7 +157,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @return the current brush
|
||||
*/
|
||||
public Brush getBrush() {
|
||||
return brush;
|
||||
return context.brush;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +166,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @param material the material
|
||||
*/
|
||||
public void setFill(@Nullable Pattern material) {
|
||||
this.material = material;
|
||||
this.context.material = material;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,7 +175,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @return the material
|
||||
*/
|
||||
@Nullable public Pattern getMaterial() {
|
||||
return material;
|
||||
return context.material;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,7 +184,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @return a radius
|
||||
*/
|
||||
public double getSize() {
|
||||
return size;
|
||||
return context.size;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +193,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
* @param radius a radius
|
||||
*/
|
||||
public void setSize(double radius) {
|
||||
this.size = radius;
|
||||
this.context.size = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,57 +214,96 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
if (action == BrushAction.SECONDARY && !(brush instanceof DoubleActionBrush)) {
|
||||
return false;
|
||||
public Vector getPosition(EditSession editSession, Player player) {
|
||||
switch (targetMode) {
|
||||
case TARGET_BLOCK_RANGE:
|
||||
return player.getBlockTrace(getRange(), true);
|
||||
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_FACE_RANGE:
|
||||
return player.getBlockTraceFace(getRange(), true);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
WorldVector target = null;
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
}
|
||||
|
||||
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
||||
switch (action) {
|
||||
case PRIMARY:
|
||||
context = primary;
|
||||
break;
|
||||
case SECONDARY:
|
||||
context = secondary;
|
||||
break;
|
||||
}
|
||||
|
||||
BrushSettings current = context;
|
||||
|
||||
EditSession editSession = session.createEditSession(player);
|
||||
Vector target = getPosition(editSession, player);
|
||||
|
||||
if (target == null) {
|
||||
editSession.cancel();
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
BlockBag bag = session.getBlockBag(player);
|
||||
|
||||
EditSession editSession = session.createEditSession(player);
|
||||
Request.request().setEditSession(editSession);
|
||||
if (mask != null) {
|
||||
if (current.mask != null) {
|
||||
Mask existingMask = editSession.getMask();
|
||||
|
||||
if (existingMask == null) {
|
||||
editSession.setMask(mask);
|
||||
editSession.setMask(current.mask);
|
||||
} else if (existingMask instanceof MaskIntersection) {
|
||||
((MaskIntersection) existingMask).add(mask);
|
||||
((MaskIntersection) existingMask).add(current.mask);
|
||||
} else {
|
||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||
newMask.add(mask);
|
||||
newMask.add(current.mask);
|
||||
editSession.setMask(newMask);
|
||||
}
|
||||
}
|
||||
if (sourceMask != null) {
|
||||
if (current.sourceMask != null) {
|
||||
Mask existingMask = editSession.getSourceMask();
|
||||
|
||||
if (existingMask == null) {
|
||||
editSession.setSourceMask(sourceMask);
|
||||
editSession.setSourceMask(current.sourceMask);
|
||||
} else if (existingMask instanceof MaskIntersection) {
|
||||
((MaskIntersection) existingMask).add(sourceMask);
|
||||
((MaskIntersection) existingMask).add(current.sourceMask);
|
||||
} else {
|
||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||
newMask.add(sourceMask);
|
||||
newMask.add(current.sourceMask);
|
||||
editSession.setSourceMask(newMask);
|
||||
}
|
||||
}
|
||||
if (transform != null) {
|
||||
editSession.addTransform(transform);
|
||||
if (current.transform != null) {
|
||||
editSession.addTransform(current.transform);
|
||||
}
|
||||
try {
|
||||
if (brush instanceof DoubleActionBrush) {
|
||||
((DoubleActionBrush) brush).build(action, editSession, target, material, size);
|
||||
} else {
|
||||
brush.build(editSession, target, material, size);
|
||||
}
|
||||
current.brush.build(editSession, target, current.material, current.size);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached."); // Never happens
|
||||
} finally {
|
||||
@ -256,4 +328,104 @@ public class BrushTool implements DoubleActionTraceTool {
|
||||
public static Class<?> inject() {
|
||||
return BrushTool.class;
|
||||
}
|
||||
|
||||
public void setScrollAction(ScrollAction scrollAction) {
|
||||
this.context.scrollAction = scrollAction;
|
||||
}
|
||||
|
||||
public void setTargetMode(TargetMode targetMode) {
|
||||
this.targetMode = targetMode != null ? targetMode : TargetMode.TARGET_BLOCK_RANGE;
|
||||
}
|
||||
|
||||
public void setVisualMode(VisualMode visualMode) {
|
||||
this.visualMode = visualMode != null ? visualMode : VisualMode.NONE;
|
||||
}
|
||||
|
||||
public TargetMode getTargetMode() {
|
||||
return targetMode;
|
||||
}
|
||||
|
||||
public VisualMode getVisualMode() {
|
||||
return visualMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean increment(Player player, int amount) {
|
||||
BrushSettings current = context;
|
||||
ScrollAction tmp = current.scrollAction;
|
||||
if (tmp != null && tmp.increment(player, amount)) {
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
try {
|
||||
queueVisualization(FawePlayer.wrap(player));
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void queueVisualization(FawePlayer player) {
|
||||
Fawe.get().getVisualQueue().queue(player);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public synchronized void visualize(BrushTool.BrushAction action, Player player) throws MaxChangedBlocksException {
|
||||
VisualMode mode = getVisualMode();
|
||||
if (mode == VisualMode.NONE) {
|
||||
return;
|
||||
}
|
||||
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());
|
||||
Vector position = getPosition(editSession, player);
|
||||
if (position != null) {
|
||||
editSession.setExtent(newVisualExtent);
|
||||
switch (mode) {
|
||||
case POINT: {
|
||||
editSession.setBlockFast(position, FaweCache.getBlock(VisualChunk.VISUALIZE_BLOCK, 0));
|
||||
break;
|
||||
}
|
||||
case OUTLINE: {
|
||||
BrushSettings current = context;
|
||||
current.brush.build(editSession, position, current.material, current.size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
queueVisualization(FawePlayer.wrap(player));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private VisualExtent visualExtent;
|
||||
private Lock lock = new ReentrantLock();
|
||||
}
|
||||
|
@ -162,21 +162,28 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
} else {
|
||||
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(testId);
|
||||
if (block == null) {
|
||||
blockType = BlockType.lookup(testId);
|
||||
if (blockType == null) {
|
||||
int t = worldEdit.getServer().resolveItem(testId);
|
||||
if (t >= 0) {
|
||||
blockType = BlockType.fromID(t); // Could be null
|
||||
blockId = t;
|
||||
} else if (blockLocator.length == 2) { // Block IDs in MC 1.7 and above use mod:name
|
||||
t = worldEdit.getServer().resolveItem(blockAndExtraData[0]);
|
||||
BaseBlock baseBlock = BundledBlockData.getInstance().findByState(testId);
|
||||
if (baseBlock == null) {
|
||||
blockType = BlockType.lookup(testId);
|
||||
if (blockType == null) {
|
||||
int t = worldEdit.getServer().resolveItem(testId);
|
||||
if (t >= 0) {
|
||||
blockType = BlockType.fromID(t); // Could be null
|
||||
blockId = t;
|
||||
typeAndData = new String[] { blockAndExtraData[0] };
|
||||
testId = blockAndExtraData[0];
|
||||
} else if (blockLocator.length == 2) { // Block IDs in MC 1.7 and above use mod:name
|
||||
t = worldEdit.getServer().resolveItem(blockAndExtraData[0]);
|
||||
if (t >= 0) {
|
||||
blockType = BlockType.fromID(t); // Could be null
|
||||
blockId = t;
|
||||
typeAndData = new String[]{blockAndExtraData[0]};
|
||||
testId = blockAndExtraData[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
blockId = baseBlock.getId();
|
||||
blockType = BlockType.fromID(blockId);
|
||||
data = baseBlock.getData();
|
||||
}
|
||||
} else {
|
||||
blockId = block.legacyId;
|
||||
|
@ -185,7 +185,9 @@ public final class CommandManager {
|
||||
.group("superpickaxe", "pickaxe", "sp").describeAs("Super-pickaxe commands")
|
||||
.registerMethods(new SuperPickaxeCommands(worldEdit)).parent().group("tool")
|
||||
.describeAs("Bind functions to held items")
|
||||
.registerMethods(new ToolCommands(worldEdit)).parent().graph().getDispatcher();
|
||||
.registerMethods(new ToolCommands(worldEdit))
|
||||
.registerMethods(new BrushCommands(worldEdit))
|
||||
.parent().graph().getDispatcher();
|
||||
}
|
||||
|
||||
public static CommandManager getInstance() {
|
||||
@ -251,7 +253,7 @@ public final class CommandManager {
|
||||
return split;
|
||||
}
|
||||
|
||||
public void handleCommandOnCurrentThread(final CommandEvent event, boolean checkLimit) {
|
||||
public void handleCommandOnCurrentThread(final CommandEvent event) {
|
||||
Actor actor = platformManager.createProxyActor(event.getActor());
|
||||
final String args = event.getArguments();
|
||||
final String[] split = commandDetection(args.split(" "));
|
||||
@ -294,93 +296,95 @@ public final class CommandManager {
|
||||
}
|
||||
locals.put(Actor.class, actor);
|
||||
final Actor finalActor = actor;
|
||||
if (!fp.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
locals.put("arguments", args);
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
// This is a bit of a hack, since the call method can only throw CommandExceptions
|
||||
// everything needs to be wrapped at least once. Which means to handle all WorldEdit
|
||||
// exceptions without writing a hook into every dispatcher, we need to unwrap these
|
||||
// exceptions and rethrow their converted form, if their is one.
|
||||
try {
|
||||
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
|
||||
} catch (Throwable t) {
|
||||
// Use the exception converter to convert the exception if any of its causes
|
||||
// can be converted, otherwise throw the original exception
|
||||
Throwable next = t;
|
||||
do {
|
||||
exceptionConverter.convert(next);
|
||||
next = next.getCause();
|
||||
} while (next != null);
|
||||
|
||||
throw t;
|
||||
}
|
||||
} catch (CommandPermissionsException e) {
|
||||
BBC.NO_PERM.send(finalActor, StringMan.join(failedPermissions, " "));
|
||||
} catch (InvalidUsageException e) {
|
||||
if (e.isFullHelpSuggested()) {
|
||||
finalActor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)));
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(message);
|
||||
}
|
||||
} else {
|
||||
String message = e.getMessage();
|
||||
finalActor.print(BBC.getPrefix() + (message != null ? message : "The command was not used properly (no more help available)."));
|
||||
BBC.COMMAND_SYNTAX.send(finalActor, e.getSimpleUsageString("/"));
|
||||
}
|
||||
} catch (WrappedCommandException e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(finalActor, faweException.getMessage());
|
||||
} else {
|
||||
Throwable t = e.getCause();
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
finalActor.printError("There was an error handling a FAWE command: [See console]");
|
||||
finalActor.printRaw(t.getClass().getName() + ": " + t.getMessage());
|
||||
log.log(Level.SEVERE, "An unexpected error occurred while handling a FAWE command", t);
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(e.getMessage());
|
||||
} else {
|
||||
finalActor.printError("An unknown error has occurred! Please see console.");
|
||||
log.log(Level.SEVERE, "An unknown error occurred", e);
|
||||
}
|
||||
} finally {
|
||||
final EditSession editSession = locals.get(EditSession.class);
|
||||
boolean hasSession = false;
|
||||
if (editSession != null) {
|
||||
editSession.flushQueue();
|
||||
worldEdit.flushBlockBag(finalActor, editSession);
|
||||
session.remember(editSession);
|
||||
final long time = System.currentTimeMillis() - start;
|
||||
if (time > 250 && hasSession) {
|
||||
BBC.ACTION_COMPLETE.send(finalActor, (time / 1000d));
|
||||
}
|
||||
}
|
||||
locals.put("arguments", args);
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
// This is a bit of a hack, since the call method can only throw CommandExceptions
|
||||
// everything needs to be wrapped at least once. Which means to handle all WorldEdit
|
||||
// exceptions without writing a hook into every dispatcher, we need to unwrap these
|
||||
// exceptions and rethrow their converted form, if their is one.
|
||||
try {
|
||||
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
|
||||
} catch (Throwable t) {
|
||||
// Use the exception converter to convert the exception if any of its causes
|
||||
// can be converted, otherwise throw the original exception
|
||||
Throwable next = t;
|
||||
do {
|
||||
exceptionConverter.convert(next);
|
||||
next = next.getCause();
|
||||
} while (next != null);
|
||||
|
||||
throw t;
|
||||
}
|
||||
} catch (CommandPermissionsException e) {
|
||||
BBC.NO_PERM.send(finalActor, StringMan.join(failedPermissions, " "));
|
||||
} catch (InvalidUsageException e) {
|
||||
if (e.isFullHelpSuggested()) {
|
||||
finalActor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)));
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(message);
|
||||
}
|
||||
} else {
|
||||
String message = e.getMessage();
|
||||
finalActor.print(BBC.getPrefix() + (message != null ? message : "The command was not used properly (no more help available)."));
|
||||
BBC.COMMAND_SYNTAX.send(finalActor, e.getSimpleUsageString("/"));
|
||||
}
|
||||
} catch (WrappedCommandException e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(finalActor, faweException.getMessage());
|
||||
} else {
|
||||
Throwable t = e.getCause();
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
finalActor.printError("There was an error handling a FAWE command: [See console]");
|
||||
finalActor.printRaw(t.getClass().getName() + ": " + t.getMessage());
|
||||
log.log(Level.SEVERE, "An unexpected error occurred while handling a FAWE command", t);
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(e.getMessage());
|
||||
} else {
|
||||
finalActor.printError("An unknown error has occurred! Please see console.");
|
||||
log.log(Level.SEVERE, "An unknown error occurred", e);
|
||||
}
|
||||
} finally {
|
||||
final EditSession editSession = locals.get(EditSession.class);
|
||||
boolean hasSession = false;
|
||||
if (editSession != null) {
|
||||
editSession.flushQueue();
|
||||
worldEdit.flushBlockBag(finalActor, editSession);
|
||||
session.remember(editSession);
|
||||
final long time = System.currentTimeMillis() - start;
|
||||
if (time > 250 && hasSession) {
|
||||
BBC.ACTION_COMPLETE.send(finalActor, (time / 1000d));
|
||||
}
|
||||
}
|
||||
}, checkLimit, false)) {
|
||||
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleCommand(final CommandEvent event) {
|
||||
Request.reset();
|
||||
final FawePlayer<Object> fp = FawePlayer.wrap(event.getActor());
|
||||
TaskManager.IMP.taskNow(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleCommandOnCurrentThread(event, true);
|
||||
if (!fp.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleCommandOnCurrentThread(event);
|
||||
}
|
||||
}, true, false)) {
|
||||
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}, Fawe.isMainThread());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@ -388,7 +392,6 @@ public final class CommandManager {
|
||||
try {
|
||||
CommandLocals locals = new CommandLocals();
|
||||
locals.put(Actor.class, event.getActor());
|
||||
locals.put("arguments", event.getArguments());
|
||||
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
|
||||
} catch (CommandException e) {
|
||||
event.getActor().printError(e.getMessage());
|
||||
|
@ -63,6 +63,7 @@ public class BundledBlockData {
|
||||
private static final BundledBlockData INSTANCE = new BundledBlockData();
|
||||
|
||||
private final Map<String, BlockEntry> idMap = new HashMap<String, BlockEntry>();
|
||||
private final Map<String, BaseBlock> stateMap = new HashMap<String, BaseBlock>();
|
||||
private final Map<String, BlockEntry> localIdMap = new HashMap<String, BlockEntry>();
|
||||
|
||||
private final BlockEntry[] legacyMap = new BlockEntry[4096];
|
||||
@ -140,13 +141,23 @@ public class BundledBlockData {
|
||||
if (!overwrite && (idMap.containsKey(entry.id) || legacyMap[entry.legacyId] != null)) {
|
||||
return false;
|
||||
}
|
||||
String id = entry.id.contains(":") ? entry.id.split(":")[1] : entry.id;
|
||||
idMap.put(entry.id, entry);
|
||||
localIdMap.put(id.toLowerCase().replace(" ", "_"), entry);
|
||||
String id = (entry.id.contains(":") ? entry.id.split(":")[1] : entry.id).toLowerCase().replace(" ", "_");
|
||||
if (!idMap.containsKey(id)) {
|
||||
idMap.put(id, entry);
|
||||
}
|
||||
legacyMap[entry.legacyId] = entry;
|
||||
if (entry.states == null) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<String, FaweState> stateEntry : entry.states.entrySet()) {
|
||||
for (Map.Entry<String, FaweStateValue> valueEntry : stateEntry.getValue().valueMap().entrySet()) {
|
||||
String key = valueEntry.getKey();
|
||||
if (!stateMap.containsKey(key)) {
|
||||
stateMap.put(key, new BaseBlock(entry.legacyId, valueEntry.getValue().data));
|
||||
}
|
||||
}
|
||||
}
|
||||
FaweState half = entry.states.get("half");
|
||||
if (half != null && half.values != null) {
|
||||
FaweStateValue top = half.values.get("top");
|
||||
@ -230,6 +241,10 @@ public class BundledBlockData {
|
||||
return true;
|
||||
}
|
||||
|
||||
public BaseBlock findByState(String state) {
|
||||
return stateMap.get(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry for the given block ID.
|
||||
*
|
||||
@ -238,11 +253,7 @@ public class BundledBlockData {
|
||||
*/
|
||||
@Nullable
|
||||
public BlockEntry findById(String id) {
|
||||
BlockEntry result = idMap.get(id);
|
||||
if (result == null) {
|
||||
result = localIdMap.get(id);
|
||||
}
|
||||
return result;
|
||||
return idMap.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -16,6 +19,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
@ -146,30 +150,53 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarIntToBuffer(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarIntToBuffer(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarIntToBuffer(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,9 @@ import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.forge.MutableGenLayer;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -17,6 +20,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
@ -160,32 +164,54 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
return ExtendedBlockStorages[cy];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarInt(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarInt(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarInt(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarInt(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.IntegerPair;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -18,6 +21,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
@ -322,30 +326,53 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = new UnpooledByteBufAllocator(true).buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarIntToBuffer(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerManager playerManager = ((WorldServer) getWorld()).getPlayerManager();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((ForgePlayer) player).parent.playerNetServerHandler.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
||||
ByteBuf byteBuf = new UnpooledByteBufAllocator(true).buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarIntToBuffer(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarIntToBuffer(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).playerNetServerHandler.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -16,6 +19,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
@ -203,30 +207,53 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarIntToBuffer(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerManager playerManager = ((WorldServer) getWorld()).getPlayerManager();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((ForgePlayer) player).parent.playerNetServerHandler.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarIntToBuffer(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarIntToBuffer(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).playerNetServerHandler.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -16,6 +19,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
@ -244,30 +248,53 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarIntToBuffer(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarIntToBuffer(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarIntToBuffer(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ public class NukkitRegistryDumper {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public NukkitRegistryDumper(File file) {
|
||||
this.file = file;
|
||||
GsonBuilder builder = new GsonBuilder().setPrettyPrinting();
|
||||
|
@ -17,6 +17,7 @@ import com.boydti.fawe.nukkit.optimization.FaweNukkit;
|
||||
import com.boydti.fawe.nukkit.optimization.FaweNukkitPlayer;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
@ -128,39 +129,40 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
ArrayList<Block> blocks = new ArrayList<Block>();
|
||||
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> ids = entry.getValue();
|
||||
for (Map.Entry<Short, Character> blockEntry : ids.entrySet()) {
|
||||
char combined = blockEntry.getValue();
|
||||
int id = FaweCache.getId(combined);
|
||||
int data = FaweCache.getData(combined);
|
||||
Block block = Block.get(id, data);
|
||||
short blockHash = blockEntry.getKey();
|
||||
block.x = (blockHash >> 12 & 0xF) + (cx << 4);
|
||||
block.y = (blockHash & 0xFF);
|
||||
block.z = (blockHash >> 8 & 0xF) + (cz << 4);
|
||||
blocks.add(block);
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
boolean watching = true; // TODO check if player can see chunk
|
||||
if (!watching) return;
|
||||
final ArrayList<Block> blocks = new ArrayList<>();
|
||||
final int bx = chunk.getX() << 4;
|
||||
final int bz = chunk.getZ() << 4;
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
Block block = Block.get(FaweCache.getId(combined), FaweCache.getData(combined));
|
||||
block.x = bz + localX;
|
||||
block.y = y;
|
||||
block.z = bx + localZ;
|
||||
blocks.add(block);
|
||||
}
|
||||
});
|
||||
Map<Level, List<Player>> playerMap = new HashMap<>();
|
||||
for (FawePlayer player : players) {
|
||||
Player nukkitPlayer = ((FaweNukkitPlayer) player).parent;
|
||||
List<Player> list = playerMap.get(nukkitPlayer.getLevel());
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
playerMap.put(nukkitPlayer.getLevel(), list);
|
||||
}
|
||||
list.add(nukkitPlayer);
|
||||
}
|
||||
}
|
||||
Map<Level, List<Player>> playerMap = new HashMap<>();
|
||||
for (FawePlayer player : players) {
|
||||
Player nukkitPlayer = ((FaweNukkitPlayer) player).parent;
|
||||
List<Player> list = playerMap.get(nukkitPlayer.getLevel());
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
playerMap.put(nukkitPlayer.getLevel(), list);
|
||||
Block[] blocksArray = blocks.toArray(new Block[blocks.size()]);
|
||||
for (Map.Entry<Level, List<Player>> levelListEntry : playerMap.entrySet()) {
|
||||
List<Player> playerList = levelListEntry.getValue();
|
||||
levelListEntry.getKey().sendBlocks(playerList.toArray(new Player[playerList.size()]), blocksArray, UpdateBlockPacket.FLAG_ALL_PRIORITY);
|
||||
}
|
||||
list.add(nukkitPlayer);
|
||||
}
|
||||
Block[] blocksArray = blocks.toArray(new Block[blocks.size()]);
|
||||
for (Map.Entry<Level, List<Player>> levelListEntry : playerMap.entrySet()) {
|
||||
List<Player> playerList = levelListEntry.getValue();
|
||||
levelListEntry.getKey().sendBlocks(playerList.toArray(new Player[playerList.size()]), blocksArray, UpdateBlockPacket.FLAG_ALL_PRIORITY);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ import org.spongepowered.api.plugin.Plugin;
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.profile.GameProfileManager;
|
||||
|
||||
@Plugin(id = "fastasyncworldedit", name = "FastAsyncWorldEdit", description = "fawe", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "development", authors = "Empire92")
|
||||
@Plugin(id = "fastasyncworldedit", name = " FastAsyncWorldEdit", description = "fawe", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "development", authors = "Empire92")
|
||||
public class SpongeMain {
|
||||
@Inject
|
||||
public PluginContainer plugin;
|
||||
|
@ -5,6 +5,9 @@ import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.number.LongAdder;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.sponge.SpongePlayer;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -19,6 +22,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
@ -132,30 +136,53 @@ public class SpongeQueue_1_11 extends NMSMappedFaweQueue<World, net.minecraft.wo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
||||
try {
|
||||
long chunkHash = chunkEntry.getKey();
|
||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
int cx = MathMan.unpairIntX(chunkHash);
|
||||
int cz = MathMan.unpairIntY(chunkHash);
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(cx);
|
||||
buffer.writeInt(cz);
|
||||
buffer.writeVarIntToBuffer(blocks.size());
|
||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
||||
buffer.writeShort(blockEntry.getKey());
|
||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) ((SpongePlayer) players[i]).parent;
|
||||
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||
players[i] = null;
|
||||
} else {
|
||||
watching = true;
|
||||
}
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
((EntityPlayerMP) ((SpongePlayer) player).parent).connection.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketBuffer buffer = new PacketBuffer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeVarIntToBuffer(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
buffer.writeShort(index);
|
||||
buffer.writeVarIntToBuffer(combined);
|
||||
}
|
||||
});
|
||||
packet.readPacketData(buffer);
|
||||
for (FawePlayer player : players) {
|
||||
if (player != null) ((EntityPlayerMP) ((SpongePlayer) player).parent).connection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user