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;
|
package com.boydti.fawe.bukkit;
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.brush.MovableBrush;
|
import com.boydti.fawe.object.brush.MovableTool;
|
||||||
import com.boydti.fawe.object.brush.scroll.ScrollableBrush;
|
import com.boydti.fawe.object.brush.ResettableTool;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
import com.boydti.fawe.object.brush.scroll.ScrollTool;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
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.Tool;
|
||||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
@ -40,16 +36,9 @@ public class BrushListener implements Listener {
|
|||||||
LocalSession session = fp.getSession();
|
LocalSession session = fp.getSession();
|
||||||
Tool tool = session.getTool(player);
|
Tool tool = session.getTool(player);
|
||||||
if (tool != null) {
|
if (tool != null) {
|
||||||
ScrollableBrush scrollable;
|
if (tool instanceof ScrollTool) {
|
||||||
if (tool instanceof ScrollableBrush) {
|
|
||||||
scrollable = (ScrollableBrush) tool;
|
|
||||||
} else if (tool instanceof BrushTool) {
|
|
||||||
Brush brush = ((BrushTool) tool).getBrush();
|
|
||||||
scrollable = brush instanceof ScrollableBrush ? (ScrollableBrush) brush : null;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (scrollable != null) {
|
|
||||||
final int slot = event.getNewSlot();
|
final int slot = event.getNewSlot();
|
||||||
final int oldSlot = event.getPreviousSlot();
|
final int oldSlot = event.getPreviousSlot();
|
||||||
final int ri;
|
final int ri;
|
||||||
@ -58,21 +47,14 @@ public class BrushListener implements Listener {
|
|||||||
} else {
|
} else {
|
||||||
ri = -1;
|
ri = -1;
|
||||||
}
|
}
|
||||||
if (scrollable.increment(ri)) {
|
ScrollTool scrollable = (ScrollTool) tool;
|
||||||
|
if (scrollable.increment(player, ri)) {
|
||||||
final PlayerInventory inv = bukkitPlayer.getInventory();
|
final PlayerInventory inv = bukkitPlayer.getInventory();
|
||||||
final ItemStack item = inv.getItem(slot);
|
final ItemStack item = inv.getItem(slot);
|
||||||
final ItemStack newItem = inv.getItem(oldSlot);
|
final ItemStack newItem = inv.getItem(oldSlot);
|
||||||
inv.setItem(slot, newItem);
|
inv.setItem(slot, newItem);
|
||||||
inv.setItem(oldSlot, item);
|
inv.setItem(oldSlot, item);
|
||||||
bukkitPlayer.updateInventory();
|
bukkitPlayer.updateInventory();
|
||||||
if (scrollable instanceof VisualBrush) {
|
|
||||||
try {
|
|
||||||
((VisualBrush) scrollable).queueVisualization(fp);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,21 +70,8 @@ public class BrushListener implements Listener {
|
|||||||
LocalSession session = fp.getSession();
|
LocalSession session = fp.getSession();
|
||||||
Tool tool = session.getTool(player);
|
Tool tool = session.getTool(player);
|
||||||
if (tool != null) {
|
if (tool != null) {
|
||||||
if (tool instanceof MovableBrush) {
|
if (tool instanceof MovableTool) {
|
||||||
((MovableBrush) tool).move(player);
|
((MovableTool) 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,11 +79,9 @@ public class BrushListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPlayerInteract(final PlayerInteractEvent event) {
|
public void onPlayerInteract(final PlayerInteractEvent event) {
|
||||||
switch (event.getAction()) {
|
|
||||||
case LEFT_CLICK_AIR:
|
|
||||||
case LEFT_CLICK_BLOCK:
|
|
||||||
Player bukkitPlayer = event.getPlayer();
|
Player bukkitPlayer = event.getPlayer();
|
||||||
if (!bukkitPlayer.isSneaking()) {
|
if (bukkitPlayer.isSneaking()) {
|
||||||
|
if (event.getAction() == Action.PHYSICAL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FawePlayer<Object> fp = FawePlayer.wrap(bukkitPlayer);
|
FawePlayer<Object> fp = FawePlayer.wrap(bukkitPlayer);
|
||||||
@ -122,12 +89,9 @@ public class BrushListener implements Listener {
|
|||||||
LocalSession session = fp.getSession();
|
LocalSession session = fp.getSession();
|
||||||
int item = player.getItemInHand();
|
int item = player.getItemInHand();
|
||||||
Tool tool = session.getTool(item);
|
Tool tool = session.getTool(item);
|
||||||
if (tool != null) {
|
if (tool instanceof ResettableTool) {
|
||||||
try {
|
if (((ResettableTool) tool).reset()) {
|
||||||
session.setTool(item, null, player);
|
event.setCancelled(true);
|
||||||
BBC.TOOL_NONE.send(player);
|
|
||||||
} catch (InvalidToolBindException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
|||||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
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.ClipboardPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||||
@ -450,6 +451,7 @@ public class Fawe {
|
|||||||
ClipboardPattern.inject(); // Optimizations
|
ClipboardPattern.inject(); // Optimizations
|
||||||
HashTagPatternParser.inject(); // Add new patterns
|
HashTagPatternParser.inject(); // Add new patterns
|
||||||
DefaultBlockParser.inject(); // Fix block lookups
|
DefaultBlockParser.inject(); // Fix block lookups
|
||||||
|
BlockPattern.inject(); // Optimization
|
||||||
// Mask
|
// Mask
|
||||||
Mask.inject(); // Extend deprecated mask
|
Mask.inject(); // Extend deprecated mask
|
||||||
BlockMask.inject(); // Optimizations
|
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"),
|
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"),
|
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"),
|
ACTION_COMPLETE("Action completed in %s0 seconds", "Info"),
|
||||||
GENERATING_LINK("Uploading %s, please wait...", "Web"),
|
GENERATING_LINK("Uploading %s, please wait...", "Web"),
|
||||||
GENERATING_LINK_FAILED("&cFailed to generate download link!", "Web"),
|
GENERATING_LINK_FAILED("&cFailed to generate download link!", "Web"),
|
||||||
@ -104,6 +105,9 @@ public enum BBC {
|
|||||||
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
||||||
|
|
||||||
BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"),
|
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_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
|
||||||
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
||||||
BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "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_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_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
|
||||||
BRUSH_LINE("Line 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("Spline 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_PRIMARY("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY("Created spline", "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_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_CIRCLE("Circle brush equipped (%s0). Right click to create a circle.", "WorldEdit.Brush"),
|
||||||
BRUSH_RECURSIVE("Recursive brush equipped (%s0).", "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_SIZE("Brush size set", "WorldEdit.Brush"),
|
||||||
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
||||||
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
||||||
|
@ -31,7 +31,7 @@ public class PseudoRandom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double nextDouble() {
|
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) {
|
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;
|
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.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
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.entity.Player;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
|
||||||
public class CircleBrush extends VisualBrush {
|
public class CircleBrush implements Brush {
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
private final BrushTool tool;
|
||||||
|
|
||||||
public CircleBrush(BrushTool tool, Player player) {
|
public CircleBrush(BrushTool tool, Player player) {
|
||||||
super(tool);
|
this.tool = tool;
|
||||||
this.player = LocationMaskedPlayerWrapper.unwrap(player);
|
this.player = LocationMaskedPlayerWrapper.unwrap(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
public void build(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());
|
Vector normal = position.subtract(player.getPosition());
|
||||||
editSession.makeCircle(position, pattern, size, size, size, false, normal);
|
editSession.makeCircle(position, pattern, size, size, size, false, normal);
|
||||||
break;
|
|
||||||
case SECONDARY:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector any90Rotate(Vector normal) {
|
private Vector any90Rotate(Vector normal) {
|
||||||
normal = normal.normalize();
|
normal = normal.normalize();
|
||||||
if (normal.getX() == 1 || normal.getY() == 1 || normal.getZ() == 1) {
|
if (normal.getX() == 1 || normal.getY() == 1 || normal.getZ() == 1) {
|
||||||
return new Vector(normal.getZ(), normal.getX(), normal.getY());
|
return new Vector(normal.getZ(), normal.getX(), normal.getY());
|
||||||
|
@ -51,7 +51,7 @@ public class CommandBrush implements Brush {
|
|||||||
String[] cmds = replaced.split(";");
|
String[] cmds = replaced.split(";");
|
||||||
for (String cmd : cmds) {
|
for (String cmd : cmds) {
|
||||||
CommandEvent event = new CommandEvent(wePlayer, cmd);
|
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.config.BBC;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.clipboard.ResizableClipboardBuilder;
|
||||||
import com.boydti.fawe.object.function.NullRegionFunction;
|
import com.boydti.fawe.object.function.NullRegionFunction;
|
||||||
import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
|
import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.EmptyClipboardException;
|
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
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.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.Masks;
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
@ -22,20 +23,31 @@ import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
|
||||||
public class CopyPastaBrush implements DoubleActionBrush {
|
public class CopyPastaBrush implements Brush, ResettableTool {
|
||||||
|
|
||||||
private final BrushTool tool;
|
private final BrushTool tool;
|
||||||
|
private final LocalSession session;
|
||||||
|
|
||||||
public CopyPastaBrush(BrushTool tool) {
|
public CopyPastaBrush(BrushTool tool, LocalSession session) {
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
|
session.setClipboard(null);
|
||||||
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
FawePlayer fp = editSession.getPlayer();
|
||||||
LocalSession session = fp.getSession();
|
ClipboardHolder clipboard = session.getExistingClipboard();
|
||||||
switch (action) {
|
if (clipboard == null) {
|
||||||
case SECONDARY: {
|
if (editSession.getExtent() instanceof VisualExtent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Mask mask = tool.getMask();
|
Mask mask = tool.getMask();
|
||||||
if (mask == null) {
|
if (mask == null) {
|
||||||
mask = Masks.alwaysTrue();
|
mask = Masks.alwaysTrue();
|
||||||
@ -62,30 +74,23 @@ public class CopyPastaBrush implements DoubleActionBrush {
|
|||||||
visitor.visit(position);
|
visitor.visit(position);
|
||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
// Build the clipboard
|
// Build the clipboard
|
||||||
Clipboard clipboard = builder.build();
|
Clipboard newClipboard = builder.build();
|
||||||
clipboard.setOrigin(position);
|
newClipboard.setOrigin(position);
|
||||||
ClipboardHolder holder = new ClipboardHolder(clipboard, editSession.getWorld().getWorldData());
|
ClipboardHolder holder = new ClipboardHolder(newClipboard, editSession.getWorld().getWorldData());
|
||||||
session.setClipboard(holder);
|
session.setClipboard(holder);
|
||||||
int blocks = builder.size();
|
int blocks = builder.size();
|
||||||
BBC.COMMAND_COPY.send(fp, blocks);
|
BBC.COMMAND_COPY.send(fp, blocks);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
case PRIMARY: {
|
Clipboard faweClip = clipboard.getClipboard();
|
||||||
try {
|
Region region = faweClip.getRegion();
|
||||||
ClipboardHolder holder = session.getClipboard();
|
Vector centerOffset = region.getCenter().subtract(faweClip.getOrigin());
|
||||||
Clipboard clipboard = holder.getClipboard();
|
Operation operation = clipboard
|
||||||
Region region = clipboard.getRegion();
|
|
||||||
Vector centerOffset = region.getCenter().subtract(clipboard.getOrigin());
|
|
||||||
Operation operation = holder
|
|
||||||
.createPaste(editSession, editSession.getWorld().getWorldData())
|
.createPaste(editSession, editSession.getWorld().getWorldData())
|
||||||
.to(position.add(0, 1, 0))
|
.to(position.add(0, 1, 0))
|
||||||
.ignoreAirBlocks(true)
|
.ignoreAirBlocks(true)
|
||||||
.build();
|
.build();
|
||||||
Operations.completeLegacy(operation);
|
Operations.completeLegacy(operation);
|
||||||
} catch (EmptyClipboardException e) {
|
|
||||||
BBC.BRUSH_PASTE_NONE.send(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
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 com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class ErodeBrush implements DoubleActionBrush {
|
public class ErodeBrush implements Brush {
|
||||||
|
|
||||||
private PseudoRandom rand = new PseudoRandom();
|
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)};
|
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
|
@Override
|
||||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||||
switch (action) {
|
this.erosion(editSession, 2, 1, 5, 1, position, size);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 brushSize = (int) size + 1;
|
||||||
int brushSizeSquared = (int) (size * size);
|
int brushSizeSquared = (int) (size * size);
|
||||||
int dimension = brushSize * 2 + 1;
|
int dimension = brushSize * 2 + 1;
|
||||||
@ -86,7 +69,7 @@ public class ErodeBrush implements DoubleActionBrush {
|
|||||||
}, true);
|
}, 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;
|
int[] frequency = null;
|
||||||
for (int x = -brushSize; x <= brushSize; x++) {
|
for (int x = -brushSize; x <= brushSize; x++) {
|
||||||
int x2 = x * 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;
|
int[] frequency = null;
|
||||||
for (int x = -brushSize; x <= brushSize; x++) {
|
for (int x = -brushSize; x <= brushSize; x++) {
|
||||||
int x2 = x * x;
|
int x2 = x * x;
|
||||||
|
@ -18,13 +18,13 @@ public class FlattenBrush extends HeightBrush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
int size = (int) sizeDouble;
|
||||||
Mask mask = tool.getMask();
|
Mask mask = tool.getMask();
|
||||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||||
mask = null;
|
mask = null;
|
||||||
}
|
}
|
||||||
heightMap.setSize(size);
|
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.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
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.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.Masks;
|
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.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class HeightBrush implements DoubleActionBrush {
|
public class HeightBrush implements Brush {
|
||||||
|
|
||||||
public final ScalableHeightMap heightMap;
|
public final ScalableHeightMap heightMap;
|
||||||
public final int rotation;
|
public final int rotation;
|
||||||
@ -43,13 +44,13 @@ public class HeightBrush implements DoubleActionBrush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
int size = (int) sizeDouble;
|
||||||
Mask mask = tool.getMask();
|
Mask mask = tool.getMask();
|
||||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||||
mask = null;
|
mask = null;
|
||||||
}
|
}
|
||||||
heightMap.setSize(size);
|
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.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
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.Pattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
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 final boolean shell, select, flat;
|
||||||
private Vector pos1;
|
private Vector pos1;
|
||||||
@ -19,20 +19,21 @@ public class LineBrush implements DoubleActionBrush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
public void build(EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||||
switch (action) {
|
|
||||||
case PRIMARY:
|
|
||||||
if (pos1 == null) {
|
if (pos1 == null) {
|
||||||
pos1 = position;
|
pos1 = position;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat);
|
editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat);
|
||||||
if (!select) {
|
if (!select) {
|
||||||
return;
|
pos1 = null;
|
||||||
}
|
|
||||||
case SECONDARY:
|
|
||||||
pos1 = position;
|
|
||||||
return;
|
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;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
|
||||||
public interface MovableBrush {
|
public interface MovableTool {
|
||||||
public boolean move(Player player);
|
public boolean move(Player player);
|
||||||
}
|
}
|
@ -3,19 +3,11 @@ package com.boydti.fawe.object.brush;
|
|||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
public class RaiseBrush implements DoubleActionBrush {
|
public class RaiseBrush extends ErodeBrush {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(BrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||||
switch (action) {
|
this.erosion(editSession, 6, 0, 1, 1, position, size);
|
||||||
case PRIMARY:
|
|
||||||
break;
|
|
||||||
case SECONDARY:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
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.entity.Player;
|
||||||
import com.sk89q.worldedit.function.RegionFunction;
|
import com.sk89q.worldedit.function.RegionFunction;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
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 com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SplineBrush implements DoubleActionBrush {
|
public class SplineBrush implements Brush {
|
||||||
|
|
||||||
public static int MAX_POINTS = 15;
|
public static int MAX_POINTS = 15;
|
||||||
private ArrayList<ArrayList<Vector>> positionSets;
|
private ArrayList<ArrayList<Vector>> positionSets;
|
||||||
@ -33,6 +36,7 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
private final BrushTool tool;
|
private final BrushTool tool;
|
||||||
private final LocalSession session;
|
private final LocalSession session;
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
private Vector position;
|
||||||
|
|
||||||
public SplineBrush(Player player, LocalSession session, BrushTool tool) {
|
public SplineBrush(Player player, LocalSession session, BrushTool tool) {
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
@ -42,7 +46,7 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
Mask mask = tool.getMask();
|
||||||
if (mask == null) {
|
if (mask == null) {
|
||||||
mask = new IdMask(editSession);
|
mask = new IdMask(editSession);
|
||||||
@ -54,12 +58,14 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int originalSize = numSplines;
|
int originalSize = numSplines;
|
||||||
switch (action) {
|
boolean newPos = this.position == null || !position.equals(this.position);
|
||||||
case PRIMARY: {
|
this.position = position;
|
||||||
|
if (newPos) {
|
||||||
if (positionSets.size() >= MAX_POINTS) {
|
if (positionSets.size() >= MAX_POINTS) {
|
||||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||||
}
|
}
|
||||||
final ArrayList<Vector> points = new ArrayList<>();
|
final ArrayList<Vector> points = new ArrayList<>();
|
||||||
|
if (tool.getSize() > 0) {
|
||||||
DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, new RegionFunction() {
|
DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, new RegionFunction() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Vector p) throws WorldEditException {
|
public boolean apply(Vector p) throws WorldEditException {
|
||||||
@ -67,10 +73,11 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}, (int) size, 1);
|
}, (int) size, 1);
|
||||||
Collection<Vector> directions = visitor.getDirections();
|
List<Vector> directions = visitor.getDirections();
|
||||||
for (int x = -1; x <= 1; x++) {
|
for (int x = -1; x <= 1; x++) {
|
||||||
for (int y = -1; y <= 1; y++) {
|
for (int y = -1; y <= 1; y++) {
|
||||||
for (int z = -1; z <= 1; z++) {
|
for (int z = -1; z <= 1; z++) {
|
||||||
|
if (x != 0 || y != 0 && z != 0) {
|
||||||
Vector pos = new Vector(x, y, z);
|
Vector pos = new Vector(x, y, z);
|
||||||
if (!directions.contains(pos)) {
|
if (!directions.contains(pos)) {
|
||||||
directions.add(pos);
|
directions.add(pos);
|
||||||
@ -78,18 +85,27 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
visitor.visit(position);
|
||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
if (points.size() > numSplines) {
|
if (points.size() > numSplines) {
|
||||||
numSplines = points.size();
|
numSplines = points.size();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
points.add(position);
|
||||||
|
}
|
||||||
this.positionSets.add(points);
|
this.positionSets.add(points);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY.s());
|
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY.s());
|
||||||
if (!visualization) {
|
if (!visualization) {
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case SECONDARY: {
|
|
||||||
if (positionSets.size() < 2) {
|
if (positionSets.size() < 2) {
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY_ERROR.s());
|
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY_ERROR.s());
|
||||||
return;
|
return;
|
||||||
@ -137,9 +153,6 @@ public class SplineBrush implements DoubleActionBrush {
|
|||||||
numSplines = originalSize;
|
numSplines = originalSize;
|
||||||
positionSets.remove(positionSets.size() - 1);
|
positionSets.remove(positionSets.size() - 1);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector getCentroid(Collection<Vector> points) {
|
private Vector getCentroid(Collection<Vector> points) {
|
||||||
|
@ -4,5 +4,5 @@ public enum TargetMode {
|
|||||||
TARGET_BLOCK_RANGE,
|
TARGET_BLOCK_RANGE,
|
||||||
FOWARD_POINT_PITCH,
|
FOWARD_POINT_PITCH,
|
||||||
TARGET_POINT_HEIGHT,
|
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;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
|
||||||
public abstract class ScrollAction implements ScrollableBrush {
|
public abstract class ScrollAction implements ScrollTool {
|
||||||
public final BrushTool tool;
|
public final BrushTool tool;
|
||||||
|
|
||||||
public ScrollAction(BrushTool tool) {
|
public ScrollAction(BrushTool tool) {
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
package com.boydti.fawe.object.brush.scroll;
|
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.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
public class ScrollMask extends ScrollAction {
|
public class ScrollMask extends ScrollAction {
|
||||||
@ -15,7 +16,7 @@ public class ScrollMask extends ScrollAction {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean increment(int amount) {
|
public boolean increment(Player player, int amount) {
|
||||||
if (masks.length > 1) {
|
if (masks.length > 1) {
|
||||||
tool.setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]);
|
tool.setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.brush.scroll;
|
|||||||
|
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
public class ScrollPattern extends ScrollAction {
|
public class ScrollPattern extends ScrollAction {
|
||||||
@ -15,7 +16,7 @@ public class ScrollPattern extends ScrollAction {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean increment(int amount) {
|
public boolean increment(Player player, int amount) {
|
||||||
if (patterns.length > 1) {
|
if (patterns.length > 1) {
|
||||||
tool.setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]);
|
tool.setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]);
|
||||||
return true;
|
return true;
|
||||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.brush.scroll;
|
|||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
|
||||||
public class ScrollRange extends ScrollAction {
|
public class ScrollRange extends ScrollAction {
|
||||||
public ScrollRange(BrushTool tool) {
|
public ScrollRange(BrushTool tool) {
|
||||||
@ -10,7 +11,7 @@ public class ScrollRange extends ScrollAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean increment(int amount) {
|
public boolean increment(Player player, int amount) {
|
||||||
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
|
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
|
||||||
int newSize = MathMan.wrap(tool.getRange() + amount, (int) (tool.getSize() + 1), max);
|
int newSize = MathMan.wrap(tool.getRange() + amount, (int) (tool.getSize() + 1), max);
|
||||||
tool.setRange(newSize);
|
tool.setRange(newSize);
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.brush.scroll;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
|
||||||
public class ScrollSize extends ScrollAction {
|
public class ScrollSize extends ScrollAction {
|
||||||
public ScrollSize(BrushTool tool) {
|
public ScrollSize(BrushTool tool) {
|
||||||
@ -9,7 +10,7 @@ public class ScrollSize extends ScrollAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean increment(int amount) {
|
public boolean increment(Player player, int amount) {
|
||||||
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
||||||
double newSize = Math.max(0, Math.min(max, tool.getSize() + amount));
|
double newSize = Math.max(0, Math.min(max, tool.getSize() + amount));
|
||||||
tool.setSize(newSize);
|
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,21 +35,17 @@ public class VisualQueue {
|
|||||||
Tool tool = session.getTool(player.getItemInHand());
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
Brush brush;
|
Brush brush;
|
||||||
if (tool instanceof BrushTool) {
|
if (tool instanceof BrushTool) {
|
||||||
brush = ((BrushTool) tool).getBrush();
|
BrushTool brushTool = (BrushTool) tool;
|
||||||
} else if (tool instanceof VisualBrush) {
|
if (brushTool.getVisualMode() != VisualMode.NONE) {
|
||||||
brush = (Brush) tool;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (brush instanceof VisualBrush) {
|
|
||||||
try {
|
try {
|
||||||
((VisualBrush) brush).visualize(BrushTool.BrushAction.PRIMARY, player);
|
brushTool.visualize(BrushTool.BrushAction.PRIMARY, player);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TaskManager.IMP.laterAsync(this, 3);
|
TaskManager.IMP.laterAsync(this, 3);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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> {
|
public class LocalBlockVectorSet implements Set<Vector> {
|
||||||
private int offsetX, offsetZ;
|
private int offsetX, offsetZ;
|
||||||
private final SparseBitSet set;
|
private final SparseBitSet set;
|
||||||
private BlockVector mVec = new BlockVector(0, 0, 0);
|
|
||||||
|
|
||||||
public LocalBlockVectorSet() {
|
public LocalBlockVectorSet() {
|
||||||
offsetX = offsetZ = Integer.MAX_VALUE;
|
offsetX = offsetZ = Integer.MAX_VALUE;
|
||||||
this.set = new SparseBitSet();
|
this.set = new SparseBitSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalBlockVectorSet(int x, int z, SparseBitSet set) {
|
||||||
|
this.offsetX = x;
|
||||||
|
this.offsetZ = z;
|
||||||
|
this.set = set;
|
||||||
|
}
|
||||||
|
|
||||||
public SparseBitSet getBitSet() {
|
public SparseBitSet getBitSet() {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
@ -50,6 +55,38 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
|||||||
return false;
|
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) {
|
public void addOffset(int x, int z) {
|
||||||
this.offsetX += x;
|
this.offsetX += x;
|
||||||
this.offsetZ += z;
|
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]");
|
throw new UnsupportedOperationException("LocalVectorSet can only contain vectors from y elem:[0,255]");
|
||||||
}
|
}
|
||||||
int index = getIndex(x, y, z);
|
int index = getIndex(x, y, z);
|
||||||
boolean value = set.get(index);
|
if (set.get(index)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
set.set(index);
|
set.set(index);
|
||||||
return !value;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -196,9 +236,10 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
|||||||
public boolean retainAll(Collection<?> c) {
|
public boolean retainAll(Collection<?> c) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
int size = size();
|
int size = size();
|
||||||
int index = 0;
|
int index = -1;
|
||||||
|
Vector mVec = MutableBlockVector.get(0, 0, 0);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
index = set.nextSetBit(index);
|
index = set.nextSetBit(index + 1);
|
||||||
int b1 = (index & 0xFF);
|
int b1 = (index & 0xFF);
|
||||||
int b2 = ((byte) (index >> 8)) & 0x7F;
|
int b2 = ((byte) (index >> 8)) & 0x7F;
|
||||||
int b3 = ((byte)(index >> 15)) & 0xFF;
|
int b3 = ((byte)(index >> 15)) & 0xFF;
|
||||||
@ -210,7 +251,6 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
|||||||
result = true;
|
result = true;
|
||||||
set.clear(index);
|
set.clear(index);
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -224,6 +264,27 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
|||||||
return result;
|
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
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
set.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 com.sk89q.worldedit.function.operation.RunContext;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
@ -50,7 +49,7 @@ public abstract class DFSVisitor implements Operation {
|
|||||||
|
|
||||||
public abstract boolean isVisitable(Vector from, Vector to);
|
public abstract boolean isVisitable(Vector from, Vector to);
|
||||||
|
|
||||||
public Collection<Vector> getDirections() {
|
public List<Vector> getDirections() {
|
||||||
return this.directions;
|
return this.directions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +523,10 @@ public class MainUtil {
|
|||||||
}
|
}
|
||||||
return newFile;
|
return newFile;
|
||||||
}
|
}
|
||||||
|
File parent = newFile.getParentFile();
|
||||||
|
if (!parent.exists()) {
|
||||||
|
parent.mkdirs();
|
||||||
|
}
|
||||||
newFile.createNewFile();
|
newFile.createNewFile();
|
||||||
try (FileOutputStream fos = new FileOutputStream(newFile)) {
|
try (FileOutputStream fos = new FileOutputStream(newFile)) {
|
||||||
int len;
|
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
|
@Override
|
||||||
public boolean setBlock(final Vector position, final BaseBlock block, final boolean ignorePhysics) throws MaxChangedBlocksException {
|
public boolean setBlock(final Vector position, final BaseBlock block, final boolean ignorePhysics) throws MaxChangedBlocksException {
|
||||||
return setBlockFast(position, block);
|
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.FaweOutputStream;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
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.DiskStorageHistory;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
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.InvalidToolBindException;
|
||||||
import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
||||||
import com.sk89q.worldedit.command.tool.Tool;
|
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.entity.Player;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
@ -777,6 +775,11 @@ public class LocalSession {
|
|||||||
return clipboard;
|
return clipboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ClipboardHolder getExistingClipboard() {
|
||||||
|
return clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the clipboard.
|
* Sets the clipboard.
|
||||||
*
|
*
|
||||||
@ -979,11 +982,19 @@ public class LocalSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BrushTool getBrushTool(int item, Player player) throws InvalidToolBindException {
|
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);
|
Tool tool = getTool(item);
|
||||||
|
|
||||||
if (tool == null || !(tool instanceof BrushTool)) {
|
if ((tool == null || !(tool instanceof BrushTool))) {
|
||||||
|
if (create) {
|
||||||
tool = new BrushTool("worldedit.brush.sphere");
|
tool = new BrushTool("worldedit.brush.sphere");
|
||||||
setTool(item, tool, player);
|
setTool(item, tool, player);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (BrushTool) tool;
|
return (BrushTool) tool;
|
||||||
@ -1011,12 +1022,8 @@ public class LocalSession {
|
|||||||
Tool previous = this.tools.put(item, tool);
|
Tool previous = this.tools.put(item, tool);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
if (previous instanceof BrushTool) {
|
if (previous instanceof BrushTool) {
|
||||||
Brush brush = ((BrushTool) previous).getBrush();
|
BrushTool brushTool = (BrushTool) previous;
|
||||||
if (brush instanceof VisualBrush) {
|
brushTool.clear(player);
|
||||||
((VisualBrush) brush).clear(player);
|
|
||||||
}
|
|
||||||
} else if (previous instanceof VisualBrush) {
|
|
||||||
((VisualBrush) tool).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.FlattenBrush;
|
||||||
import com.boydti.fawe.object.brush.HeightBrush;
|
import com.boydti.fawe.object.brush.HeightBrush;
|
||||||
import com.boydti.fawe.object.brush.LineBrush;
|
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.RecurseBrush;
|
||||||
import com.boydti.fawe.object.brush.SplineBrush;
|
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.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.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.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
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.tool.brush.SphereBrush;
|
||||||
import com.sk89q.worldedit.command.util.CreatureButcher;
|
import com.sk89q.worldedit.command.util.CreatureButcher;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
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.Clipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
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.BlockPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -74,6 +95,10 @@ import java.io.InputStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
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;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -95,6 +120,227 @@ public class BrushCommands {
|
|||||||
this.worldEdit = worldEdit;
|
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(
|
@Command(
|
||||||
aliases = { "blendball", "bb", "blend" },
|
aliases = { "blendball", "bb", "blend" },
|
||||||
usage = "[radius]",
|
usage = "[radius]",
|
||||||
@ -129,6 +375,23 @@ public class BrushCommands {
|
|||||||
player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius));
|
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(
|
@Command(
|
||||||
aliases = { "circle" },
|
aliases = { "circle" },
|
||||||
usage = "<pattern> [radius]",
|
usage = "<pattern> [radius]",
|
||||||
@ -191,7 +454,7 @@ public class BrushCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "spline", "spl" },
|
aliases = { "spline", "spl", "curve" },
|
||||||
usage = "<pattern>",
|
usage = "<pattern>",
|
||||||
desc = "Choose the spline brush",
|
desc = "Choose the spline brush",
|
||||||
help = "Chooses 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);
|
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(
|
@Command(
|
||||||
aliases = { "cylinder", "cyl", "c" },
|
aliases = { "cylinder", "cyl", "c" },
|
||||||
usage = "<block> [radius] [height]",
|
usage = "<block> [radius] [height]",
|
||||||
@ -484,7 +769,7 @@ public class BrushCommands {
|
|||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
BrushTool tool = session.getBrushTool(player.getItemInHand(), player);
|
||||||
tool.setSize(radius);
|
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));
|
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public class HistoryCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/frb", "frb", "fawerollback", "/fawerollback" },
|
aliases = { "/frb", "frb", "fawerollback", "/fawerollback", "/rollback" },
|
||||||
usage = "<user> <radius> <time>",
|
usage = "<user> <radius> <time>",
|
||||||
desc = "Undo edits within a radius",
|
desc = "Undo edits within a radius",
|
||||||
min = 1,
|
min = 1,
|
||||||
|
@ -257,7 +257,7 @@ public class RegionCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/curve" },
|
aliases = { "/curve", "/spline" },
|
||||||
usage = "<block> [thickness]",
|
usage = "<block> [thickness]",
|
||||||
desc = "Draws a spline through selected points",
|
desc = "Draws a spline through selected points",
|
||||||
help =
|
help =
|
||||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
|
|||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
@ -114,12 +115,31 @@ public class SchematicCommands {
|
|||||||
BBC.NO_PERM.send(player, "worldedit.clipboard.load");
|
BBC.NO_PERM.send(player, "worldedit.clipboard.load");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
if (filename.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||||
final File f = this.worldEdit.getSafeOpenFile(player, dir, filename, format.getExtension(), format.getExtension());
|
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()) {
|
if (!f.exists()) {
|
||||||
player.printError("Schematic " + filename + " does not exist!");
|
player.printError("Schematic " + filename + " does not exist!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
final String filePath = f.getCanonicalPath();
|
final String filePath = f.getCanonicalPath();
|
||||||
final String dirPath = dir.getCanonicalPath();
|
final String dirPath = dir.getCanonicalPath();
|
||||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
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")
|
@Command(aliases = { "save" }, usage = "[<format>] <filename>", desc = "Save a schematic into your clipboard")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@CommandPermissions({ "worldedit.clipboard.save", "worldedit.schematic.save" })
|
@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 LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
player.printError("Unknown schematic format: " + formatName);
|
player.printError("Unknown schematic format: " + formatName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (filename.contains("../") && !player.hasPermission("worldedit.schematic.save.other")) {
|
||||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
BBC.NO_PERM.send(player, "worldedit.schematic.save.other");
|
||||||
final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
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();
|
final File parent = f.getParentFile();
|
||||||
if ((parent != null) && !parent.exists()) {
|
if ((parent != null) && !parent.exists()) {
|
||||||
if (!parent.mkdirs()) {
|
if (!parent.mkdirs()) {
|
||||||
|
@ -1,14 +1,26 @@
|
|||||||
package com.sk89q.worldedit.command.tool;
|
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.config.BBC;
|
||||||
import com.boydti.fawe.object.brush.DoubleActionBrush;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualBrush;
|
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.object.extent.ResettableExtent;
|
||||||
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.LocalConfiguration;
|
import com.sk89q.worldedit.LocalConfiguration;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
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.command.tool.brush.Brush;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
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.mask.MaskIntersection;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
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 javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class BrushTool implements DoubleActionTraceTool {
|
public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool {
|
||||||
|
|
||||||
public enum BrushAction {
|
public enum BrushAction {
|
||||||
PRIMARY,
|
PRIMARY,
|
||||||
@ -32,14 +47,12 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
|
|
||||||
protected static int MAX_RANGE = 500;
|
protected static int MAX_RANGE = 500;
|
||||||
protected int range = -1;
|
protected int range = -1;
|
||||||
private Mask mask = null;
|
private VisualMode visualMode = VisualMode.NONE;
|
||||||
private Mask sourceMask = null;
|
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||||
private ResettableExtent transform = null;
|
|
||||||
private Brush brush = null;
|
private BrushSettings context = new BrushSettings();
|
||||||
@Nullable
|
private BrushSettings primary = context;
|
||||||
private Pattern material;
|
private BrushSettings secondary = context;
|
||||||
private double size = 1;
|
|
||||||
private String permission;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the tool.
|
* Construct the tool.
|
||||||
@ -48,20 +61,41 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
*/
|
*/
|
||||||
public BrushTool(String permission) {
|
public BrushTool(String permission) {
|
||||||
checkNotNull(permission);
|
checkNotNull(permission);
|
||||||
this.permission = permission;
|
this.context.permission = permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUse(Actor player) {
|
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() {
|
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) {
|
public void setTransform(ResettableExtent transform) {
|
||||||
this.transform = transform;
|
this.context.transform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,7 +104,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @return the filter
|
* @return the filter
|
||||||
*/
|
*/
|
||||||
public Mask getMask() {
|
public Mask getMask() {
|
||||||
return mask;
|
return context.mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +113,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @return the filter
|
* @return the filter
|
||||||
*/
|
*/
|
||||||
public Mask getSourceMask() {
|
public Mask getSourceMask() {
|
||||||
return sourceMask;
|
return context.sourceMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,7 +122,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @param filter the filter to set
|
* @param filter the filter to set
|
||||||
*/
|
*/
|
||||||
public void setMask(Mask filter) {
|
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
|
* @param filter the filter to set
|
||||||
*/
|
*/
|
||||||
public void setSourceMask(Mask filter) {
|
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) {
|
public void setBrush(Brush brush, String permission, Player player) {
|
||||||
if (player != null && brush instanceof VisualBrush) {
|
if (player != null) clear(player);
|
||||||
((VisualBrush) brush).clear(player);
|
BrushSettings current = context;
|
||||||
}
|
current.brush = brush;
|
||||||
this.brush = brush;
|
current.permission = permission;
|
||||||
this.permission = permission;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,7 +157,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @return the current brush
|
* @return the current brush
|
||||||
*/
|
*/
|
||||||
public Brush getBrush() {
|
public Brush getBrush() {
|
||||||
return brush;
|
return context.brush;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +166,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @param material the material
|
* @param material the material
|
||||||
*/
|
*/
|
||||||
public void setFill(@Nullable Pattern 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
|
* @return the material
|
||||||
*/
|
*/
|
||||||
@Nullable public Pattern getMaterial() {
|
@Nullable public Pattern getMaterial() {
|
||||||
return material;
|
return context.material;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +184,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @return a radius
|
* @return a radius
|
||||||
*/
|
*/
|
||||||
public double getSize() {
|
public double getSize() {
|
||||||
return size;
|
return context.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,7 +193,7 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
* @param radius a radius
|
* @param radius a radius
|
||||||
*/
|
*/
|
||||||
public void setSize(double 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;
|
this.range = range;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
|
public Vector getPosition(EditSession editSession, Player player) {
|
||||||
if (action == BrushAction.SECONDARY && !(brush instanceof DoubleActionBrush)) {
|
switch (targetMode) {
|
||||||
return false;
|
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;
|
||||||
}
|
}
|
||||||
WorldVector target = null;
|
case TARGET_POINT_HEIGHT: {
|
||||||
target = player.getBlockTrace(getRange(), true);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
if (target == null) {
|
||||||
|
editSession.cancel();
|
||||||
BBC.NO_BLOCK.send(player);
|
BBC.NO_BLOCK.send(player);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockBag bag = session.getBlockBag(player);
|
BlockBag bag = session.getBlockBag(player);
|
||||||
|
|
||||||
EditSession editSession = session.createEditSession(player);
|
|
||||||
Request.request().setEditSession(editSession);
|
Request.request().setEditSession(editSession);
|
||||||
if (mask != null) {
|
if (current.mask != null) {
|
||||||
Mask existingMask = editSession.getMask();
|
Mask existingMask = editSession.getMask();
|
||||||
|
|
||||||
if (existingMask == null) {
|
if (existingMask == null) {
|
||||||
editSession.setMask(mask);
|
editSession.setMask(current.mask);
|
||||||
} else if (existingMask instanceof MaskIntersection) {
|
} else if (existingMask instanceof MaskIntersection) {
|
||||||
((MaskIntersection) existingMask).add(mask);
|
((MaskIntersection) existingMask).add(current.mask);
|
||||||
} else {
|
} else {
|
||||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||||
newMask.add(mask);
|
newMask.add(current.mask);
|
||||||
editSession.setMask(newMask);
|
editSession.setMask(newMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sourceMask != null) {
|
if (current.sourceMask != null) {
|
||||||
Mask existingMask = editSession.getSourceMask();
|
Mask existingMask = editSession.getSourceMask();
|
||||||
|
|
||||||
if (existingMask == null) {
|
if (existingMask == null) {
|
||||||
editSession.setSourceMask(sourceMask);
|
editSession.setSourceMask(current.sourceMask);
|
||||||
} else if (existingMask instanceof MaskIntersection) {
|
} else if (existingMask instanceof MaskIntersection) {
|
||||||
((MaskIntersection) existingMask).add(sourceMask);
|
((MaskIntersection) existingMask).add(current.sourceMask);
|
||||||
} else {
|
} else {
|
||||||
MaskIntersection newMask = new MaskIntersection(existingMask);
|
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||||
newMask.add(sourceMask);
|
newMask.add(current.sourceMask);
|
||||||
editSession.setSourceMask(newMask);
|
editSession.setSourceMask(newMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transform != null) {
|
if (current.transform != null) {
|
||||||
editSession.addTransform(transform);
|
editSession.addTransform(current.transform);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (brush instanceof DoubleActionBrush) {
|
current.brush.build(editSession, target, current.material, current.size);
|
||||||
((DoubleActionBrush) brush).build(action, editSession, target, material, size);
|
|
||||||
} else {
|
|
||||||
brush.build(editSession, target, material, size);
|
|
||||||
}
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
} catch (MaxChangedBlocksException e) {
|
||||||
player.printError("Max blocks change limit reached."); // Never happens
|
player.printError("Max blocks change limit reached."); // Never happens
|
||||||
} finally {
|
} finally {
|
||||||
@ -256,4 +328,104 @@ public class BrushTool implements DoubleActionTraceTool {
|
|||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
return BrushTool.class;
|
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,6 +162,8 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
|||||||
} else {
|
} else {
|
||||||
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(testId);
|
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(testId);
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
|
BaseBlock baseBlock = BundledBlockData.getInstance().findByState(testId);
|
||||||
|
if (baseBlock == null) {
|
||||||
blockType = BlockType.lookup(testId);
|
blockType = BlockType.lookup(testId);
|
||||||
if (blockType == null) {
|
if (blockType == null) {
|
||||||
int t = worldEdit.getServer().resolveItem(testId);
|
int t = worldEdit.getServer().resolveItem(testId);
|
||||||
@ -178,6 +180,11 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
blockId = baseBlock.getId();
|
||||||
|
blockType = BlockType.fromID(blockId);
|
||||||
|
data = baseBlock.getData();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
blockId = block.legacyId;
|
blockId = block.legacyId;
|
||||||
blockType = BlockType.fromID(blockId);
|
blockType = BlockType.fromID(blockId);
|
||||||
|
@ -185,7 +185,9 @@ public final class CommandManager {
|
|||||||
.group("superpickaxe", "pickaxe", "sp").describeAs("Super-pickaxe commands")
|
.group("superpickaxe", "pickaxe", "sp").describeAs("Super-pickaxe commands")
|
||||||
.registerMethods(new SuperPickaxeCommands(worldEdit)).parent().group("tool")
|
.registerMethods(new SuperPickaxeCommands(worldEdit)).parent().group("tool")
|
||||||
.describeAs("Bind functions to held items")
|
.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() {
|
public static CommandManager getInstance() {
|
||||||
@ -251,7 +253,7 @@ public final class CommandManager {
|
|||||||
return split;
|
return split;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleCommandOnCurrentThread(final CommandEvent event, boolean checkLimit) {
|
public void handleCommandOnCurrentThread(final CommandEvent event) {
|
||||||
Actor actor = platformManager.createProxyActor(event.getActor());
|
Actor actor = platformManager.createProxyActor(event.getActor());
|
||||||
final String args = event.getArguments();
|
final String args = event.getArguments();
|
||||||
final String[] split = commandDetection(args.split(" "));
|
final String[] split = commandDetection(args.split(" "));
|
||||||
@ -294,9 +296,7 @@ public final class CommandManager {
|
|||||||
}
|
}
|
||||||
locals.put(Actor.class, actor);
|
locals.put(Actor.class, actor);
|
||||||
final Actor finalActor = actor;
|
final Actor finalActor = actor;
|
||||||
if (!fp.runAction(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
locals.put("arguments", args);
|
locals.put("arguments", args);
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
@ -366,21 +366,25 @@ public final class CommandManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, checkLimit, false)) {
|
|
||||||
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handleCommand(final CommandEvent event) {
|
public void handleCommand(final CommandEvent event) {
|
||||||
Request.reset();
|
Request.reset();
|
||||||
|
final FawePlayer<Object> fp = FawePlayer.wrap(event.getActor());
|
||||||
TaskManager.IMP.taskNow(new Runnable() {
|
TaskManager.IMP.taskNow(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
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());
|
}, Fawe.isMainThread());
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@ -388,7 +392,6 @@ public final class CommandManager {
|
|||||||
try {
|
try {
|
||||||
CommandLocals locals = new CommandLocals();
|
CommandLocals locals = new CommandLocals();
|
||||||
locals.put(Actor.class, event.getActor());
|
locals.put(Actor.class, event.getActor());
|
||||||
locals.put("arguments", event.getArguments());
|
|
||||||
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
|
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
|
||||||
} catch (CommandException e) {
|
} catch (CommandException e) {
|
||||||
event.getActor().printError(e.getMessage());
|
event.getActor().printError(e.getMessage());
|
||||||
|
@ -63,6 +63,7 @@ public class BundledBlockData {
|
|||||||
private static final BundledBlockData INSTANCE = new BundledBlockData();
|
private static final BundledBlockData INSTANCE = new BundledBlockData();
|
||||||
|
|
||||||
private final Map<String, BlockEntry> idMap = new HashMap<String, BlockEntry>();
|
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 Map<String, BlockEntry> localIdMap = new HashMap<String, BlockEntry>();
|
||||||
|
|
||||||
private final BlockEntry[] legacyMap = new BlockEntry[4096];
|
private final BlockEntry[] legacyMap = new BlockEntry[4096];
|
||||||
@ -140,13 +141,23 @@ public class BundledBlockData {
|
|||||||
if (!overwrite && (idMap.containsKey(entry.id) || legacyMap[entry.legacyId] != null)) {
|
if (!overwrite && (idMap.containsKey(entry.id) || legacyMap[entry.legacyId] != null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String id = entry.id.contains(":") ? entry.id.split(":")[1] : entry.id;
|
|
||||||
idMap.put(entry.id, entry);
|
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;
|
legacyMap[entry.legacyId] = entry;
|
||||||
if (entry.states == null) {
|
if (entry.states == null) {
|
||||||
return true;
|
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");
|
FaweState half = entry.states.get("half");
|
||||||
if (half != null && half.values != null) {
|
if (half != null && half.values != null) {
|
||||||
FaweStateValue top = half.values.get("top");
|
FaweStateValue top = half.values.get("top");
|
||||||
@ -230,6 +241,10 @@ public class BundledBlockData {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BaseBlock findByState(String state) {
|
||||||
|
return stateMap.get(state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the entry for the given block ID.
|
* Return the entry for the given block ID.
|
||||||
*
|
*
|
||||||
@ -238,11 +253,7 @@ public class BundledBlockData {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockEntry findById(String id) {
|
public BlockEntry findById(String id) {
|
||||||
BlockEntry result = idMap.get(id);
|
return idMap.get(id);
|
||||||
if (result == null) {
|
|
||||||
result = localIdMap.get(id);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
|||||||
import com.boydti.fawe.forge.ForgePlayer;
|
import com.boydti.fawe.forge.ForgePlayer;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -146,32 +150,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarIntToBuffer(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
protected BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@ import com.boydti.fawe.forge.ForgePlayer;
|
|||||||
import com.boydti.fawe.forge.MutableGenLayer;
|
import com.boydti.fawe.forge.MutableGenLayer;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -160,34 +164,56 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
return ExtendedBlockStorages[cy];
|
return ExtendedBlockStorages[cy];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarInt(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarInt(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||||
|
@ -8,6 +8,9 @@ import com.boydti.fawe.object.FaweChunk;
|
|||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.IntegerPair;
|
import com.boydti.fawe.object.IntegerPair;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -322,32 +326,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerManager playerManager = ((WorldServer) getWorld()).getPlayerManager();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = new UnpooledByteBufAllocator(true).buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarIntToBuffer(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((ForgePlayer) player).parent.playerNetServerHandler.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).playerNetServerHandler.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ExtendedBlockStorage section) throws NoSuchFieldException, IllegalAccessException {
|
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ExtendedBlockStorage section) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<? extends ExtendedBlockStorage> clazz = section.getClass();
|
Class<? extends ExtendedBlockStorage> clazz = section.getClass();
|
||||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
|||||||
import com.boydti.fawe.forge.ForgePlayer;
|
import com.boydti.fawe.forge.ForgePlayer;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -203,32 +207,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerManager playerManager = ((WorldServer) getWorld()).getPlayerManager();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
S22PacketMultiBlockChange packet = new S22PacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarIntToBuffer(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((ForgePlayer) player).parent.playerNetServerHandler.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).playerNetServerHandler.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||||
|
@ -6,6 +6,9 @@ import com.boydti.fawe.example.NMSMappedFaweQueue;
|
|||||||
import com.boydti.fawe.forge.ForgePlayer;
|
import com.boydti.fawe.forge.ForgePlayer;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -244,32 +248,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((ForgePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarIntToBuffer(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((ForgePlayer) player).parent.connection.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((ForgePlayer) player).parent).connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||||
|
@ -33,6 +33,7 @@ public class NukkitRegistryDumper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NukkitRegistryDumper(File file) {
|
public NukkitRegistryDumper(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
GsonBuilder builder = new GsonBuilder().setPrettyPrinting();
|
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.nukkit.optimization.FaweNukkitPlayer;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
|
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
@ -128,25 +129,23 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
ArrayList<Block> blocks = new ArrayList<Block>();
|
try {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> entry : blockMap.entrySet()) {
|
boolean watching = true; // TODO check if player can see chunk
|
||||||
long chunkHash = entry.getKey();
|
if (!watching) return;
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
final ArrayList<Block> blocks = new ArrayList<>();
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
final int bx = chunk.getX() << 4;
|
||||||
Map<Short, Character> ids = entry.getValue();
|
final int bz = chunk.getZ() << 4;
|
||||||
for (Map.Entry<Short, Character> blockEntry : ids.entrySet()) {
|
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||||
char combined = blockEntry.getValue();
|
@Override
|
||||||
int id = FaweCache.getId(combined);
|
public void run(int localX, int y, int localZ, int combined) {
|
||||||
int data = FaweCache.getData(combined);
|
Block block = Block.get(FaweCache.getId(combined), FaweCache.getData(combined));
|
||||||
Block block = Block.get(id, data);
|
block.x = bz + localX;
|
||||||
short blockHash = blockEntry.getKey();
|
block.y = y;
|
||||||
block.x = (blockHash >> 12 & 0xF) + (cx << 4);
|
block.z = bx + localZ;
|
||||||
block.y = (blockHash & 0xFF);
|
|
||||||
block.z = (blockHash >> 8 & 0xF) + (cz << 4);
|
|
||||||
blocks.add(block);
|
blocks.add(block);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
Map<Level, List<Player>> playerMap = new HashMap<>();
|
Map<Level, List<Player>> playerMap = new HashMap<>();
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
Player nukkitPlayer = ((FaweNukkitPlayer) player).parent;
|
Player nukkitPlayer = ((FaweNukkitPlayer) player).parent;
|
||||||
@ -162,6 +161,9 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
|||||||
List<Player> playerList = levelListEntry.getValue();
|
List<Player> playerList = levelListEntry.getValue();
|
||||||
levelListEntry.getKey().sendBlocks(playerList.toArray(new Player[playerList.size()]), blocksArray, UpdateBlockPacket.FLAG_ALL_PRIORITY);
|
levelListEntry.getKey().sendBlocks(playerList.toArray(new Player[playerList.size()]), blocksArray, UpdateBlockPacket.FLAG_ALL_PRIORITY);
|
||||||
}
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,6 +5,9 @@ import com.boydti.fawe.example.CharFaweChunk;
|
|||||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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.sponge.SpongePlayer;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
@ -19,6 +22,7 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -132,32 +136,55 @@ public class SpongeQueue_1_11 extends NMSMappedFaweQueue<World, net.minecraft.wo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdate(Map<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
|
|
||||||
try {
|
try {
|
||||||
long chunkHash = chunkEntry.getKey();
|
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
||||||
Map<Short, Character> blocks = chunkEntry.getValue();
|
boolean watching = false;
|
||||||
SPacketMultiBlockChange packet = new SPacketMultiBlockChange();
|
for (int i = 0; i < players.length; i++) {
|
||||||
int cx = MathMan.unpairIntX(chunkHash);
|
EntityPlayerMP player = (EntityPlayerMP) ((SpongePlayer) players[i]).parent;
|
||||||
int cz = MathMan.unpairIntY(chunkHash);
|
if (!playerManager.isPlayerWatchingChunk(player, chunk.getX(), chunk.getZ())) {
|
||||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
players[i] = null;
|
||||||
PacketBuffer buffer = new PacketBuffer(byteBuf);
|
} else {
|
||||||
buffer.writeInt(cx);
|
watching = true;
|
||||||
buffer.writeInt(cz);
|
|
||||||
buffer.writeVarIntToBuffer(blocks.size());
|
|
||||||
for (Map.Entry<Short, Character> blockEntry : blocks.entrySet()) {
|
|
||||||
buffer.writeShort(blockEntry.getKey());
|
|
||||||
buffer.writeVarIntToBuffer(blockEntry.getValue());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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);
|
packet.readPacketData(buffer);
|
||||||
for (FawePlayer player : players) {
|
for (FawePlayer player : players) {
|
||||||
((EntityPlayerMP) ((SpongePlayer) player).parent).connection.sendPacket(packet);
|
if (player != null) ((EntityPlayerMP) ((SpongePlayer) player).parent).connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtendedBlockStorage[] getSections(Chunk chunk) {
|
public ExtendedBlockStorage[] getSections(Chunk chunk) {
|
||||||
|
Loading…
Reference in New Issue
Block a user