mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-12-01 07:03:52 +01:00
Various minor
Fix surfacespread pattern Add schematic loadall Fix brush reset
This commit is contained in:
parent
e79559650f
commit
eef3eff310
@ -105,6 +105,7 @@ public enum BBC {
|
||||
SELECTION_SHIFT("Region shifted", "WorldEdit.Selection"),
|
||||
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
||||
|
||||
BRUSH_RESET("Reset your 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"),
|
||||
|
@ -13,6 +13,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
@ -28,9 +29,11 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
||||
|
||||
private final LocalSession session;
|
||||
private final boolean randomRotate;
|
||||
private final Player player;
|
||||
|
||||
public CopyPastaBrush(LocalSession session, boolean randomRotate) {
|
||||
public CopyPastaBrush(Player player, LocalSession session, boolean randomRotate) {
|
||||
session.setClipboard(null);
|
||||
this.player = player;
|
||||
this.session = session;
|
||||
this.randomRotate = randomRotate;
|
||||
}
|
||||
@ -38,6 +41,7 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
||||
@Override
|
||||
public boolean reset() {
|
||||
session.setClipboard(null);
|
||||
BBC.BRUSH_RESET.send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
|
||||
public class MultiClipboardHolder extends ClipboardHolder{
|
||||
private final ClipboardHolder[] holders;
|
||||
|
||||
private ClipboardHolder holder;
|
||||
|
||||
public MultiClipboardHolder(WorldData worldData, ClipboardHolder... holders) {
|
||||
super(holders[0].getClipboard(), worldData);
|
||||
holder = holders[0];
|
||||
this.holders = holders;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
holder = holders[PseudoRandom.random.nextInt(holders.length)];
|
||||
return holder.getClipboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transform getTransform() {
|
||||
return holder.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(Transform transform) {
|
||||
holder.setTransform(transform);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@ -14,6 +15,10 @@ public class AdjacentAnyMask extends BlockMask {
|
||||
|
||||
private MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
public AdjacentAnyMask(Extent extent, BaseBlock... blocks) {
|
||||
this(extent, Arrays.asList(blocks));
|
||||
}
|
||||
|
||||
public AdjacentAnyMask(Extent extent, Collection<BaseBlock> blocks) {
|
||||
super(extent, blocks);
|
||||
}
|
||||
|
@ -4,65 +4,124 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
||||
|
||||
public class SurfaceRandomOffsetPattern extends AbstractPattern {
|
||||
private final PseudoRandom r = new PseudoRandom();
|
||||
private final int dx, dy, dz, dx2, dy2, dz2;
|
||||
private final Pattern pattern;
|
||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||
boolean[] solid;
|
||||
private final Extent extent;
|
||||
|
||||
public SurfaceRandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
||||
private int moves;
|
||||
|
||||
private final MutableBlockVector cur = new MutableBlockVector();
|
||||
private final MutableBlockVector[] buffer;
|
||||
private final MutableBlockVector[] allowed;
|
||||
private MutableBlockVector next;
|
||||
|
||||
public SurfaceRandomOffsetPattern(Extent extent, Pattern pattern, int distance) {
|
||||
this.pattern = pattern;
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
this.dx2 = dx * 2 + 1;
|
||||
this.dy2 = dy * 2 + 1;
|
||||
this.dz2 = dz * 2 + 1;
|
||||
solid = new boolean[Character.MAX_VALUE + 1];
|
||||
for (int id = 0; id < 4096; id++) {
|
||||
for (int data = 0; data < 16; data++) {
|
||||
if (!BlockType.canPassThrough(id, data)) {
|
||||
solid[FaweCache.getCombined(id, data)] = true;
|
||||
}
|
||||
}
|
||||
this.extent = extent;
|
||||
this.moves = Math.min(255, distance);
|
||||
this.buffer = new MutableBlockVector[BreadthFirstSearch.DIAGONAL_DIRECTIONS.length];
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
buffer[i] = new MutableBlockVector();
|
||||
}
|
||||
allowed = new MutableBlockVector[buffer.length];
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
|
||||
mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
|
||||
mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
|
||||
BaseBlock block = pattern.apply(mutable);
|
||||
if (solid[FaweCache.getCombined(block)]) {
|
||||
mutable.mutY(mutable.getY() + 1);
|
||||
if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return pattern.apply(position);
|
||||
return pattern.apply(travel(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector set, Vector get) throws WorldEditException {
|
||||
mutable.mutX((get.getX() + r.nextInt(dx2) - dx));
|
||||
mutable.mutY((get.getY() + r.nextInt(dy2) - dy));
|
||||
mutable.mutZ((get.getZ() + r.nextInt(dz2) - dz));
|
||||
BaseBlock block = pattern.apply(mutable);
|
||||
if (solid[FaweCache.getCombined(block)]) {
|
||||
mutable.mutY(mutable.getY() + 1);
|
||||
if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
||||
return pattern.apply(extent, set, mutable);
|
||||
private Vector travel(Vector pos) {
|
||||
cur.setComponents(pos);
|
||||
for (int move = 0; move < moves; move++) {
|
||||
int index = 0;
|
||||
for (int i = 0; i < allowed.length; i++) {
|
||||
next = buffer[i];
|
||||
Vector dir = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i];
|
||||
next.setComponents(cur.getBlockX() + dir.getBlockX(), cur.getBlockY() + dir.getBlockY(), cur.getBlockZ() + dir.getBlockZ());
|
||||
if (allowed(next)) {
|
||||
allowed[index++] = next;
|
||||
}
|
||||
}
|
||||
return pattern.apply(extent, set, get);
|
||||
if (index == 0) {
|
||||
return cur;
|
||||
}
|
||||
next = allowed[PseudoRandom.random.nextInt(index)];
|
||||
cur.setComponents(next.getBlockX(), next.getBlockY(), next.getBlockZ());
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
private boolean allowed(Vector v) {
|
||||
BaseBlock block = pattern.apply(v);
|
||||
if (FaweCache.canPassThrough(block.getId(), block.getData())) {
|
||||
return false;
|
||||
}
|
||||
int x = v.getBlockX();
|
||||
int y = v.getBlockY();
|
||||
int z = v.getBlockZ();
|
||||
v.mutY(y + 1);
|
||||
if (canPassthrough(v)) { v.mutY(y); return true; }
|
||||
v.mutY(y - 1);
|
||||
if (canPassthrough(v)) { v.mutY(y); return true; }
|
||||
v.mutY(y);
|
||||
v.mutX(x + 1);
|
||||
if (canPassthrough(v)) { v.mutX(x); return true; }
|
||||
v.mutX(x - 1);
|
||||
if (canPassthrough(v)) { v.mutX(x); return true; }
|
||||
v.mutX(x);
|
||||
v.mutZ(z + 1);
|
||||
if (canPassthrough(v)) { v.mutZ(z); return true; }
|
||||
v.mutZ(z - 1);
|
||||
if (canPassthrough(v)) { v.mutZ(z); return true; }
|
||||
v.mutZ(z);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean canPassthrough(Vector v) {
|
||||
BaseBlock block = pattern.apply(v);
|
||||
return FaweCache.canPassThrough(block.getId(), block.getData());
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public BaseBlock apply(Vector position) {
|
||||
// mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
|
||||
// mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
|
||||
// mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
|
||||
// BaseBlock block = pattern.apply(mutable);
|
||||
// if (solid[FaweCache.getCombined(block)]) {
|
||||
// if (solid[FaweCache.getCombined(mutable)])
|
||||
// mutable.mutY(mutable.getY() + 1);
|
||||
// if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
||||
// return block;
|
||||
// }
|
||||
// }
|
||||
// return pattern.apply(position);
|
||||
// }
|
||||
//
|
||||
// private Vector get(Vector input) {
|
||||
// for (dir :
|
||||
// BreadthFirstSearch.DIAGONAL_DIRECTIONS)
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean apply(Extent extent, Vector set, Vector get) throws WorldEditException {
|
||||
// mutable.mutX((get.getX() + r.nextInt(dx2) - dx));
|
||||
// mutable.mutY((get.getY() + r.nextInt(dy2) - dy));
|
||||
// mutable.mutZ((get.getZ() + r.nextInt(dz2) - dz));
|
||||
// BaseBlock block = pattern.apply(mutable);
|
||||
// if (solid[FaweCache.getCombined(block)]) {
|
||||
// mutable.mutY(mutable.getY() + 1);
|
||||
// if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
||||
// return pattern.apply(extent, set, mutable);
|
||||
// }
|
||||
// }
|
||||
// return pattern.apply(extent, set, get);
|
||||
// }
|
||||
}
|
@ -29,6 +29,10 @@ public class MutableBlockVector extends BlockVector {
|
||||
super(0, 0, 0);
|
||||
}
|
||||
|
||||
public MutableBlockVector setComponents(Vector other) {
|
||||
return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBlockVector setComponents(double x, double y, double z) {
|
||||
return this.setComponents((int) x, (int) y, (int) z);
|
||||
|
@ -895,7 +895,7 @@ public class BrushCommands {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new CopyPastaBrush(session, rotate), "worldedit.brush.copy", player);
|
||||
tool.setBrush(new CopyPastaBrush(player, session, rotate), "worldedit.brush.copy", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -89,6 +90,28 @@ public class SchematicCommands {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
@Command(aliases = { "loadall" }, usage = "[<format>] <filename|url>", desc = "Load a schematic into your clipboard")
|
||||
@Deprecated
|
||||
@CommandPermissions({ "worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.upload" })
|
||||
public void loadall(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws FilenameException {
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
WorldData wd = player.getWorld().getWorldData();
|
||||
ClipboardHolder[] all = format.loadAllFromInput(player, wd, filename, true);
|
||||
if (all != null) {
|
||||
MultiClipboardHolder multi = new MultiClipboardHolder(wd, all);
|
||||
session.setClipboard(multi);
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = { "load" }, usage = "[<format>] <filename>", desc = "Load a schematic into your clipboard")
|
||||
@Deprecated
|
||||
@CommandPermissions({ "worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.upload" })
|
||||
@ -96,7 +119,7 @@ public class SchematicCommands {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
player.printError("Unknown schematic format: " + formatName);
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName);
|
||||
return;
|
||||
}
|
||||
InputStream in = null;
|
||||
|
@ -598,9 +598,8 @@ public class UtilityCommands {
|
||||
}
|
||||
if (effectiveLength > 0) {
|
||||
String cat = args.getString(0);
|
||||
ArrayList<CommandMapping> mappings = grouped.get(cat);
|
||||
ArrayList<CommandMapping> mappings = effectiveLength == 1 ? grouped.get(cat) : null;
|
||||
if (mappings == null) {
|
||||
System.out.println("Aliases not found!");
|
||||
// Drill down to the command
|
||||
for (int i = 0; i < effectiveLength; i++) {
|
||||
String command = args.getString(i);
|
||||
@ -624,8 +623,6 @@ public class UtilityCommands {
|
||||
return;
|
||||
}
|
||||
}
|
||||
effectiveLength--;
|
||||
|
||||
visited.add(args.getString(i));
|
||||
isRootLevel = false;
|
||||
} else {
|
||||
@ -641,7 +638,6 @@ public class UtilityCommands {
|
||||
dispatcher = (Dispatcher) callable;
|
||||
aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
|
||||
} else {
|
||||
System.out.println("Set aliases " + aliases);
|
||||
aliases = mappings;
|
||||
}
|
||||
page = Math.max(0, page);
|
||||
@ -683,9 +679,7 @@ public class UtilityCommands {
|
||||
for (CommandMapping mapping : list) {
|
||||
CommandCallable c = mapping.getCallable();
|
||||
StringBuilder s1 = new StringBuilder();
|
||||
if (isRootLevel) {
|
||||
s1.append("/");
|
||||
}
|
||||
if (!visited.isEmpty()) {
|
||||
s1.append(Joiner.on(" ").join(visited));
|
||||
s1.append(" ");
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.BrushSettings;
|
||||
import com.boydti.fawe.object.brush.MovableTool;
|
||||
import com.boydti.fawe.object.brush.ResettableTool;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollAction;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollTool;
|
||||
@ -40,7 +41,7 @@ import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool {
|
||||
public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool, ResettableTool {
|
||||
|
||||
public enum BrushAction {
|
||||
PRIMARY,
|
||||
@ -133,6 +134,15 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
||||
return getContext().sourceMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reset() {
|
||||
Brush br = getBrush();
|
||||
if (br instanceof ResettableTool) {
|
||||
return ((ResettableTool) br).reset();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block filter used for identifying blocks to replace.
|
||||
*
|
||||
|
@ -245,15 +245,13 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
}
|
||||
case "#surfacespread": {
|
||||
try {
|
||||
List<String> split3 = suggestRemaining(rest, "#surfacespread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||
List<String> split3 = suggestRemaining(rest, "#surfacespread", "<distance>", "<pattern>");
|
||||
int dist = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||
rest = StringMan.join(split3.subList(1, split3.size()), ":");
|
||||
Pattern pattern = catchSuggestion(input, rest, context);
|
||||
return new SurfaceRandomOffsetPattern(pattern, x, y, z);
|
||||
return new SurfaceRandomOffsetPattern(Request.request().getExtent(), pattern, dist);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#surfacespread:<dx>:<dy>:<dz>:<pattern>");
|
||||
throw new SuggestInputParseException(null, "#surfacespread:<distance>:<pattern>");
|
||||
}
|
||||
}
|
||||
case "#solidspread": {
|
||||
|
Loading…
Reference in New Issue
Block a user