mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-13 14:48:34 +00:00
It started on work with commands then I got carried away.
This commit is contained in:
@ -95,7 +95,7 @@ public class ChunkCommands {
|
||||
Set<BlockVector2> chunks = session.getSelection(player.getWorld()).getChunks();
|
||||
|
||||
PaginationBox paginationBox = PaginationBox.fromStrings("Selected Chunks", "/listchunks -p %page%",
|
||||
chunks.stream().map(LegacyChunkStore::getFilename).collect(Collectors.toList()));
|
||||
chunks.stream().map(BlockVector2::toString).collect(Collectors.toList()));
|
||||
player.print(paginationBox.create(page));
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ public class ClipboardCommands {
|
||||
@Selection Region region,
|
||||
@Arg(desc = "Pattern to leave in place of the selection", def = "air")
|
||||
Pattern leavePattern,
|
||||
@Switch(name = 'e', desc = "skip cut entities")
|
||||
@Switch(name = 'e', desc = "Skip cut entities")
|
||||
boolean skipEntities,
|
||||
@Switch(name = 'b', desc = "Also copy biomes, source biomes are unaffected")
|
||||
boolean copyBiomes,
|
||||
@ -579,7 +579,7 @@ public class ClipboardCommands {
|
||||
desc = "Clear your clipboard"
|
||||
)
|
||||
@CommandPermissions("worldedit.clipboard.clear")
|
||||
public void clearClipboard(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
|
||||
public void clearClipboard(Player player, LocalSession session) throws WorldEditException {
|
||||
session.setClipboard(null);
|
||||
BBC.CLIPBOARD_CLEARED.send(player);
|
||||
}
|
||||
|
@ -19,9 +19,10 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
@ -29,8 +30,6 @@ import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -41,36 +40,32 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.DisallowedUsageException;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Callable;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
import org.enginehub.piston.annotation.param.Arg;
|
||||
import org.enginehub.piston.annotation.param.ArgFlag;
|
||||
import org.enginehub.piston.annotation.param.Switch;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* General WorldEdit commands.
|
||||
*/
|
||||
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
||||
//@Command(aliases = {}, desc = "Player toggles, settings and item info")
|
||||
public class GeneralCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
@ -141,12 +136,16 @@ public class GeneralCommands {
|
||||
@CommandPermissions("worldedit.fast")
|
||||
public void fast(Player player, LocalSession session, @Arg(desc = "The new fast mode state", def = "") Boolean fastMode) {
|
||||
boolean hasFastMode = session.hasFastMode();
|
||||
if (fastMode == null) fastMode = !hasFastMode;
|
||||
session.setFastMode(fastMode);
|
||||
if (fastMode) {
|
||||
BBC.FAST_ENABLED.send(player);
|
||||
} else {
|
||||
if (fastMode != null && fastMode == hasFastMode) {
|
||||
player.printError("Fast mode already " + (fastMode ? "enabled" : "disabled") + ".");
|
||||
return;
|
||||
}
|
||||
if (hasFastMode) {
|
||||
session.setFastMode(false);
|
||||
BBC.FAST_DISABLED.send(player);
|
||||
} else {
|
||||
session.setFastMode(true);
|
||||
BBC.FAST_ENABLED.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +298,7 @@ public class GeneralCommands {
|
||||
desc = "Set the global mask"
|
||||
)
|
||||
@CommandPermissions("worldedit.global-texture")
|
||||
public void gtexture(FawePlayer player, LocalSession session, EditSession editSession, @Arg(name = "context", desc = "InjectedValueAccess", def = "") List<String> arguments) throws WorldEditException, FileNotFoundException {
|
||||
public void gtexture(Player player, World world, LocalSession session, EditSession editSession, @Arg(name = "context", desc = "InjectedValueAccess", def = "") List<String> arguments) throws WorldEditException, FileNotFoundException {
|
||||
// gtexture <randomize> <min=0> <max=100>
|
||||
// TODO NOT IMPLEMENTED convert this to an ArgumentConverter
|
||||
if (arguments.isEmpty()) {
|
||||
@ -307,7 +306,7 @@ public class GeneralCommands {
|
||||
BBC.TEXTURE_DISABLED.send(player);
|
||||
} else {
|
||||
String arg = arguments.get(0);
|
||||
String argLower = arg.toLowerCase();
|
||||
String argLower = arg.toLowerCase(Locale.ROOT);
|
||||
|
||||
TextureUtil util = Fawe.get().getTextureUtil();
|
||||
int randomIndex = 1;
|
||||
@ -324,16 +323,15 @@ public class GeneralCommands {
|
||||
if (argLower.equals("true")) util = new RandomTextureUtil(util);
|
||||
checkRandomization = false;
|
||||
} else {
|
||||
HashSet<BaseBlock> blocks = null;
|
||||
if (argLower.equals("#copy") || argLower.equals("#clipboard")) {
|
||||
Clipboard clipboard = player.getSession().getClipboard().getClipboard();
|
||||
Clipboard clipboard = worldEdit.getSessionManager().get(player).getClipboard().getClipboard();
|
||||
util = TextureUtil.fromClipboard(clipboard);
|
||||
} else if (argLower.equals("*") || argLower.equals("true")) {
|
||||
util = Fawe.get().getTextureUtil();
|
||||
} else {
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(player.getPlayer());
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setActor(player);
|
||||
parserContext.setWorld(world);
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
Mask mask = worldEdit.getMaskFactory().parseFromInput(arg, parserContext);
|
||||
@ -392,7 +390,6 @@ public class GeneralCommands {
|
||||
)
|
||||
@CommandPermissions("fawe.tips")
|
||||
public void tips(Player player, LocalSession session) throws WorldEditException {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
if (player.togglePermission("fawe.tips")) {
|
||||
BBC.WORLDEDIT_TOGGLE_TIPS_ON.send(player);
|
||||
} else {
|
||||
|
@ -70,8 +70,7 @@ import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
* Commands for the generation of shapes and other objects.
|
||||
*/
|
||||
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
||||
//@Command(aliases = {}, desc = "Create structures and features: [More Info](https://goo.gl/KuLFRW)")
|
||||
public class GenerationCommands extends MethodCommands {
|
||||
public class GenerationCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
@ -275,9 +274,10 @@ public class GenerationCommands extends MethodCommands {
|
||||
int size,
|
||||
@Arg(desc = "The type of forest", def = "tree")
|
||||
TreeType type,
|
||||
@Range(min = 0, max = 100) @Arg(desc = "The density of the forest, between 0 and 100", def = "5")
|
||||
@Arg(desc = "The density of the forest, between 0 and 100", def = "5")
|
||||
double density) throws WorldEditException {
|
||||
density = density / 100;
|
||||
checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100");
|
||||
density /= 100;
|
||||
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type);
|
||||
player.print(affected + " trees created.");
|
||||
return affected;
|
||||
@ -393,7 +393,7 @@ public class GenerationCommands extends MethodCommands {
|
||||
|
||||
fp.checkConfirmationRegion(() -> {
|
||||
try {
|
||||
int affected = editSession.makeShape(region, zero, unit1, pattern, String.join(" ", expression), hollow, session.getTimeout());
|
||||
final int affected = editSession.makeShape(region, zero, unit1, pattern, String.join(" ", expression), hollow, session.getTimeout());
|
||||
player.findFreePosition();
|
||||
BBC.VISITOR_BLOCK.send(fp, affected);
|
||||
} catch (ExpressionException e) {
|
||||
|
@ -60,7 +60,7 @@ import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
* Commands to undo, redo, and clear history.
|
||||
*/
|
||||
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
||||
public class HistoryCommands extends MethodCommands {
|
||||
public class HistoryCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
@ -224,11 +224,12 @@ public class HistoryCommands extends MethodCommands {
|
||||
@Arg(name = "player", desc = "Undo this player's operations", def = "")
|
||||
String playerName,
|
||||
InjectedValueAccess context) throws WorldEditException {
|
||||
times = Math.max(1, times);
|
||||
LocalSession undoSession;
|
||||
if (session.hasFastMode()) {
|
||||
BBC.COMMAND_UNDO_DISABLED.send(player);
|
||||
return;
|
||||
}
|
||||
LocalSession undoSession;
|
||||
if (playerName != null && !playerName.isEmpty()) {
|
||||
player.checkPermission("worldedit.history.undo.other");
|
||||
undoSession = worldEdit.getSessionManager().findByName(playerName);
|
||||
@ -239,7 +240,6 @@ public class HistoryCommands extends MethodCommands {
|
||||
} else {
|
||||
undoSession = session;
|
||||
}
|
||||
times = Math.max(1, times);
|
||||
int finalTimes = times;
|
||||
FawePlayer.wrap(player).checkConfirmation(() -> {
|
||||
EditSession undone = null;
|
||||
|
@ -25,6 +25,7 @@ import com.boydti.fawe.object.mask.ZAxisMask;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
|
||||
@ -39,12 +40,14 @@ import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.request.RequestSelection;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
import org.enginehub.piston.annotation.param.Arg;
|
||||
import org.enginehub.piston.annotation.param.Switch;
|
||||
|
||||
@ -57,7 +60,8 @@ import org.enginehub.piston.annotation.param.Switch;
|
||||
// "e.g. >[stone,dirt],#light[0][5],$jungle\n" +
|
||||
// "More Info: https://git.io/v9r4K"
|
||||
//)
|
||||
public class MaskCommands extends MethodCommands {
|
||||
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
||||
public class MaskCommands {
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
public MaskCommands(WorldEdit worldEdit) {
|
||||
@ -69,7 +73,7 @@ public class MaskCommands extends MethodCommands {
|
||||
desc = "Use simplex noise as the mask"
|
||||
)
|
||||
public Mask simplex(double scale, double min, double max) {
|
||||
scale = (1d / Math.max(1, scale));
|
||||
scale = 1d / Math.max(1, scale);
|
||||
min = (min - 50) / 50;
|
||||
max = (max - 50) / 50;
|
||||
return new SimplexMask(scale, min, max);
|
||||
@ -290,11 +294,11 @@ public class MaskCommands extends MethodCommands {
|
||||
if (max.endsWith("d")) {
|
||||
double y1d = Expression.compile(min.substring(0, min.length() - 1)).evaluate();
|
||||
double y2d = Expression.compile(max.substring(0, max.length() - 1)).evaluate();
|
||||
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||
y1 = Math.tan(y1d * (Math.PI / 180));
|
||||
y2 = Math.tan(y2d * (Math.PI / 180));
|
||||
} else {
|
||||
y1 = (Expression.compile(min).evaluate());
|
||||
y2 = (Expression.compile(max).evaluate());
|
||||
y1 = Expression.compile(min).evaluate();
|
||||
y2 = Expression.compile(max).evaluate();
|
||||
}
|
||||
return new AngleMask(extent, y1, y2, overlay, distance);
|
||||
}
|
||||
@ -315,11 +319,11 @@ public class MaskCommands extends MethodCommands {
|
||||
if (max.endsWith("d")) {
|
||||
double y1d = Expression.compile(min.substring(0, min.length() - 1)).evaluate();
|
||||
double y2d = Expression.compile(max.substring(0, max.length() - 1)).evaluate();
|
||||
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||
y1 = Math.tan(y1d * (Math.PI / 180));
|
||||
y2 = Math.tan(y2d * (Math.PI / 180));
|
||||
} else {
|
||||
y1 = (Expression.compile(min).evaluate());
|
||||
y2 = (Expression.compile(max).evaluate());
|
||||
y1 = Expression.compile(min).evaluate();
|
||||
y2 = Expression.compile(max).evaluate();
|
||||
}
|
||||
return new ROCAngleMask(extent, y1, y2, overlay, distance);
|
||||
}
|
||||
@ -340,11 +344,11 @@ public class MaskCommands extends MethodCommands {
|
||||
if (max.endsWith("d")) {
|
||||
double y1d = Expression.compile(min.substring(0, min.length() - 1)).evaluate();
|
||||
double y2d = Expression.compile(max.substring(0, max.length() - 1)).evaluate();
|
||||
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||
y1 = Math.tan(y1d * (Math.PI / 180));
|
||||
y2 = Math.tan(y2d * (Math.PI / 180));
|
||||
} else {
|
||||
y1 = (Expression.compile(min).evaluate());
|
||||
y2 = (Expression.compile(max).evaluate());
|
||||
y1 = Expression.compile(min).evaluate();
|
||||
y2 = Expression.compile(max).evaluate();
|
||||
}
|
||||
return new ExtremaMask(extent, y1, y2, overlay, distance);
|
||||
}
|
||||
@ -430,7 +434,7 @@ public class MaskCommands extends MethodCommands {
|
||||
)
|
||||
public Mask expression(Extent extent, String input) throws ExpressionException {
|
||||
Expression exp = Expression.compile(input, "x", "y", "z");
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(extent, Vector3.ONE, Vector3.ZERO);
|
||||
ExpressionEnvironment env = new WorldEditExpressionEnvironment(extent, Vector3.ONE, Vector3.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
return new ExpressionMask(exp);
|
||||
}
|
||||
|
@ -159,12 +159,21 @@ public class NavigationCommands {
|
||||
desc = "Teleport to a location"
|
||||
)
|
||||
@CommandPermissions("worldedit.navigation.jumpto.command")
|
||||
public void jumpTo(Player player, @Arg(desc = "Location to jump to", def = "") Location pos, @Switch(name='f', desc = "force teleport") boolean force) throws WorldEditException {
|
||||
public void jumpTo(Player player,
|
||||
@Arg(desc = "Location to jump to", def = "")
|
||||
Location pos,
|
||||
@Switch(name='f', desc = "force teleport")
|
||||
boolean force) throws WorldEditException {
|
||||
|
||||
if (pos == null) {
|
||||
pos = player.getSolidBlockTrace(300);
|
||||
}
|
||||
if (pos != null) {
|
||||
if(force) player.setPosition(pos); else player.findFreePosition(pos);
|
||||
if (force) {
|
||||
player.setPosition(pos);
|
||||
} else {
|
||||
player.findFreePosition(pos);
|
||||
}
|
||||
BBC.POOF.send(player);
|
||||
} else {
|
||||
BBC.NO_BLOCK.send(player);
|
||||
|
@ -8,6 +8,7 @@ import com.boydti.fawe.object.pattern.*;
|
||||
import com.boydti.fawe.object.random.SimplexRandom;
|
||||
import com.boydti.fawe.util.ColorUtil;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
@ -27,6 +28,7 @@ import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.internal.annotation.Range;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
import org.enginehub.piston.annotation.param.Arg;
|
||||
|
||||
import java.awt.Color;
|
||||
@ -43,12 +45,8 @@ import java.util.Set;
|
||||
// "e.g. #surfacespread[10][#existing],andesite\n" +
|
||||
// "More Info: https://git.io/vSPmA"
|
||||
//)
|
||||
public class PatternCommands extends MethodCommands {
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
public PatternCommands(WorldEdit worldEdit) {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
||||
public class PatternCommands {
|
||||
|
||||
@Command(
|
||||
name = "#existing",
|
||||
|
@ -100,6 +100,26 @@ public class RegionCommands {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/set",
|
||||
desc = "Sets all the blocks in the region"
|
||||
)
|
||||
@CommandPermissions("worldedit.region.set")
|
||||
@Logging(REGION)
|
||||
public void set(FawePlayer player, EditSession editSession,
|
||||
@Selection Region region,
|
||||
@Arg(desc = "The pattern of blocks to set")
|
||||
Pattern pattern, InjectedValueAccess context) throws WorldEditException {
|
||||
player.checkConfirmationRegion(() -> {
|
||||
int affected = editSession.setBlocks(region, pattern);
|
||||
if (affected != 0) {
|
||||
BBC.OPERATION.send(player, affected);
|
||||
if (!player.hasPermission("fawe.tips"))
|
||||
BBC.TIP_FAST.or(BBC.TIP_CANCEL, BBC.TIP_MASK, BBC.TIP_MASK_ANGLE, BBC.TIP_SET_LINEAR, BBC.TIP_SURFACE_SPREAD, BBC.TIP_SET_HAND).send(player);
|
||||
}
|
||||
}, getArguments(context), region, context);
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/fixlighting",
|
||||
desc = "Get the light at a position"
|
||||
@ -197,7 +217,7 @@ public class RegionCommands {
|
||||
@Arg(desc = "The pattern of blocks to place")
|
||||
Pattern pattern,
|
||||
@Arg(desc = "The thickness of the line", def = "0")
|
||||
@Range(min = 0) int thickness,
|
||||
int thickness,
|
||||
@Switch(name = 'h', desc = "Generate only a shell")
|
||||
boolean shell) throws WorldEditException {
|
||||
if (!(region instanceof CuboidRegion)) {
|
||||
@ -227,7 +247,7 @@ public class RegionCommands {
|
||||
@Arg(desc = "The pattern of blocks to place")
|
||||
Pattern pattern,
|
||||
@Arg(desc = "The thickness of the curve", def = "0")
|
||||
@Range(min = 0) int thickness,
|
||||
int thickness,
|
||||
@Switch(name = 'h', desc = "Generate only a shell")
|
||||
boolean shell, InjectedValueAccess context) throws WorldEditException {
|
||||
if (!(region instanceof ConvexPolyhedralRegion)) {
|
||||
@ -258,6 +278,9 @@ public class RegionCommands {
|
||||
Mask from,
|
||||
@Arg(desc = "The pattern of blocks to replace with")
|
||||
Pattern to, InjectedValueAccess context) throws WorldEditException {
|
||||
if (from == null) {
|
||||
from = new ExistingBlockMask(editSession);
|
||||
}
|
||||
player.checkConfirmationRegion(() -> {
|
||||
int affected = editSession.replaceBlocks(region, from == null ? new ExistingBlockMask(editSession) : from, to);
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
@ -269,31 +292,13 @@ public class RegionCommands {
|
||||
}
|
||||
}, getArguments(context), region, context);
|
||||
}
|
||||
|
||||
// Compatibility for SKCompat
|
||||
|
||||
@Deprecated
|
||||
public void set(Player player, LocalSession session, EditSession editSession, Pattern pattern) throws WorldEditException {
|
||||
set(FawePlayer.wrap(player), session, editSession, session.getSelection(player.getWorld()), pattern, null);
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/set",
|
||||
aliases = { "/s" },
|
||||
desc = "Set all blocks within selection"
|
||||
)
|
||||
@CommandPermissions("worldedit.region.set")
|
||||
@Logging(REGION)
|
||||
public void set(FawePlayer player, LocalSession session, EditSession editSession, @Selection Region selection, Pattern to, InjectedValueAccess context) throws WorldEditException {
|
||||
player.checkConfirmationRegion(() -> {
|
||||
int affected = editSession.setBlocks(selection, to);
|
||||
if (affected != 0) {
|
||||
BBC.OPERATION.send(player, affected);
|
||||
if (!player.hasPermission("fawe.tips"))
|
||||
BBC.TIP_FAST.or(BBC.TIP_CANCEL, BBC.TIP_MASK, BBC.TIP_MASK_ANGLE, BBC.TIP_SET_LINEAR, BBC.TIP_SURFACE_SPREAD, BBC.TIP_SET_HAND).send(player);
|
||||
}
|
||||
}, getArguments(context), selection, context);
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/overlay",
|
||||
desc = "Set a block on top of blocks in the region"
|
||||
@ -526,7 +531,7 @@ public class RegionCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.region.stack")
|
||||
@Logging(ORIENTATION_REGION)
|
||||
public void stack(FawePlayer player, World world, EditSession editSession, LocalSession session,
|
||||
public void stack(FawePlayer player, EditSession editSession, LocalSession session,
|
||||
@Selection Region region,
|
||||
@Arg(desc = "# of copies to stack", def = "1")
|
||||
int count,
|
||||
@ -557,8 +562,8 @@ public class RegionCommands {
|
||||
final BlockVector3 shiftVector = direction.toVector3().multiply(count * (Math.abs(direction.dot(size)) + 1)).toBlockPoint();
|
||||
region.shift(shiftVector);
|
||||
|
||||
session.getRegionSelector(world).learnChanges();
|
||||
session.getRegionSelector(world).explainRegionAdjust(player.getPlayer(), session);
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player.getPlayer(), session);
|
||||
} catch (RegionOperationException e) {
|
||||
player.toWorldEditPlayer().printError(e.getMessage());
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.command.argument.SelectorChoice;
|
||||
import com.sk89q.worldedit.command.tool.NavigationWand;
|
||||
import com.sk89q.worldedit.command.tool.SelectionWand;
|
||||
import com.sk89q.worldedit.command.util.CommandPermissions;
|
||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||
import com.sk89q.worldedit.command.util.Logging;
|
||||
@ -66,6 +68,7 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import java.io.File;
|
||||
@ -249,8 +252,23 @@ public class SelectionCommands {
|
||||
@CommandPermissions("worldedit.wand")
|
||||
public void wand(Player player, LocalSession session,
|
||||
@Switch(name = 'n', desc = "Get a navigation wand") boolean navWand) throws WorldEditException {
|
||||
player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1));
|
||||
BBC.SELECTION_WAND.send(player);
|
||||
String wandId = navWand ? session.getNavWandItem() : session.getWandItem();
|
||||
if (wandId == null) {
|
||||
wandId = navWand ? we.getConfiguration().navigationWand : we.getConfiguration().wandItem;
|
||||
}
|
||||
ItemType itemType = ItemTypes.parse(wandId);
|
||||
if (itemType == null) {
|
||||
player.printError("Wand item is mis-configured or disabled.");
|
||||
return;
|
||||
}
|
||||
player.giveItem(new BaseItemStack(itemType, 1));
|
||||
if (navWand) {
|
||||
session.setTool(itemType, new NavigationWand());
|
||||
player.print("Left click: jump to location; Right click: pass through walls");
|
||||
} else {
|
||||
session.setTool(itemType, new SelectionWand());
|
||||
BBC.SELECTION_WAND.send(player);
|
||||
}
|
||||
if (!player.hasPermission("fawe.tips"))
|
||||
BBC.TIP_SEL_LIST.or(BBC.TIP_SELECT_CONNECTED, BBC.TIP_SET_POS1, BBC.TIP_FARWAND, BBC.TIP_DISCORD).send(player);
|
||||
}
|
||||
@ -440,20 +458,22 @@ public class SelectionCommands {
|
||||
index++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
region = session.getSelection(player.getWorld());
|
||||
region = session.getSelection(player.getWorld());
|
||||
player.print("Type: " + session.getRegionSelector(player.getWorld()).getTypeName());
|
||||
|
||||
for (String line : session.getRegionSelector(player.getWorld())
|
||||
.getInformationLines()) {
|
||||
player.print(line);
|
||||
}
|
||||
|
||||
}
|
||||
BlockVector3 size = region.getMaximumPoint()
|
||||
.subtract(region.getMinimumPoint())
|
||||
.add(1, 1, 1);
|
||||
|
||||
player.print("Type: " + session.getRegionSelector(player.getWorld())
|
||||
.getTypeName());
|
||||
|
||||
for (String line : session.getRegionSelector(player.getWorld())
|
||||
.getInformationLines()) {
|
||||
player.print(line);
|
||||
}
|
||||
|
||||
player.print("Size: " + size);
|
||||
player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
|
||||
@ -463,7 +483,7 @@ public class SelectionCommands {
|
||||
|
||||
@Command(
|
||||
name = "/count",
|
||||
desc = "Counts the number of a certain type of block"
|
||||
desc = "Counts the number of blocks matching a mask"
|
||||
)
|
||||
@CommandPermissions("worldedit.analysis.count")
|
||||
public void count(Player player, LocalSession session, EditSession editSession,
|
||||
|
@ -110,6 +110,7 @@ public class ToolCommands {
|
||||
public void inspectBrush(Player player, LocalSession session,
|
||||
@Arg(desc = "The radius of the brush", def = "1")
|
||||
double radius) throws WorldEditException {
|
||||
radius = Math.max(1,radius);
|
||||
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
|
||||
session.setTool(player, new InspectBrush());
|
||||
BBC.TOOL_INSPECT.send(player, itemStack.getType().getName());
|
||||
|
@ -72,7 +72,7 @@ public class TransformCommands {
|
||||
aliases = {"#randomoffset"},
|
||||
desc = "Random offset transform"
|
||||
)
|
||||
public ResettableExtent randomoffset(Actor actor, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
|
||||
public ResettableExtent randomOffset(Actor actor, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
|
||||
return new RandomOffsetTransform(other, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ public class TransformCommands {
|
||||
desc = "All changes will be rotate around the initial position"
|
||||
)
|
||||
public ResettableExtent rotate(Player player, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
|
||||
ExtentTraverser<TransformExtent> traverser = new ExtentTraverser(other).find(TransformExtent.class);
|
||||
ExtentTraverser<TransformExtent> traverser = new ExtentTraverser<>(other).find(TransformExtent.class);
|
||||
BlockTransformExtent affine = traverser != null ? traverser.get() : null;
|
||||
if (affine == null) {
|
||||
other = affine = new TransformExtent(other);
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
|
||||
import static com.sk89q.worldedit.util.formatting.text.TextComponent.newline;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
@ -29,7 +30,6 @@ import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal3;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
@ -70,6 +70,9 @@ import com.sk89q.worldedit.regions.CylinderRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent.Builder;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
@ -85,10 +88,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
import org.enginehub.piston.annotation.param.Arg;
|
||||
@ -188,11 +191,13 @@ public class UtilityCommands {
|
||||
@Arg(desc = "The blocks to fill with")
|
||||
Pattern pattern,
|
||||
@Arg(desc = "The radius to fill in")
|
||||
@Range(min = 1) double radius,
|
||||
double radius,
|
||||
@Arg(desc = "The depth to fill", def = "1")
|
||||
@Range(min = 1) int depth,
|
||||
int depth,
|
||||
@Arg(desc = "Direction to fill", def = "down") BlockVector3 direction) throws WorldEditException {
|
||||
radius = Math.max(1, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
depth = Math.max(1, depth);
|
||||
|
||||
BlockVector3 pos = session.getPlacementPosition(player);
|
||||
int affected = editSession.fillDirection(pos, pattern, radius, depth, direction);
|
||||
@ -281,9 +286,10 @@ public class UtilityCommands {
|
||||
@Arg(desc = "The blocks to fill with")
|
||||
Pattern pattern,
|
||||
@Arg(desc = "The radius to fill in")
|
||||
@Range(min = 1) double radius,
|
||||
double radius,
|
||||
@Arg(desc = "The depth to fill", def = "")
|
||||
@Range(min = 1) Integer depth) throws WorldEditException {
|
||||
Integer depth) throws WorldEditException {
|
||||
radius = Math.max(1, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
depth = depth == null ? Integer.MAX_VALUE : Math.max(1, depth);
|
||||
we.checkMaxRadius(radius);
|
||||
@ -302,9 +308,10 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int drain(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius to drain")
|
||||
@Range(min = 0) double radius,
|
||||
double radius,
|
||||
@Switch(name = 'w', desc = "Also un-waterlog blocks")
|
||||
boolean waterlogged) throws WorldEditException {
|
||||
radius = Math.max(0, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
int affected = editSession.drainArea(
|
||||
session.getPlacementPosition(player), radius, waterlogged);
|
||||
@ -321,7 +328,8 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int fixLava(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius to fix in")
|
||||
@Range(min = 0) double radius) throws WorldEditException {
|
||||
double radius) throws WorldEditException {
|
||||
radius = Math.max(0, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
int affected = editSession.fixLiquid(session.getPlacementPosition(player), radius, BlockTypes.LAVA);
|
||||
player.print(affected + " block(s) have been changed.");
|
||||
@ -354,10 +362,13 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int removeAbove(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The apothem of the square to remove from", def = "1")
|
||||
@Range(min = 1) int size,
|
||||
int size,
|
||||
@Arg(desc = "The maximum height above you to remove from", def = "")
|
||||
Integer height) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
World world = player.getWorld();
|
||||
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
|
||||
int affected = editSession.removeAbove(session.getPlacementPosition(player), size, height);
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
return affected;
|
||||
@ -372,9 +383,10 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int removeBelow(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The apothem of the square to remove from", def = "1")
|
||||
@Range(min =1) int size,
|
||||
int size,
|
||||
@Arg(desc = "The maximum height below you to remove from", def = "")
|
||||
Integer height) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
World world = player.getWorld();
|
||||
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
|
||||
@ -395,7 +407,8 @@ public class UtilityCommands {
|
||||
@Arg(desc = "The mask of blocks to remove")
|
||||
Mask mask,
|
||||
@Arg(desc = "The radius of the square to remove from", def = "50")
|
||||
@Range(min=1) int radius) throws WorldEditException {
|
||||
int radius) throws WorldEditException {
|
||||
radius = Math.max(1, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
|
||||
int affected = editSession.removeNear(session.getPlacementPosition(player), mask, radius);
|
||||
@ -412,11 +425,12 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int replaceNear(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius of the square to remove in")
|
||||
@Range(min=1) int radius,
|
||||
int radius,
|
||||
@Arg(desc = "The mask matching blocks to remove", def = "")
|
||||
Mask from,
|
||||
@Arg(desc = "The pattern of blocks to replace with")
|
||||
Pattern to) throws WorldEditException {
|
||||
radius = Math.max(1, radius);
|
||||
we.checkMaxRadius(radius);
|
||||
|
||||
BlockVector3 base = session.getPlacementPosition(player);
|
||||
@ -442,11 +456,12 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int snow(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius of the circle to snow in", def = "10")
|
||||
@Range(min=1) double size) throws WorldEditException {
|
||||
double size) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
|
||||
int affected = editSession.simulateSnow(session.getPlacementPosition(player), size);
|
||||
player.print(affected + " surfaces covered. Let it snow~");
|
||||
player.print(affected + " surface(s) covered. Let it snow~");
|
||||
return affected;
|
||||
}
|
||||
|
||||
@ -459,11 +474,12 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int thaw(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius of the circle to thaw in", def = "10")
|
||||
@Range(min=1) double size) throws WorldEditException {
|
||||
double size) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
|
||||
int affected = editSession.thaw(session.getPlacementPosition(player), size);
|
||||
player.print(affected + " surfaces thawed.");
|
||||
player.print(affected + " surface(s) thawed.");
|
||||
return affected;
|
||||
}
|
||||
|
||||
@ -476,9 +492,10 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public int green(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius of the circle to convert in", def = "10")
|
||||
@Range(min=1) double size,
|
||||
double size,
|
||||
@Switch(name = 'f', desc = "Also convert coarse dirt")
|
||||
boolean convertCoarse) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
final boolean onlyNormalDirt = !convertCoarse;
|
||||
|
||||
@ -496,12 +513,12 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public void extinguish(Player player, LocalSession session, EditSession editSession,
|
||||
@Arg(desc = "The radius of the square to remove in", def = "")
|
||||
@Range(min=1) Integer radius) throws WorldEditException {
|
||||
Integer radius) throws WorldEditException {
|
||||
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
|
||||
int defaultRadius = config.maxRadius != -1 ? Math.min(40, config.maxRadius) : 40;
|
||||
int size = radius != null ? radius : defaultRadius;
|
||||
int size = radius != null ? Math.max(1, radius) : defaultRadius;
|
||||
we.checkMaxRadius(size);
|
||||
|
||||
Mask mask = new BlockTypeMask(editSession, BlockTypes.FIRE);
|
||||
@ -657,7 +674,8 @@ public class UtilityCommands {
|
||||
return;
|
||||
}
|
||||
WorldEditAsyncCommandBuilder.createAndSendMessage(actor, () -> {
|
||||
double result = expression.evaluateTimeout(WorldEdit.getInstance().getSessionManager().get(actor).getTimeout());
|
||||
double result = expression.evaluate(
|
||||
new double[]{}, WorldEdit.getInstance().getSessionManager().get(actor).getTimeout());
|
||||
String formatted = Double.isNaN(result) ? "NaN" : formatter.format(result);
|
||||
return SubtleFormat.wrap(input + " = ").append(TextComponent.of(formatted, TextColor.LIGHT_PURPLE));
|
||||
}, null);
|
||||
@ -690,16 +708,18 @@ public class UtilityCommands {
|
||||
}
|
||||
|
||||
public static void list(File dir, Actor actor, InjectedValueAccess args, @Range(min = 0) int page, String formatName, boolean playerFolder, String onClickCmd) {
|
||||
list(dir, actor, args, page, -1, formatName, playerFolder, new RunnableVal3<Message, URI, String>() {
|
||||
list(dir, actor, args, page, -1, formatName, playerFolder, new RunnableVal3<Builder, URI, String>() {
|
||||
@Override
|
||||
public void run(Message m, URI uri, String fileName) {
|
||||
m.text(BBC.SCHEMATIC_LIST_ELEM, fileName, "");
|
||||
if (onClickCmd != null) m.cmdTip(onClickCmd + " " + fileName);
|
||||
public void run(Builder m, URI uri, String fileName) {
|
||||
m.append(BBC.SCHEMATIC_LIST_ELEM.format(fileName, ""));
|
||||
if (onClickCmd != null) { m.hoverEvent(HoverEvent.showText(TextComponent.of(onClickCmd + " " + fileName)))
|
||||
.clickEvent(ClickEvent.runCommand(onClickCmd + " " + fileName));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void list(File dir, Actor actor, InjectedValueAccess args, @Range(min = 0) int page, int perPage, String formatName, boolean playerFolder, RunnableVal3<Message, URI, String> eachMsg) {
|
||||
public static void list(File dir, Actor actor, InjectedValueAccess args, @Range(min = 0) int page, int perPage, String formatName, boolean playerFolder, RunnableVal3<Builder, URI, String> eachMsg) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
if (perPage == -1) perPage = actor instanceof Player ? 12 : 20; // More pages for console
|
||||
page = getFiles(dir, actor, args, page, perPage, formatName, playerFolder, fileList::add);
|
||||
@ -719,7 +739,7 @@ public class UtilityCommands {
|
||||
return;
|
||||
}
|
||||
|
||||
final int sortType = args.hasFlag('d') ? -1 : args.hasFlag('n') ? 1 : 0;
|
||||
final int sortType = 0; //args.hasFlag('d') ? -1 : args.hasFlag('n') ? 1 : 0;
|
||||
// cleanup file list
|
||||
fileList.sort((f1, f2) -> {
|
||||
boolean dir1 = f1.isDirectory();
|
||||
@ -751,18 +771,18 @@ public class UtilityCommands {
|
||||
if (fullArgs != null) {
|
||||
baseCmd = fullArgs.endsWith(" " + page) ? fullArgs.substring(0, fullArgs.length() - (" " + page).length()) : fullArgs;
|
||||
}
|
||||
Message m = new Message(BBC.SCHEMATIC_LIST, page, pageCount);
|
||||
@NonNull Builder m = TextComponent.builder(BBC.SCHEMATIC_LIST.format(page, pageCount));
|
||||
|
||||
UUID uuid = playerFolder ? actor.getUniqueId() : null;
|
||||
for (int i = offset; i < limit; i++) {
|
||||
m.newline();
|
||||
m.append(newline());
|
||||
File file = fileList.get(i);
|
||||
eachMsg.run(m, file.toURI(), getPath(dir, file, uuid));
|
||||
}
|
||||
if (baseCmd != null) {
|
||||
m.newline().paginate(baseCmd, page, pageCount);
|
||||
//TODO m.newline().paginate(baseCmd, page, pageCount);
|
||||
}
|
||||
m.send(actor);
|
||||
actor.print(m.build());
|
||||
}
|
||||
|
||||
public static int getFiles(File root, Actor actor, InjectedValueAccess args, int page, int perPage, String formatName, boolean playerFolder, Consumer<File> forEachFile, ListFilters... filters) {
|
||||
|
@ -101,7 +101,7 @@ public class WorldEditCommands {
|
||||
Platform platform = pm.queryCapability(capability);
|
||||
actor.printDebug(String.format("%s: %s", capability.name(), platform != null ? platform.getPlatformName() : "NONE"));
|
||||
}
|
||||
actor.printDebug("------------------------------------");
|
||||
actor.printDebug("");
|
||||
actor.printDebug("Wiki: " + "https://github.com/boy0001/FastAsyncWorldedit/wiki");
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
||||
protected int range = -1;
|
||||
private VisualMode visualMode = VisualMode.NONE;
|
||||
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||
private Mask traceMask;
|
||||
private Mask traceMask = null;
|
||||
private int targetOffset;
|
||||
|
||||
private transient BrushSettings primary = new BrushSettings();
|
||||
|
@ -26,6 +26,7 @@ import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@ -72,10 +73,11 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
|
||||
|
||||
private Location getTarget(Player player) {
|
||||
Location target;
|
||||
Mask mask = getTraceMask();
|
||||
if (this.range > -1) {
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
target = player.getBlockTrace(getRange(), true, mask);
|
||||
} else {
|
||||
target = player.getBlockTrace(DEFAULT_RANGE);
|
||||
target = player.getBlockTrace(MAX_RANGE, false, mask);
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
|
@ -216,7 +216,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
final World world = context.requireWorld();
|
||||
final BlockVector3 primaryPosition;
|
||||
try {
|
||||
primaryPosition = context.requireSession().getRegionSelector(world).getVerticies().get(index - 1);
|
||||
primaryPosition = context.requireSession().getRegionSelector(world).getVertices().get(index - 1);
|
||||
} catch (IncompleteRegionException e) {
|
||||
throw new InputParseException("Your selection is not complete.");
|
||||
}
|
||||
@ -356,4 +356,4 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class DefaultPatternParser extends FaweParser<Pattern> {
|
||||
public DefaultPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
this.dispatcher = new SimpleDispatcher();
|
||||
this.register(new PatternCommands(worldEdit));
|
||||
this.register(new PatternCommands());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -412,7 +412,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
if (typeId.hasBlockType()) {
|
||||
return typeId.getBlockType().getDefaultState().toBaseBlock();
|
||||
} else {
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
throw new NotABlockException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ import com.sk89q.worldedit.command.HistoryCommandsRegistration;
|
||||
import com.sk89q.worldedit.command.NavigationCommands;
|
||||
import com.sk89q.worldedit.command.NavigationCommandsRegistration;
|
||||
import com.sk89q.worldedit.command.PaintBrushCommands;
|
||||
import com.sk89q.worldedit.command.PatternCommands;
|
||||
import com.sk89q.worldedit.command.RegionCommands;
|
||||
import com.sk89q.worldedit.command.RegionCommandsRegistration;
|
||||
import com.sk89q.worldedit.command.SchematicCommands;
|
||||
@ -298,6 +299,20 @@ public final class PlatformCommandManager {
|
||||
public void registerAllCommands() {
|
||||
if (Settings.IMP.ENABLED_COMPONENTS.COMMANDS) {
|
||||
// TODO NOT IMPLEMENTED dunno why these have issues generating
|
||||
registerSubCommands(
|
||||
"patterns",
|
||||
ImmutableList.of(),
|
||||
"Patterns determine what blocks are placed",
|
||||
PatternCommandsRegistration.builder(),
|
||||
new PatternCommands()
|
||||
);
|
||||
registerSubCommands(
|
||||
"transforms",
|
||||
ImmutableList.of(),
|
||||
"Transforms modify how a block is placed",
|
||||
TransformCommandsRegistration.builder(),
|
||||
new TransformCommands()
|
||||
);
|
||||
registerSubCommands(
|
||||
"schematic",
|
||||
ImmutableList.of("schem", "/schematic", "/schem"),
|
||||
@ -654,7 +669,7 @@ public final class PlatformCommandManager {
|
||||
handleCommandTask(task, context, session, event);
|
||||
}
|
||||
|
||||
public Object handleCommandTask(ThrowableSupplier<Throwable> task, InjectedValueAccess context, @Nullable LocalSession session, CommandEvent event) {
|
||||
public void handleCommandTask(ThrowableSupplier<Throwable> task, InjectedValueAccess context, @Nullable LocalSession session, CommandEvent event) {
|
||||
Request.reset();
|
||||
Actor actor = context.injectedValue(Key.of(Actor.class)).orElseThrow(() -> new IllegalStateException("No player"));
|
||||
|
||||
@ -666,7 +681,7 @@ public final class PlatformCommandManager {
|
||||
// exceptions without writing a hook into every dispatcher, we need to unwrap these
|
||||
// exceptions and rethrow their converted form, if their is one.
|
||||
try {
|
||||
return task.get();
|
||||
task.get();
|
||||
} catch (Throwable t) {
|
||||
// Use the exception converter to convert the exception if any of its causes
|
||||
// can be converted, otherwise throw the original exception
|
||||
@ -729,7 +744,6 @@ public final class PlatformCommandManager {
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
private MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor actor) {
|
||||
|
@ -41,14 +41,10 @@ import com.sk89q.worldedit.command.tool.TraceTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
|
||||
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
|
||||
import com.sk89q.worldedit.event.platform.Interaction;
|
||||
import com.sk89q.worldedit.event.platform.PlatformInitializeEvent;
|
||||
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
|
||||
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
||||
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.HandSide;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@ -321,6 +317,8 @@ public class PlatformManager {
|
||||
LocalSession session = worldEdit.getSessionManager().get(actor);
|
||||
|
||||
Request.reset();
|
||||
Request.request().setSession(session);
|
||||
Request.request().setWorld(player.getWorld());
|
||||
|
||||
try {
|
||||
Vector3 vector = location.toVector();
|
||||
@ -335,7 +333,7 @@ public class PlatformManager {
|
||||
case HIT: {
|
||||
// superpickaxe is special because its primary interaction is a left click, not a right click
|
||||
// in addition, it is implicitly bound to all pickaxe items, not just a single tool item
|
||||
if (session.hasSuperPickAxe()) {
|
||||
if (session.hasSuperPickAxe() && player.isHoldingPickAxe()) {
|
||||
final BlockTool superPickaxe = session.getSuperPickaxe();
|
||||
if (superPickaxe != null && superPickaxe.canUse(player) && player.isHoldingPickAxe()) {
|
||||
FawePlayer<?> fp = FawePlayer.wrap(player);
|
||||
|
@ -43,6 +43,7 @@ import javax.annotation.Nullable;
|
||||
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||
*/
|
||||
public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
|
||||
private final Extent extent;
|
||||
|
||||
/**
|
||||
@ -60,14 +61,19 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
*
|
||||
* @return the extent
|
||||
*/
|
||||
public final Extent getExtent() {
|
||||
public Extent getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return getBlock(position.getX(),position.getY(),position.getZ());
|
||||
}
|
||||
|
||||
/*
|
||||
Queue based methods
|
||||
TODO NOT IMPLEMENTED: IQueueExtent and such need to implement these
|
||||
*/
|
||||
Queue based methods
|
||||
TODO NOT IMPLEMENTED: IQueueExtent and such need to implement these
|
||||
*/
|
||||
public boolean isQueueEnabled() {
|
||||
return extent.isQueueEnabled();
|
||||
}
|
||||
@ -78,7 +84,8 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
if (!(extent instanceof ForgetfulExtentBuffer)) { // placeholder
|
||||
extent.disableQueue();
|
||||
}
|
||||
} catch (FaweException ignored) {}
|
||||
} catch (FaweException ignored) {
|
||||
}
|
||||
if (extent instanceof AbstractDelegateExtent) {
|
||||
Extent next = ((AbstractDelegateExtent) extent).getExtent();
|
||||
new ExtentTraverser(this).setNext(next);
|
||||
@ -108,8 +115,7 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
} else {
|
||||
history.setChangeSet(changeSet);
|
||||
}
|
||||
}
|
||||
else if (extent instanceof AbstractDelegateExtent) {
|
||||
} else if (extent instanceof AbstractDelegateExtent) {
|
||||
((AbstractDelegateExtent) extent).setChangeSet(changeSet);
|
||||
} else if (changeSet != null) {
|
||||
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
|
||||
@ -124,21 +130,12 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
/*
|
||||
Bounds
|
||||
*/
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return extent.getMinimumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMaximumPoint() {
|
||||
return extent.getMaximumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return extent.getMaxY();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Input + Output
|
||||
*/
|
||||
@ -147,7 +144,6 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return extent.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return extent.getFullBlock(x, y, z);
|
||||
@ -164,10 +160,12 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
|
||||
throws WorldEditException {
|
||||
return extent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Light
|
||||
*/
|
||||
@ -184,7 +182,6 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
}
|
||||
return getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
public int getOpacity(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getOpacity(x, y, z);
|
||||
@ -217,15 +214,21 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Generic
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + extent.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return extent.getMinimumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMaximumPoint() {
|
||||
return extent.getMaximumPoint();
|
||||
}
|
||||
|
||||
protected Operation commitBefore() {
|
||||
return null;
|
||||
}
|
||||
@ -234,7 +237,9 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
public @Nullable Operation commit() {
|
||||
Operation ours = commitBefore();
|
||||
Operation other = null;
|
||||
if (extent != this) other = extent.commit();
|
||||
if (extent != this) {
|
||||
other = extent.commit();
|
||||
}
|
||||
if (ours != null && other != null) {
|
||||
return new OperationQueue(ours, other);
|
||||
} else if (ours != null) {
|
||||
|
@ -45,8 +45,6 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public class NullExtent implements Extent {
|
||||
|
||||
public static final NullExtent INSTANCE = new NullExtent();
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return BlockVector3.ZERO;
|
||||
@ -73,6 +71,7 @@ public class NullExtent implements Extent {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
@ -19,9 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.buffer;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
@ -29,16 +31,14 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Buffers changes to an {@link Extent} and allows retrieval of the changed blocks,
|
||||
* without modifying the underlying extent.
|
||||
*/
|
||||
public class ExtentBuffer extends AbstractDelegateExtent {
|
||||
public class ExtentBuffer extends AbstractBufferingExtent {
|
||||
|
||||
private final Map<BlockVector3, BaseBlock> buffer = Maps.newHashMap();
|
||||
private final Mask mask;
|
||||
@ -66,6 +66,14 @@ public class ExtentBuffer extends AbstractDelegateExtent {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
|
||||
if (mask.test(position)) {
|
||||
return Optional.of(buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos))));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
if (mask.test(position)) {
|
||||
|
@ -61,7 +61,7 @@ public interface Clipboard extends Extent {
|
||||
|
||||
/**
|
||||
* Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)}
|
||||
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes#OCEAN} instead of {@code null}
|
||||
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes.OCEAN} instead of {@code null}
|
||||
* if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting
|
||||
* to ocean, instead of having biomes explicitly set.
|
||||
*
|
||||
|
@ -72,13 +72,27 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new IOException("This format does not support saving, use `.schem` as format");
|
||||
throw new IOException("This format does not support saving");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
String name = file.getName().toLowerCase();
|
||||
return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce");
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Materials")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
SPONGE_SCHEMATIC("sponge", "schem") {
|
||||
@ -113,8 +127,23 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
String name = file.getName().toLowerCase();
|
||||
return name.endsWith(".schem") || name.endsWith(".sponge");
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Version")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
},
|
||||
@ -149,6 +178,8 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
CompoundTag structureTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> structure = structureTag.getValue();
|
||||
if (!structure.containsKey("DataVersion")) {
|
||||
return false;
|
||||
|
@ -69,7 +69,7 @@ public class ClipboardFormats {
|
||||
checkNotNull(format);
|
||||
|
||||
for (String key : format.getAliases()) {
|
||||
String lowKey = key.toLowerCase(Locale.ROOT);
|
||||
String lowKey = key.toLowerCase(Locale.ENGLISH);
|
||||
ClipboardFormat old = aliasMap.put(lowKey, format);
|
||||
if (old != null) {
|
||||
aliasMap.put(lowKey, old);
|
||||
@ -77,7 +77,7 @@ public class ClipboardFormats {
|
||||
}
|
||||
}
|
||||
for (String ext : format.getFileExtensions()) {
|
||||
String lowExt = ext.toLowerCase(Locale.ROOT);
|
||||
String lowExt = ext.toLowerCase(Locale.ENGLISH);
|
||||
fileExtensionMap.put(lowExt, format);
|
||||
}
|
||||
registeredFormats.add(format);
|
||||
@ -99,7 +99,7 @@ public class ClipboardFormats {
|
||||
@Nullable
|
||||
public static ClipboardFormat findByAlias(String alias) {
|
||||
checkNotNull(alias);
|
||||
return aliasMap.get(alias.toLowerCase(Locale.ROOT).trim());
|
||||
return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,7 +157,7 @@ public class ClipboardFormats {
|
||||
* It is not in SchematicCommands because it may rely on internal register calls.
|
||||
*/
|
||||
public static String[] getFileExtensionArray() {
|
||||
return fileExtensionMap.keySet().toArray(new String[0]);
|
||||
return fileExtensionMap.keySet().toArray(new String[fileExtensionMap.keySet().size()]);
|
||||
}
|
||||
|
||||
private ClipboardFormats() {
|
||||
@ -259,7 +259,7 @@ public class ClipboardFormats {
|
||||
File[] files = dir.listFiles(pathname -> {
|
||||
String input = pathname.getName();
|
||||
String extension = input.substring(input.lastIndexOf('.') + 1);
|
||||
return (extensions.contains(extension.toLowerCase()));
|
||||
return (extensions.contains(extension.toLowerCase(Locale.ENGLISH)));
|
||||
});
|
||||
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
|
@ -19,10 +19,18 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.FloatTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Writes {@code Clipboard}s.
|
||||
@ -39,4 +47,18 @@ public interface ClipboardWriter extends Closeable {
|
||||
*/
|
||||
void write(Clipboard clipboard) throws IOException;
|
||||
|
||||
default Tag writeVector(Vector3 vector) {
|
||||
List<DoubleTag> list = new ArrayList<>();
|
||||
list.add(new DoubleTag(vector.getX()));
|
||||
list.add(new DoubleTag(vector.getY()));
|
||||
list.add(new DoubleTag(vector.getZ()));
|
||||
return new ListTag(DoubleTag.class, list);
|
||||
}
|
||||
|
||||
default Tag writeRotation(Location location) {
|
||||
List<FloatTag> list = new ArrayList<>();
|
||||
list.add(new FloatTag(location.getYaw()));
|
||||
list.add(new FloatTag(location.getPitch()));
|
||||
return new ListTag(FloatTag.class, list);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer.LazyReader;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
@ -31,21 +34,15 @@ import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||
import com.boydti.fawe.util.IOUtil;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -60,18 +57,16 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
import com.sk89q.worldedit.world.storage.NBTConversions;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Reads schematic files using the Sponge Schematic Specification.
|
||||
@ -174,24 +169,18 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
|
||||
/// readBiomes
|
||||
|
||||
streamer.addReader("Schematic.BlockData.#", new NBTStreamer.LazyReader() {
|
||||
@Override
|
||||
public void accept(Integer arrayLen, DataInputStream dis) {
|
||||
try (FaweOutputStream blocks = new FaweOutputStream(new LZ4BlockOutputStream(blocksOut))) {
|
||||
IOUtil.copy(dis, blocks, arrayLen);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
streamer.addReader("Schematic.BlockData.#", (LazyReader) (arrayLen, dis) -> {
|
||||
try (FaweOutputStream blocks = new FaweOutputStream(new LZ4BlockOutputStream(blocksOut))) {
|
||||
IOUtil.copy(dis, blocks, arrayLen);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
streamer.addReader("Schematic.Biomes.#", new NBTStreamer.LazyReader() {
|
||||
@Override
|
||||
public void accept(Integer arrayLen, DataInputStream dis) {
|
||||
try (FaweOutputStream biomes = new FaweOutputStream(new LZ4BlockOutputStream(biomesOut))) {
|
||||
IOUtil.copy(dis, biomes, arrayLen);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
streamer.addReader("Schematic.Biomes.#", (LazyReader) (arrayLen, dis) -> {
|
||||
try (FaweOutputStream biomes = new FaweOutputStream(new LZ4BlockOutputStream(biomesOut))) {
|
||||
IOUtil.copy(dis, biomes, arrayLen);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
streamer.addReader("Schematic.TileEntities.#", (BiConsumer<Integer, CompoundTag>) (index, value) -> {
|
||||
@ -291,6 +280,17 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
private Clipboard readVersion2(BlockArrayClipboard version1, CompoundTag schematicTag) throws IOException {
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (schematic.containsKey("BiomeData")) {
|
||||
readBiomes(version1, schematic);
|
||||
}
|
||||
if (schematic.containsKey("Entities")) {
|
||||
readEntities(version1, schematic);
|
||||
}
|
||||
return version1;
|
||||
}
|
||||
|
||||
private void readBiomes(BlockArrayClipboard clipboard, Map<String, Tag> schematic) throws IOException {
|
||||
ByteArrayTag dataTag = requireTag(schematic, "BiomeData", ByteArrayTag.class);
|
||||
IntTag maxTag = requireTag(schematic, "BiomePaletteMax", IntTag.class);
|
||||
@ -349,6 +349,36 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
}
|
||||
|
||||
private void readEntities(BlockArrayClipboard clipboard, Map<String, Tag> schematic) throws IOException {
|
||||
List<Tag> entList = requireTag(schematic, "Entities", ListTag.class).getValue();
|
||||
if (entList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (Tag et : entList) {
|
||||
if (!(et instanceof CompoundTag)) {
|
||||
continue;
|
||||
}
|
||||
CompoundTag entityTag = (CompoundTag) et;
|
||||
Map<String, Tag> tags = entityTag.getValue();
|
||||
String id = requireTag(tags, "Id", StringTag.class).getValue();
|
||||
entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build();
|
||||
|
||||
if (fixer != null) {
|
||||
entityTag = fixer.fixUp(DataFixer.FixTypes.ENTITY, entityTag, dataVersion);
|
||||
}
|
||||
|
||||
EntityType entityType = EntityTypes.get(id);
|
||||
if (entityType != null) {
|
||||
Location location = NBTConversions.toLocation(clipboard,
|
||||
requireTag(tags, "Pos", ListTag.class),
|
||||
requireTag(tags, "Rotation", ListTag.class));
|
||||
BaseEntity state = new BaseEntity(entityType, entityTag);
|
||||
clipboard.createEntity(location, state);
|
||||
} else {
|
||||
log.warn("Unknown entity when pasting schematic: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
|
@ -19,13 +19,19 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.util.IOUtil;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -34,18 +40,13 @@ import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
@ -53,13 +54,13 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
|
||||
/**
|
||||
* Writes schematic files using the Sponge schematic format.
|
||||
@ -345,21 +346,6 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
schematic.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
|
||||
}
|
||||
|
||||
private static Tag writeVector(Vector3 vector) {
|
||||
List<DoubleTag> list = new ArrayList<>();
|
||||
list.add(new DoubleTag(vector.getX()));
|
||||
list.add(new DoubleTag(vector.getY()));
|
||||
list.add(new DoubleTag(vector.getZ()));
|
||||
return new ListTag(DoubleTag.class, list);
|
||||
}
|
||||
|
||||
private static Tag writeRotation(Location location) {
|
||||
List<FloatTag> list = new ArrayList<>();
|
||||
list.add(new FloatTag(location.getYaw()));
|
||||
list.add(new FloatTag(location.getPitch()));
|
||||
return new ListTag(FloatTag.class, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
|
@ -28,14 +28,10 @@ import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Applies a {@link BlockBag} to operations.
|
||||
@ -44,7 +40,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final boolean mine;
|
||||
private int[] missingBlocks = new int[BlockTypes.size()];
|
||||
private final BlockBag blockBag;
|
||||
private BlockBag blockBag;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -52,13 +48,12 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
* @param extent the extent
|
||||
* @param blockBag the block bag
|
||||
*/
|
||||
public BlockBagExtent(Extent extent, @Nonnull BlockBag blockBag) {
|
||||
public BlockBagExtent(Extent extent, @Nullable BlockBag blockBag) {
|
||||
this(extent, blockBag, false);
|
||||
}
|
||||
|
||||
public BlockBagExtent(Extent extent, @Nonnull BlockBag blockBag, boolean mine) {
|
||||
public BlockBagExtent(Extent extent, @Nullable BlockBag blockBag, boolean mine) {
|
||||
super(extent);
|
||||
checkNotNull(blockBag);
|
||||
this.blockBag = blockBag;
|
||||
this.mine = mine;
|
||||
}
|
||||
@ -72,6 +67,14 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
return blockBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block bag.
|
||||
*
|
||||
* @param blockBag a block bag, which may be null if none is used
|
||||
*/
|
||||
public void setBlockBag(@Nullable BlockBag blockBag) {
|
||||
this.blockBag = blockBag;
|
||||
}
|
||||
/**
|
||||
* Gets the list of missing blocks and clears the list for the next
|
||||
* operation.
|
||||
|
@ -19,22 +19,24 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.TreeBasedTable;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.collection.LocatedBlockList;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A special extent that batches changes into Minecraft chunks. This helps
|
||||
@ -42,17 +44,19 @@ import java.util.TreeMap;
|
||||
* loaded repeatedly, however it does take more memory due to caching the
|
||||
* blocks.
|
||||
*/
|
||||
public class ChunkBatchingExtent extends AbstractDelegateExtent {
|
||||
public class ChunkBatchingExtent extends AbstractBufferingExtent {
|
||||
|
||||
/**
|
||||
* Comparator optimized for sorting chunks by the region file they reside
|
||||
* in. This allows for file caches to be used while loading the chunk.
|
||||
*/
|
||||
private static final Comparator<BlockVector2> REGION_OPTIMIZED_SORT =
|
||||
Comparator.comparing((BlockVector2 vec) -> vec.divide(32), BlockVector2.COMPARING_GRID_ARRANGEMENT)
|
||||
Comparator.comparing((BlockVector2 vec) -> vec.shr(5), BlockVector2.COMPARING_GRID_ARRANGEMENT)
|
||||
.thenComparing(BlockVector2.COMPARING_GRID_ARRANGEMENT);
|
||||
|
||||
private final SortedMap<BlockVector2, LocatedBlockList> batches = new TreeMap<>(REGION_OPTIMIZED_SORT);
|
||||
private final Table<BlockVector2, BlockVector3, BaseBlock> batches =
|
||||
TreeBasedTable.create(REGION_OPTIMIZED_SORT, BlockVector3.sortByCoordsYzx());
|
||||
private final Set<BlockVector3> containedBlocks = new HashSet<>();
|
||||
private boolean enabled;
|
||||
|
||||
public ChunkBatchingExtent(Extent extent) {
|
||||
@ -76,16 +80,32 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
private BlockVector2 getChunkPos(BlockVector3 location) {
|
||||
return location.shr(4).toBlockVector2();
|
||||
}
|
||||
|
||||
private BlockVector3 getInChunkPos(BlockVector3 location) {
|
||||
return BlockVector3.at(location.getX() & 15, location.getY(), location.getZ() & 15);
|
||||
}
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
if (!enabled) {
|
||||
return getExtent().setBlock(location, block);
|
||||
return setDelegateBlock(location, block);
|
||||
}
|
||||
BlockVector2 chunkPos = BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
batches.computeIfAbsent(chunkPos, k -> new LocatedBlockList()).add(location, block);
|
||||
BlockVector2 chunkPos = getChunkPos(location);
|
||||
BlockVector3 inChunkPos = getInChunkPos(location);
|
||||
batches.put(chunkPos, inChunkPos, block.toBaseBlock());
|
||||
containedBlocks.add(location);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
|
||||
if (!containedBlocks.contains(position)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(batches.get(getChunkPos(position), getInChunkPos(position)));
|
||||
}
|
||||
@Override
|
||||
protected Operation commitBefore() {
|
||||
if (!commitRequired()) {
|
||||
@ -94,17 +114,22 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent {
|
||||
return new Operation() {
|
||||
|
||||
// we get modified between create/resume -- only create this on resume to prevent CME
|
||||
private Iterator<LocatedBlockList> batchIterator;
|
||||
private Iterator<Map.Entry<BlockVector2, Map<BlockVector3, BaseBlock>>> batchIterator;
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
if (batchIterator == null) {
|
||||
batchIterator = batches.values().iterator();
|
||||
batchIterator = batches.rowMap().entrySet().iterator();
|
||||
}
|
||||
if (!batchIterator.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
new SetLocatedBlocks(getExtent(), batchIterator.next()).resume(run);
|
||||
Map.Entry<BlockVector2, Map<BlockVector3, BaseBlock>> next = batchIterator.next();
|
||||
BlockVector3 chunkOffset = next.getKey().toBlockVector3().shl(4);
|
||||
for (Map.Entry<BlockVector3, BaseBlock> block : next.getValue().entrySet()) {
|
||||
getExtent().setBlock(block.getKey().add(chunkOffset), block.getValue());
|
||||
containedBlocks.remove(block.getKey());
|
||||
}
|
||||
batchIterator.remove();
|
||||
return this;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||
@ -33,16 +33,19 @@ import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Re-orders blocks into several stages.
|
||||
*/
|
||||
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
|
||||
public class MultiStageReorder extends AbstractBufferingExtent implements ReorderingExtent {
|
||||
|
||||
private static final Map<BlockType, PlacementPriority> priorityMap = new HashMap<>();
|
||||
|
||||
@ -139,6 +142,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
|
||||
}
|
||||
|
||||
private final Set<BlockVector3> containedBlocks = new HashSet<>();
|
||||
private Map<PlacementPriority, LocatedBlockList> stages = new HashMap<>();
|
||||
|
||||
private boolean enabled;
|
||||
@ -212,7 +216,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
if (!enabled) {
|
||||
return super.setBlock(location, block);
|
||||
return setDelegateBlock(location, block);
|
||||
}
|
||||
|
||||
BlockState existing = getBlock(location);
|
||||
@ -240,9 +244,21 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
}
|
||||
|
||||
stages.get(priority).add(location, block);
|
||||
containedBlocks.add(location);
|
||||
return !existing.equalsFuzzy(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
|
||||
if (!containedBlocks.contains(position)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return stages.values().stream()
|
||||
.map(blocks -> blocks.get(position))
|
||||
.filter(Objects::nonNull)
|
||||
.findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operation commitBefore() {
|
||||
if (!commitRequired()) {
|
||||
|
@ -50,7 +50,7 @@ public class BlockReplace implements RegionFunction {
|
||||
|
||||
@Override
|
||||
public boolean apply(BlockVector3 position) throws WorldEditException {
|
||||
return pattern.apply(extent, position, position);
|
||||
return extent.setBlock(position, pattern.apply(position));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,17 +147,33 @@ public class ExtentEntityCopy implements EntityFunction {
|
||||
CompoundTag tag = state.getNbtData();
|
||||
|
||||
if (tag != null) {
|
||||
// Handle leashed entities
|
||||
Tag leashTag = tag.getValue().get("Leash");
|
||||
if (leashTag instanceof CompoundTag) {
|
||||
CompoundTag leashCompound = (CompoundTag) leashTag;
|
||||
if (leashCompound.containsKey("X")) { // leashed to a fence
|
||||
Vector3 tilePosition = Vector3.at(leashCompound.asInt("X"), leashCompound.asInt("Y"), leashCompound.asInt("Z"));
|
||||
BlockVector3 newLeash = transform.apply(tilePosition.subtract(from)).add(to).toBlockPoint();
|
||||
return new BaseEntity(state.getType(), tag.createBuilder()
|
||||
.put("Leash", leashCompound.createBuilder()
|
||||
.putInt("X", newLeash.getBlockX())
|
||||
.putInt("Y", newLeash.getBlockY())
|
||||
.putInt("Z", newLeash.getBlockZ())
|
||||
.build()
|
||||
).build());
|
||||
}
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
// Handle hanging entities (paintings, item frames, etc.)
|
||||
|
||||
boolean hasTilePosition = tag.containsKey("TileX") && tag.containsKey("TileY") && tag.containsKey("TileZ");
|
||||
boolean hasFacing = tag.containsKey("Facing");
|
||||
tag = tag.createBuilder().build();
|
||||
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
|
||||
boolean hasTilePosition = tag.containsKey("TileX") && tag.containsKey("TileY") && tag.containsKey("TileZ");
|
||||
boolean hasDirection = tag.containsKey("Direction");
|
||||
boolean hasLegacyDirection = tag.containsKey("Dir");
|
||||
boolean hasFacing = tag.containsKey("Facing");
|
||||
|
||||
if (hasTilePosition) {
|
||||
changed = true;
|
||||
|
@ -44,7 +44,7 @@ public abstract class AbstractExtentMask extends AbstractMask {
|
||||
*
|
||||
* @return the extent
|
||||
*/
|
||||
public final Extent getExtent() {
|
||||
public Extent getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,11 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A mask that tests whether a block matches a given {@link BlockCategory}, or tag.
|
||||
@ -39,7 +41,12 @@ public class BlockCategoryMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return category.contains(vector.getBlock(getExtent()));
|
||||
return category.contains(getExtent().getBlock(vector));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.NullExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -31,8 +33,17 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A mask that checks whether blocks at the given positions are matched by
|
||||
* a block in a list.
|
||||
*
|
||||
* <p>This mask checks for both an exact block type and state value match,
|
||||
* respecting fuzzy status of the BlockState.</p>
|
||||
*/
|
||||
public class BlockMask extends ABlockMask {
|
||||
|
||||
private final boolean[] ordinals;
|
||||
|
||||
public BlockMask() {
|
||||
@ -49,6 +60,10 @@ public class BlockMask extends ABlockMask {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new block mask.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param blocks a list of blocks to match
|
||||
* @deprecated NBT not supported by this mask
|
||||
*/
|
||||
@Deprecated
|
||||
@ -57,11 +72,23 @@ public class BlockMask extends ABlockMask {
|
||||
add(blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new block mask.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param block an array of blocks to match
|
||||
*/
|
||||
public BlockMask(Extent extent, BaseBlock... block) {
|
||||
this(extent, Arrays.asList(checkNotNull(block)));
|
||||
}
|
||||
|
||||
public BlockMask add(Predicate<BlockState> predicate) {
|
||||
for (int i = 0; i < ordinals.length; i++) {
|
||||
if (!ordinals[i]) {
|
||||
BlockState state = BlockTypes.states[i];
|
||||
if (state != null) ordinals[i] = predicate.test(state);
|
||||
if (state != null) {
|
||||
ordinals[i] = predicate.test(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@ -73,7 +100,9 @@ public class BlockMask extends ABlockMask {
|
||||
}
|
||||
|
||||
public BlockMask remove(BlockState... states) {
|
||||
for (BlockState state : states) ordinals[state.getOrdinal()] = false;
|
||||
for (BlockState state : states) {
|
||||
ordinals[state.getOrdinal()] = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -84,13 +113,17 @@ public class BlockMask extends ABlockMask {
|
||||
|
||||
public boolean isEmpty() {
|
||||
for (boolean value : ordinals) {
|
||||
if (value) return false;
|
||||
if (value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public BlockMask addStates(Collection<BlockState> states) {
|
||||
for (BlockState state : states) ordinals[state.getOrdinal()] = true;
|
||||
private BlockMask addStates(Collection<BlockState> states) {
|
||||
for (BlockState state : states) {
|
||||
ordinals[state.getOrdinal()] = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -99,7 +132,7 @@ public class BlockMask extends ABlockMask {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask addTypes(Collection<BlockType> types) {
|
||||
private BlockMask addTypes(Collection<BlockType> types) {
|
||||
for (BlockType type : types) {
|
||||
for (BlockState state : type.getAllStates()) {
|
||||
ordinals[state.getOrdinal()] = true;
|
||||
@ -109,6 +142,9 @@ public class BlockMask extends ABlockMask {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given blocks to the list of criteria.
|
||||
*
|
||||
* @param blocks a list of blocks
|
||||
* @deprecated NBT not supported by this mask
|
||||
*/
|
||||
@Deprecated
|
||||
@ -118,6 +154,15 @@ public class BlockMask extends ABlockMask {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given blocks to the list of criteria.
|
||||
*
|
||||
* @param block an array of blocks
|
||||
*/
|
||||
public void add(BaseBlock... block) {
|
||||
add(Arrays.asList(checkNotNull(block)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(BlockState state) {
|
||||
return ordinals[state.getOrdinal()];
|
||||
@ -156,6 +201,12 @@ public class BlockMask extends ABlockMask {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask tryOptimize() {
|
||||
int setStates = 0;
|
||||
@ -218,7 +269,11 @@ public class BlockMask extends ABlockMask {
|
||||
}
|
||||
|
||||
if (setTypes == totalTypes - 1) {
|
||||
return new InverseSingleBlockTypeMask(getExtent(), unsetType);
|
||||
if (unsetType != null) {
|
||||
return new InverseSingleBlockTypeMask(getExtent(), unsetType);
|
||||
} else {
|
||||
throw new IllegalArgumentException("unsetType cannot be null when passed to InverseSingleBlockTypeMask");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -227,7 +282,9 @@ public class BlockMask extends ABlockMask {
|
||||
@Override
|
||||
public Mask inverse() {
|
||||
boolean[] cloned = ordinals.clone();
|
||||
for (int i = 0; i < cloned.length; i++) cloned[i] = !cloned[i];
|
||||
for (int i = 0; i < cloned.length; i++) {
|
||||
cloned[i] = !cloned[i];
|
||||
}
|
||||
return new BlockMask(getExtent(), cloned);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldedit.blocks.Blocks;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -27,8 +26,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Deprecated
|
||||
public class BlockStateMask extends AbstractExtentMask {
|
||||
@ -66,4 +65,9 @@ public class BlockStateMask extends AbstractExtentMask {
|
||||
.allMatch(entry -> block.getState(entry.getKey()) == entry.getValue());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -20,15 +20,16 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A mask that checks whether blocks at the given positions are matched by
|
||||
@ -38,10 +39,8 @@ import java.util.Set;
|
||||
* use {@link BlockMask}.</p>
|
||||
* @deprecated use BlockMaskBuilder
|
||||
*/
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@Deprecated
|
||||
public final class BlockTypeMask extends AbstractExtentMask {
|
||||
public class BlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
private final boolean[] types;
|
||||
|
||||
@ -51,7 +50,7 @@ public final class BlockTypeMask extends AbstractExtentMask {
|
||||
* @param extent the extent
|
||||
* @param blocks a list of blocks to match
|
||||
*/
|
||||
public BlockTypeMask(Extent extent, Collection<BlockType> blocks) {
|
||||
public BlockTypeMask(Extent extent, @NotNull Collection<BlockType> blocks) {
|
||||
this(extent, blocks.toArray(new BlockType[0]));
|
||||
}
|
||||
|
||||
@ -61,23 +60,18 @@ public final class BlockTypeMask extends AbstractExtentMask {
|
||||
* @param extent the extent
|
||||
* @param block an array of blocks to match
|
||||
*/
|
||||
public BlockTypeMask(Extent extent, BlockType... block) {
|
||||
public BlockTypeMask(Extent extent, @NotNull BlockType... block) {
|
||||
super(extent);
|
||||
this.types = new boolean[BlockTypes.size()];
|
||||
for (BlockType type : block) this.types[type.getInternalId()] = true;
|
||||
}
|
||||
|
||||
protected BlockTypeMask(Extent extent, boolean[] types) {
|
||||
super(extent);
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given blocks to the list of criteria.
|
||||
*
|
||||
* @param blocks a list of blocks
|
||||
*/
|
||||
public void add(Collection<BlockType> blocks) {
|
||||
public void add(@NotNull Collection<BlockType> blocks) {
|
||||
checkNotNull(blocks);
|
||||
for (BlockType type : blocks) {
|
||||
add(type);
|
||||
@ -92,7 +86,7 @@ public final class BlockTypeMask extends AbstractExtentMask {
|
||||
*
|
||||
* @param block an array of blocks
|
||||
*/
|
||||
public void add(BlockType... block) {
|
||||
public void add(@NotNull BlockType... block) {
|
||||
for (BlockType type : block) {
|
||||
this.types[type.getInternalId()] = true;
|
||||
}
|
||||
@ -120,4 +114,10 @@ public final class BlockTypeMask extends AbstractExtentMask {
|
||||
return types[block.getInternalId()];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,9 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Has the criteria where the Y value of passed positions must be within
|
||||
@ -48,4 +50,9 @@ public class BoundedHeightMask extends AbstractMask {
|
||||
return vector.getY() >= minY && vector.getY() <= maxY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A mask that returns true whenever the block at the location is not
|
||||
@ -40,7 +40,13 @@ public class ExistingBlockMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return !vector.getBlock(getExtent()).getMaterial().isAir();
|
||||
return !getExtent().getBlock(vector).getBlockType().getMaterial().isAir();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
|
@ -22,17 +22,12 @@ package com.sk89q.worldedit.function.mask;
|
||||
import com.boydti.fawe.beta.DelegateFilter;
|
||||
import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.sk89q.minecraft.util.commands.Link;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Tests whether a given vector meets a criteria.
|
||||
*/
|
||||
@Link(clazz = UtilityCommands.class, value = "masks")
|
||||
public interface Mask {
|
||||
|
||||
/**
|
||||
|
@ -22,11 +22,9 @@ package com.sk89q.worldedit.function.mask;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableVector3;
|
||||
import com.sk89q.worldedit.math.noise.NoiseGenerator;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@ -87,8 +85,8 @@ public class NoiseFilter extends AbstractMask {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 v) {
|
||||
return noiseGenerator.noise(MutableVector3.get(v.getX(), v.getY(), v.getZ())) <= density;
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return noiseGenerator.noise(MutableVector3.get(vector.getX(), vector.getY(), vector.getZ())) <= density;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -63,4 +63,9 @@ public class RegionMask extends AbstractMask {
|
||||
return region.contains(vector);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SolidBlockMask extends BlockMask {
|
||||
@ -29,6 +31,13 @@ public class SolidBlockMask extends BlockMask {
|
||||
add(state -> state.getMaterial().isMovementBlocker());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
Extent extent = getExtent();
|
||||
BlockState block = extent.getBlock(vector);
|
||||
return block.getBlockType().getMaterial().isMovementBlocker();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
|
@ -19,16 +19,14 @@
|
||||
|
||||
package com.sk89q.worldedit.function.operation;
|
||||
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@ -68,13 +66,12 @@ public class ChangeSetExecutor implements Operation {
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
while (iterator.hasNext()) {
|
||||
Change change = iterator.next();
|
||||
if (type == Type.UNDO) {
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next().undo(context);
|
||||
}
|
||||
change.undo(context);
|
||||
} else {
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next().redo(context);
|
||||
change.redo(context);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -22,7 +22,6 @@ package com.sk89q.worldedit.function.operation;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.beta.IQueueExtent;
|
||||
import com.boydti.fawe.object.extent.BlockTranslateExtent;
|
||||
import com.boydti.fawe.object.extent.PositionTransformExtent;
|
||||
import com.boydti.fawe.object.function.block.BiomeCopy;
|
||||
@ -30,7 +29,6 @@ import com.boydti.fawe.object.function.block.CombinedBlockCopy;
|
||||
import com.boydti.fawe.object.function.block.SimpleBlockCopy;
|
||||
import com.boydti.fawe.util.MaskTraverser;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.entity.metadata.EntityProperties;
|
||||
@ -74,7 +72,7 @@ public class ForwardExtentCopy implements Operation {
|
||||
private int repetitions = 1;
|
||||
private Mask sourceMask = Masks.alwaysTrue();
|
||||
private boolean removingEntities;
|
||||
private boolean copyingEntities = true; // default to true for backwards compatibility, sort of // No, it's not for compatibility, it makes sense for entities to be copied and people will get annoyed if it doesn't
|
||||
private boolean copyingEntities = true; // default to true for backwards compatibility, sort of
|
||||
private boolean copyingBiomes;
|
||||
private RegionFunction sourceFunction = null;
|
||||
private Transform transform = new Identity();
|
||||
|
@ -1,18 +1,11 @@
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Link;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
/**
|
||||
* Returns a {@link BlockStateHolder} for a given position.
|
||||
* - Adapts the vector apply to integer
|
||||
*/
|
||||
@Link(clazz = UtilityCommands.class, value = "patterns")
|
||||
public interface FawePattern extends Pattern {
|
||||
//
|
||||
// @Deprecated
|
||||
|
@ -21,9 +21,7 @@ package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.sk89q.minecraft.util.commands.Link;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -32,7 +30,6 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
/**
|
||||
* Returns a {@link BlockStateHolder} for a given position.
|
||||
*/
|
||||
@Link(clazz = UtilityCommands.class, value = "patterns")
|
||||
public interface Pattern extends Filter {
|
||||
|
||||
/**
|
||||
|
@ -20,19 +20,13 @@
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Removes the waterlogged state from blocks if possible. If not possible, returns air.
|
||||
@ -42,9 +36,9 @@ public class WaterloggedRemover extends AbstractExtentPattern {
|
||||
private static SoftReference<BlockState[]> cache = new SoftReference<>(null);
|
||||
|
||||
private synchronized BlockState[] getRemap() {
|
||||
BlockState[] remap = this.cache.get();
|
||||
BlockState[] remap = cache.get();
|
||||
if (remap != null) return remap;
|
||||
this.cache = new SoftReference<>(remap = new BlockState[BlockTypes.states.length]);
|
||||
cache = new SoftReference<>(remap = new BlockState[BlockTypes.states.length]);
|
||||
|
||||
// init
|
||||
for (int i = 0; i < remap.length; i++) {
|
||||
@ -76,4 +70,4 @@ public class WaterloggedRemover extends AbstractExtentPattern {
|
||||
}
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
@ -130,7 +131,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
* Add the directions along the axes as directions to visit.
|
||||
*/
|
||||
public void addAxes() {
|
||||
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
|
||||
HashSet<BlockVector3> set = Sets.newHashSet(directions);
|
||||
set.add(BlockVector3.UNIT_MINUS_Y);
|
||||
set.add(BlockVector3.UNIT_Y);
|
||||
set.add(BlockVector3.UNIT_MINUS_X);
|
||||
@ -144,7 +145,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
* Add the diagonal directions as directions to visit.
|
||||
*/
|
||||
public void addDiagonal() {
|
||||
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
|
||||
HashSet<BlockVector3> set = Sets.newHashSet(directions);
|
||||
set.add(Direction.NORTHEAST.toBlockVector());
|
||||
set.add(Direction.SOUTHEAST.toBlockVector());
|
||||
set.add(Direction.SOUTHWEST.toBlockVector());
|
||||
@ -175,6 +176,22 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to visit the given 'to' location.
|
||||
*
|
||||
* @param from the origin block
|
||||
* @param to the block under question
|
||||
*/
|
||||
private void visit(BlockVector3 from, BlockVector3 to) {
|
||||
BlockVector3 blockVector = to;
|
||||
if (!visited.contains(blockVector)) {
|
||||
visited.add(blockVector);
|
||||
if (isVisitable(from, to)) {
|
||||
queue.add(blockVector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisited(BlockVectorSet set) {
|
||||
this.visited = set;
|
||||
}
|
||||
@ -213,11 +230,8 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
// MutableBlockVector3 mutable2 = new MutableBlockVector3();
|
||||
boolean shouldTrim = false;
|
||||
BlockVector3[] dirs = directions;
|
||||
BlockVectorSet tempQueue = new BlockVectorSet();
|
||||
BlockVectorSet chunkLoadSet = new BlockVectorSet();
|
||||
for (currentDepth = 0; !queue.isEmpty() && currentDepth <= maxDepth; currentDepth++) {
|
||||
for (BlockVector3 from : queue) {
|
||||
if (function.apply(from)) affected++;
|
||||
@ -244,9 +258,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
BlockVectorSet tmp = queue;
|
||||
queue = tempQueue;
|
||||
tmp.clear();
|
||||
chunkLoadSet.clear();
|
||||
tempQueue = tmp;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -70,17 +70,13 @@ public class RegionVisitor implements Operation {
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
for (BlockVector3 pt : iterable) {
|
||||
apply(pt);
|
||||
if (function.apply(pt)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void apply(BlockVector3 pt) throws WorldEditException {
|
||||
if (function.apply(pt)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
@ -55,7 +55,9 @@ public class BlockOptimizedHistory extends ArrayListHistory {
|
||||
if (change instanceof BlockChange) {
|
||||
BlockChange blockChange = (BlockChange) change;
|
||||
BlockVector3 position = blockChange.getPosition();
|
||||
previous.add(position, blockChange.getPrevious());
|
||||
if (!previous.containsLocation(position)) {
|
||||
previous.add(position, blockChange.getPrevious());
|
||||
}
|
||||
current.add(position, blockChange.getCurrent());
|
||||
} else {
|
||||
super.add(change);
|
||||
|
@ -19,9 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.math;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
@ -48,25 +46,31 @@ public class BlockVector2 {
|
||||
* cdef
|
||||
* </pre>
|
||||
*/
|
||||
public static final Comparator<BlockVector2> COMPARING_GRID_ARRANGEMENT = (a, b) -> {
|
||||
return ComparisonChain.start()
|
||||
.compare(a.getBlockZ(), b.getBlockZ())
|
||||
.compare(a.getBlockX(), b.getBlockX())
|
||||
.result();
|
||||
};
|
||||
public static final Comparator<BlockVector2> COMPARING_GRID_ARRANGEMENT =
|
||||
Comparator.comparingInt(BlockVector2::getZ).thenComparingInt(BlockVector2::getX);
|
||||
|
||||
public static BlockVector2 at(double x, double z) {
|
||||
return at((int) Math.floor(x), (int) Math.floor(z));
|
||||
}
|
||||
|
||||
public static BlockVector2 at(int x, int z) {
|
||||
switch (x) {
|
||||
case 0:
|
||||
if (z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new BlockVector2(x, z);
|
||||
}
|
||||
|
||||
protected int x, z;
|
||||
|
||||
protected BlockVector2(){}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
@ -342,6 +346,26 @@ public class BlockVector2 {
|
||||
return divide(n, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift all components right.
|
||||
*
|
||||
* @param x the value to shift x by
|
||||
* @param z the value to shift z by
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector2 shr(int x, int z) {
|
||||
return at(this.x >> x, this.z >> z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift all components right by {@code n}.
|
||||
*
|
||||
* @param n the value to shift by
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector2 shr(int n) {
|
||||
return shr(n, n);
|
||||
}
|
||||
/**
|
||||
* Get the length of the vector.
|
||||
*
|
||||
@ -572,4 +596,4 @@ public class BlockVector2 {
|
||||
return "(" + x + ", " + z + ")";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,12 @@ package com.sk89q.worldedit.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
@ -50,11 +48,26 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
public static BlockVector3 at(int x, int y, int z) {
|
||||
// switch for efficiency on typical cases
|
||||
// in MC y is rarely 0/1 on selections
|
||||
switch (y) {
|
||||
case 0:
|
||||
if (x == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new BlockVector3Imp(x, y, z);
|
||||
}
|
||||
|
||||
// thread-safe initialization idiom
|
||||
private static final class YzxOrderComparator {
|
||||
|
||||
private static final Comparator<BlockVector3> YZX_ORDER =
|
||||
Comparator.comparingInt(BlockVector3::getY)
|
||||
.thenComparingInt(BlockVector3::getZ)
|
||||
@ -240,8 +253,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of vectors to this vector and return the
|
||||
* result as a new vector.
|
||||
* Add a list of vectors to this vector and return the result as a new vector.
|
||||
*
|
||||
* @param others an array of vectors
|
||||
* @return a new vector
|
||||
@ -259,8 +271,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
* Subtract another vector from this vector and return the result as a new vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
@ -270,8 +281,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
* Subtract another vector from this vector and return the result as a new vector.
|
||||
*
|
||||
* @param x the value to subtract
|
||||
* @param y the value to subtract
|
||||
@ -283,8 +293,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a list of vectors from this vector and return the result
|
||||
* as a new vector.
|
||||
* Subtract a list of vectors from this vector and return the result as a new vector.
|
||||
*
|
||||
* @param others an array of vectors
|
||||
* @return a new vector
|
||||
@ -469,8 +478,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the normalized vector, which is the vector divided by its
|
||||
* length, as a new vector.
|
||||
* Get the normalized vector, which is the vector divided by its length, as a new vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
@ -514,7 +522,8 @@ public abstract class BlockVector3 {
|
||||
* @return true if the vector is contained
|
||||
*/
|
||||
public boolean containedWithin(BlockVector3 min, BlockVector3 max) {
|
||||
return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max.getZ();
|
||||
return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max
|
||||
.getY() && getZ() >= min.getZ() && getZ() <= max.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -568,8 +577,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector with the absolute values of the components of
|
||||
* this vector.
|
||||
* Returns a vector with the absolute values of the components of this vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
@ -580,15 +588,16 @@ public abstract class BlockVector3 {
|
||||
/**
|
||||
* Perform a 2D transformation on this vector and return a new one.
|
||||
*
|
||||
* @param angle in degrees
|
||||
* @param aboutX about which x coordinate to rotate
|
||||
* @param aboutZ about which z coordinate to rotate
|
||||
* @param angle in degrees
|
||||
* @param aboutX about which x coordinate to rotate
|
||||
* @param aboutZ about which z coordinate to rotate
|
||||
* @param translateX what to add after rotation
|
||||
* @param translateZ what to add after rotation
|
||||
* @return a new vector
|
||||
* @see AffineTransform another method to transform vectors
|
||||
*/
|
||||
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
|
||||
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX,
|
||||
double translateZ) {
|
||||
angle = Math.toRadians(angle);
|
||||
double x = this.getX() - aboutX;
|
||||
double z = this.getZ() - aboutZ;
|
||||
@ -599,7 +608,7 @@ public abstract class BlockVector3 {
|
||||
|
||||
return BlockVector3.at(
|
||||
x2 + aboutX + translateX,
|
||||
getY(),
|
||||
getY(),
|
||||
z2 + aboutZ + translateZ
|
||||
);
|
||||
}
|
||||
@ -646,9 +655,9 @@ public abstract class BlockVector3 {
|
||||
*/
|
||||
public BlockVector3 getMinimum(BlockVector3 v2) {
|
||||
return new BlockVector3Imp(
|
||||
Math.min(getX(), v2.getX()),
|
||||
Math.min(getY(), v2.getY()),
|
||||
Math.min(getZ(), v2.getZ())
|
||||
Math.min(getX(), v2.getX()),
|
||||
Math.min(getY(), v2.getY()),
|
||||
Math.min(getZ(), v2.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
@ -660,9 +669,9 @@ public abstract class BlockVector3 {
|
||||
*/
|
||||
public BlockVector3 getMaximum(BlockVector3 v2) {
|
||||
return new BlockVector3Imp(
|
||||
Math.max(getX(), v2.getX()),
|
||||
Math.max(getY(), v2.getY()),
|
||||
Math.max(getZ(), v2.getZ())
|
||||
Math.max(getX(), v2.getX()),
|
||||
Math.max(getY(), v2.getY()),
|
||||
Math.max(getZ(), v2.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
@ -685,7 +694,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
public boolean setFullBlock(Extent orDefault, BaseBlock block) {
|
||||
return orDefault.setBlock(this, block);
|
||||
return orDefault.setBlock(this, block);
|
||||
}
|
||||
|
||||
public boolean setBiome(Extent orDefault, BiomeType biome) {
|
||||
@ -724,11 +733,6 @@ public abstract class BlockVector3 {
|
||||
return orDefault.getBlock(getX(), getY() + y, getZ());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Adapt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a 2D vector by dropping the Y component from this vector.
|
||||
*
|
||||
@ -743,7 +747,7 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof BlockVector3)) {
|
||||
return false;
|
||||
}
|
||||
@ -752,7 +756,8 @@ public abstract class BlockVector3 {
|
||||
}
|
||||
|
||||
public final boolean equals(BlockVector3 other) {
|
||||
return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ();
|
||||
return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this
|
||||
.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,9 +2,6 @@ package com.sk89q.worldedit.math;
|
||||
|
||||
public class MutableVector2 extends Vector2 {
|
||||
|
||||
public MutableVector2() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
|
@ -3,9 +3,12 @@ package com.sk89q.worldedit.math;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
|
||||
public class MutableVector3 extends Vector3 {
|
||||
private double x,y,z;
|
||||
|
||||
private double x, y, z;
|
||||
|
||||
public MutableVector3() {
|
||||
}
|
||||
|
||||
public static MutableVector3 get(int x, int y, int z) {
|
||||
return FaweCache.MUTABLE_VECTOR3.get().setComponents(x, y, z);
|
||||
}
|
||||
|
@ -33,13 +33,24 @@ public class Vector2 {
|
||||
public static final Vector2 ONE = new Vector2(1, 1);
|
||||
|
||||
public static Vector2 at(double x, double z) {
|
||||
int xTrunc = (int) x;
|
||||
switch (xTrunc) {
|
||||
case 0:
|
||||
if (x == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new Vector2(x, z);
|
||||
}
|
||||
|
||||
protected double x, z;
|
||||
|
||||
protected Vector2(){}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
@ -491,7 +502,7 @@ public class Vector2 {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((int) x << 16) ^ ((int) z);
|
||||
return (int) x << 16 ^ (int) z;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,6 +39,21 @@ public abstract class Vector3 {
|
||||
public static final Vector3 ONE = Vector3.at(1, 1, 1);
|
||||
|
||||
public static Vector3 at(double x, double y, double z) {
|
||||
// switch for efficiency on typical cases
|
||||
// in MC y is rarely 0/1 on selections
|
||||
int yTrunc = (int) y;
|
||||
switch (yTrunc) {
|
||||
case 0:
|
||||
if (x == 0 && y == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && y == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new Vector3Impl(x, y, z);
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.Iterator;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Allows applications of Kernels onto the region's height map.
|
||||
@ -63,11 +64,11 @@ public class HeightMap {
|
||||
this(session, region, (Mask) null, false);
|
||||
}
|
||||
|
||||
public HeightMap(EditSession session, Region region, Mask mask) {
|
||||
public HeightMap(EditSession session, Region region, @Nullable Mask mask) {
|
||||
this(session, region, mask, false);
|
||||
}
|
||||
|
||||
public HeightMap(EditSession session, Region region, Mask mask, boolean layers) {
|
||||
public HeightMap(EditSession session, Region region, @Nullable Mask mask, boolean layers) {
|
||||
checkNotNull(session);
|
||||
checkNotNull(region);
|
||||
|
||||
|
@ -22,8 +22,6 @@ package com.sk89q.worldedit.math.transform;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MathUtils;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
|
@ -106,6 +106,20 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of blocks in the region.
|
||||
*
|
||||
* @return number of blocks
|
||||
*/
|
||||
@Override
|
||||
public int getArea() {
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
|
||||
return (max.getX() - min.getX() + 1) *
|
||||
(max.getY() - min.getY() + 1) *
|
||||
(max.getZ() - min.getZ() + 1);
|
||||
}
|
||||
/**
|
||||
* Get X-size.
|
||||
*
|
||||
|
@ -392,6 +392,14 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
|
||||
return position.containedWithin(min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ && y >= this.minY && y <= this.maxY;
|
||||
@ -511,14 +519,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
if (++nextZ > max.getBlockZ()) {
|
||||
nextZ = min.getBlockZ();
|
||||
if (++nextY > max.getBlockY()) {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("End of iterator") {
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
nextX = max.getBlockX();
|
||||
nextZ = max.getBlockZ();
|
||||
nextY = max.getBlockY();
|
||||
@ -546,12 +547,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
@Override
|
||||
public BlockVector2 next() {
|
||||
if (!hasNext()) throw new NoSuchElementException() {
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
BlockVector2 answer = BlockVector2.at(nextX, nextZ);
|
||||
if (++nextX > max.getBlockX()) {
|
||||
nextX = min.getBlockX();
|
||||
|
@ -293,6 +293,22 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
|
||||
minY += changeY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a point is inside this region.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
final int blockY = position.getBlockY();
|
||||
if (blockY < minY || blockY > maxY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return position.toBlockVector2().subtract(center).toVector2().divide(radius).lengthSq() <= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a point is inside this region.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
if (y < minY || y > maxY) {
|
||||
|
@ -24,17 +24,13 @@ import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a physical shape.
|
||||
|
@ -158,11 +158,11 @@ public interface RegionSelector {
|
||||
List<String> getInformationLines();
|
||||
|
||||
/**
|
||||
* Get the verticies
|
||||
* Get the vertices
|
||||
* @return
|
||||
* @throws IncompleteRegionException
|
||||
*/
|
||||
default List<BlockVector3> getVerticies() throws IncompleteRegionException {
|
||||
default List<BlockVector3> getVertices() throws IncompleteRegionException {
|
||||
return Collections.singletonList(getPrimaryPosition());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.regions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.math.transform.Identity;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Transforms another region according to a provided vector {@code Transform}.
|
||||
*
|
||||
* @see Transform
|
||||
*/
|
||||
public class TransformRegion extends AbstractRegion {
|
||||
|
||||
private final Region region;
|
||||
private Transform transform = new Identity();
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param region the region
|
||||
* @param transform the transform
|
||||
*/
|
||||
public TransformRegion(Region region, Transform transform) {
|
||||
this(null, region, transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param world the world, which may be null
|
||||
* @param region the region
|
||||
* @param transform the transform
|
||||
*/
|
||||
public TransformRegion(@Nullable World world, Region region, Transform transform) {
|
||||
super(world);
|
||||
checkNotNull(region);
|
||||
checkNotNull(transform);
|
||||
this.region = region;
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the untransformed, base region.
|
||||
*
|
||||
* @return the base region
|
||||
*/
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the transform that is applied.
|
||||
*
|
||||
* @return the transform
|
||||
*/
|
||||
public Transform getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transform that is applied.
|
||||
*
|
||||
* @param transform the transform
|
||||
*/
|
||||
public void setTransform(Transform transform) {
|
||||
checkNotNull(transform);
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return transform.apply(region.getMinimumPoint().toVector3()).toBlockPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMaximumPoint() {
|
||||
return transform.apply(region.getMaximumPoint().toVector3()).toBlockPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 getCenter() {
|
||||
return transform.apply(region.getCenter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea(); // Cannot transform this
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return getMaximumPoint().subtract(getMinimumPoint()).getBlockX() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return getMaximumPoint().subtract(getMinimumPoint()).getBlockY() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return getMaximumPoint().subtract(getMinimumPoint()).getBlockZ() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expand(BlockVector3... changes) throws RegionOperationException {
|
||||
throw new RegionOperationException("Can't expand a TransformedRegion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contract(BlockVector3... changes) throws RegionOperationException {
|
||||
throw new RegionOperationException("Can't contract a TransformedRegion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shift(BlockVector3 change) throws RegionOperationException {
|
||||
throw new RegionOperationException("Can't change a TransformedRegion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
return region.contains(transform.inverse().apply(position.toVector3()).toBlockPoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockVector2> polygonize(int maxPoints) {
|
||||
List<BlockVector2> origPoints = region.polygonize(maxPoints);
|
||||
List<BlockVector2> transformedPoints = new ArrayList<>();
|
||||
for (BlockVector2 vector : origPoints) {
|
||||
transformedPoints.add(transform.apply(vector.toVector3(0)).toVector2().toBlockPoint());
|
||||
}
|
||||
return transformedPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<BlockVector3> iterator() {
|
||||
final Iterator<BlockVector3> it = region.iterator();
|
||||
|
||||
return new Iterator<BlockVector3>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 next() {
|
||||
BlockVector3 next = it.next();
|
||||
if (next != null) {
|
||||
return transform.apply(next.toVector3()).toBlockPoint();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
it.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -278,7 +278,7 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockVector3> getVerticies() {
|
||||
public List<BlockVector3> getVertices() {
|
||||
return new ArrayList<>(region.getVertices());
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockVector3> getVerticies() {
|
||||
public List<BlockVector3> getVertices() {
|
||||
return Arrays.asList(position1, position2);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class BooleanProperty extends AbstractProperty<Boolean> {
|
||||
this(name, values, 0);
|
||||
}
|
||||
|
||||
public BooleanProperty(final String name, final List<Boolean> values, int bitOffset) {
|
||||
private BooleanProperty(final String name, final List<Boolean> values, int bitOffset) {
|
||||
super(name, values, bitOffset);
|
||||
defaultIndex = values.get(0).booleanValue() == Boolean.TRUE ? 0 : 1;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class DirectionalProperty extends AbstractProperty<Direction> {
|
||||
this(name, values, 0);
|
||||
}
|
||||
|
||||
public DirectionalProperty(final String name, final List<Direction> values, int bitOffset) {
|
||||
private DirectionalProperty(final String name, final List<Direction> values, int bitOffset) {
|
||||
super(name, values, bitOffset);
|
||||
this.map = new int[Direction.values().length];
|
||||
Arrays.fill(this.map, -1);
|
||||
|
@ -19,12 +19,9 @@
|
||||
|
||||
package com.sk89q.worldedit.registry.state;
|
||||
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class EnumProperty extends AbstractProperty<String> {
|
||||
@ -35,7 +32,7 @@ public class EnumProperty extends AbstractProperty<String> {
|
||||
this(name, values, 0);
|
||||
}
|
||||
|
||||
public EnumProperty(final String name, final List<String> values, int bitOffset) {
|
||||
private EnumProperty(final String name, final List<String> values, int bitOffset) {
|
||||
super(name, values, bitOffset);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
String value = values.get(i).intern();
|
||||
@ -51,7 +48,7 @@ public class EnumProperty extends AbstractProperty<String> {
|
||||
|
||||
@Override
|
||||
public int getIndexFor(CharSequence string) throws IllegalArgumentException {
|
||||
Integer value = offsets.get(string);
|
||||
Integer value = offsets.get(string.toString());
|
||||
return value == null ? -1 : value;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class IntegerProperty extends AbstractProperty<Integer> {
|
||||
this(name, values, 0);
|
||||
}
|
||||
|
||||
public IntegerProperty(final String name, final List<Integer> values, int bitOffset) {
|
||||
private IntegerProperty(final String name, final List<Integer> values, int bitOffset) {
|
||||
super(name, values, bitOffset);
|
||||
int max = Collections.max(values);
|
||||
this.map = new int[max + 1];
|
||||
@ -67,9 +67,10 @@ public class IntegerProperty extends AbstractProperty<Integer> {
|
||||
public Integer getValueFor(String string) {
|
||||
try {
|
||||
int val = Integer.parseInt(string);
|
||||
// if (!getValues().contains(val)) { // This check is slow
|
||||
// throw new IllegalArgumentException("Invalid int value: " + string + ". Must be in " + getValues().toString());
|
||||
// }
|
||||
//It shouldn't matter if this check is slow. It's an important check
|
||||
if (!getValues().contains(val)) {
|
||||
throw new IllegalArgumentException("Invalid int value: " + string + ". Must be in " + getValues().toString());
|
||||
}
|
||||
return val;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid int value: " + string + ". Not an int.");
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.scripting;
|
||||
|
||||
import org.mozilla.javascript.ClassShutter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Hides Minecraft's obfuscated & de-obfuscated names from scripts.
|
||||
*/
|
||||
class MinecraftHidingClassShutter implements ClassShutter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MinecraftHidingClassShutter.class);
|
||||
|
||||
@Override
|
||||
public boolean visibleToScripts(String fullClassName) {
|
||||
if (!fullClassName.contains(".")) {
|
||||
// Default package -- probably Minecraft
|
||||
return false;
|
||||
}
|
||||
return !fullClassName.startsWith("net.minecraft");
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.boydti.fawe.util.MaskTraverser;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
@ -152,7 +151,7 @@ public class PasteBuilder {
|
||||
copy.setFilterFunction(this.canApply);
|
||||
}
|
||||
if (ignoreAirBlocks) {
|
||||
sourceMask = MaskIntersection.of(sourceMask, new ExistingBlockMask(clipboard));
|
||||
sourceMask = new MaskIntersection(sourceMask, new ExistingBlockMask(clipboard));
|
||||
}
|
||||
if (targetExtent instanceof EditSession) {
|
||||
Mask esSourceMask = ((EditSession) targetExtent).getSourceMask();
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.session;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
@ -28,6 +29,8 @@ import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||
import com.sk89q.worldedit.command.tool.NavigationWand;
|
||||
import com.sk89q.worldedit.command.tool.SelectionWand;
|
||||
import com.sk89q.worldedit.command.tool.Tool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
|
||||
@ -40,10 +43,6 @@ import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@ -53,6 +52,9 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.annotation.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Session manager for WorldEdit.
|
||||
@ -162,6 +164,19 @@ public class SessionManager {
|
||||
session.setConfiguration(config);
|
||||
session.setBlockChangeLimit(config.defaultChangeLimit);
|
||||
session.setTimeout(config.calculationTimeout);
|
||||
try {
|
||||
if (owner.hasPermission("worldedit.selection.pos")) {
|
||||
setDefaultWand(session.getWandItem(), config.wandItem, session, new SelectionWand());
|
||||
}
|
||||
if (owner.hasPermission("worldedit.navigation.jumpto.tool") || owner.hasPermission("worldedit.navigation.thru.tool")) {
|
||||
setDefaultWand(session.getNavWandItem(), config.navigationWand, session, new NavigationWand());
|
||||
}
|
||||
} catch (InvalidToolBindException e) {
|
||||
if (!warnedInvalidTool) {
|
||||
warnedInvalidTool = true;
|
||||
log.warn("Invalid wand tool set in config. Tool will not be assigned: " + e.getItemType());
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the session regardless of if it's currently active or not.
|
||||
// And have the SessionTracker FLUSH inactive sessions.
|
||||
|
@ -23,66 +23,67 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.LocatedBlock;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Wrapper around a list of blocks located in the world.
|
||||
*/
|
||||
public class LocatedBlockList implements Iterable<LocatedBlock> {
|
||||
|
||||
private final List<LocatedBlock> list;
|
||||
private final Map<BlockVector3, LocatedBlock> map = new LinkedHashMap<>();
|
||||
|
||||
public LocatedBlockList() {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public LocatedBlockList(Collection<? extends LocatedBlock> collection) {
|
||||
list = new ArrayList<>(collection);
|
||||
for (LocatedBlock locatedBlock : collection) {
|
||||
map.put(locatedBlock.getLocation(), locatedBlock);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(LocatedBlock setBlockCall) {
|
||||
checkNotNull(setBlockCall);
|
||||
list.add(setBlockCall);
|
||||
map.put(setBlockCall.getLocation(), setBlockCall);
|
||||
}
|
||||
|
||||
public <B extends BlockStateHolder<B>> void add(BlockVector3 location, B block) {
|
||||
add(new LocatedBlock(location, block.toBaseBlock()));
|
||||
}
|
||||
|
||||
public boolean containsLocation(BlockVector3 location) {
|
||||
return map.containsKey(location);
|
||||
}
|
||||
|
||||
public @Nullable BaseBlock get(BlockVector3 location) {
|
||||
return map.get(location).getBlock();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
list.clear();
|
||||
map.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<LocatedBlock> iterator() {
|
||||
return list.iterator();
|
||||
return map.values().iterator();
|
||||
}
|
||||
|
||||
public Iterator<LocatedBlock> reverseIterator() {
|
||||
return new Iterator<LocatedBlock>() {
|
||||
|
||||
private final ListIterator<LocatedBlock> backingIterator = list.listIterator(list.size());
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return backingIterator.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocatedBlock next() {
|
||||
return backingIterator.previous();
|
||||
}
|
||||
};
|
||||
List<LocatedBlock> data = new ArrayList<>(map.values());
|
||||
Collections.reverse(data);
|
||||
return data.iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -284,8 +284,4 @@ public interface World extends Extent {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default World getWorld() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user