Start work on the new BaseBlock/BlockState split

This commit is contained in:
Matthew Miller 2018-06-17 15:42:47 +10:00
parent aaaf2d5678
commit c43109bde5
20 changed files with 273 additions and 268 deletions

View File

@ -1,44 +0,0 @@
/*
* 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.util;
public final class ArrayUtil {
private ArrayUtil() {
}
public static String[] removePortionOfArray(String[] array, int from, int to, String replace) {
String[] newArray = new String[from + array.length - to - (replace == null ? 1 : 0)];
System.arraycopy(array, 0, newArray, 0, from);
if (replace != null) newArray[from] = replace;
System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1),
array.length - to - 1);
return newArray;
}
public static char[] removePortionOfArray(char[] array, int from, int to, Character replace) {
char[] newArray = new char[from + array.length - to - (replace == null ? 1 : 0)];
System.arraycopy(array, 0, newArray, 0, from);
if (replace != null) newArray[from] = replace;
System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1),
array.length - to - 1);
return newArray;
}
}

View File

@ -599,21 +599,6 @@ public class EditSession implements Extent {
return bypassNone.commit();
}
/**
* Count the number of blocks of a given list of types in a region.
*
* @param region the region
* @param searchIDs a list of IDs to search
* @return the number of found blocks
*/
public int countBlock(Region region, Set<Integer> searchIDs) {
Set<BaseBlock> passOn = new HashSet<>();
for (Integer i : searchIDs) {
passOn.add(new BaseBlock(i, -1));
}
return countBlocks(region, passOn);
}
/**
* Count the number of blocks of a list of types in a region.
*

View File

@ -19,12 +19,14 @@
package com.sk89q.worldedit;
import static com.sk89q.worldedit.event.platform.Interaction.HIT;
import static com.sk89q.worldedit.event.platform.Interaction.OPEN;
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
import com.sk89q.worldedit.event.platform.InputType;
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
@ -32,7 +34,6 @@ import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.factory.ItemFactory;
import com.sk89q.worldedit.extension.factory.MaskFactory;
import com.sk89q.worldedit.extension.factory.PatternFactory;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
@ -50,23 +51,19 @@ import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData;
import javax.script.ScriptException;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.event.platform.Interaction.HIT;
import static com.sk89q.worldedit.event.platform.Interaction.OPEN;
import javax.script.ScriptException;
/**
* The entry point and container for a working implementation of WorldEdit.
@ -102,6 +99,7 @@ public class WorldEdit {
WorldEditPrefixHandler.register("com.sk89q.worldedit");
getVersion();
BundledBlockData.getInstance(); // Load block registry
BundledItemData.getInstance(); // Load item registry
}
private WorldEdit() {
@ -191,78 +189,6 @@ public class WorldEdit {
return sessions;
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)}
*/
@Deprecated
public BaseBlock getBlock(Player player, String arg, boolean allAllowed) throws WorldEditException {
return getBlock(player, arg, allAllowed, false);
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)}
*/
@Deprecated
public BaseBlock getBlock(Player player, String arg, boolean allAllowed, boolean allowNoData) throws WorldEditException {
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(getSessionManager().get(player));
context.setRestricted(!allAllowed);
context.setPreferringWildcard(allowNoData);
return getBlockFactory().parseFromInput(arg, context);
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)}
*/
@Deprecated
public BaseBlock getBlock(Player player, String id) throws WorldEditException {
return getBlock(player, id, false);
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)}
*/
@Deprecated
public Set<BaseBlock> getBlocks(Player player, String list, boolean allAllowed, boolean allowNoData) throws WorldEditException {
String[] items = list.split(",");
Set<BaseBlock> blocks = new HashSet<>();
for (String id : items) {
blocks.add(getBlock(player, id, allAllowed, allowNoData));
}
return blocks;
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)}
*/
@Deprecated
public Set<BaseBlock> getBlocks(Player player, String list, boolean allAllowed) throws WorldEditException {
return getBlocks(player, list, allAllowed, false);
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)}
*/
@Deprecated
public Set<BaseBlock> getBlocks(Player player, String list) throws WorldEditException {
return getBlocks(player, list, false);
}
/**
* @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)}
*/
@Deprecated
public Set<Integer> getBlockIDs(Player player, String list, boolean allBlocksAllowed) throws WorldEditException {
String[] items = list.split(",");
Set<Integer> blocks = new HashSet<>();
for (String s : items) {
blocks.add(getBlock(player, s, allBlocksAllowed).getType().getLegacyId());
}
return blocks;
}
/**
* Gets the path to a file. This method will check to see if the filename
* has valid characters and has an extension. It also prevents directory
@ -641,7 +567,7 @@ public class WorldEdit {
String filename = f.getPath();
int index = filename.lastIndexOf(".");
String ext = filename.substring(index + 1, filename.length());
String ext = filename.substring(index + 1);
if (!ext.equalsIgnoreCase("js")) {
player.printError("Only .js scripts are currently supported");
@ -677,7 +603,7 @@ public class WorldEdit {
LocalSession session = getSessionManager().get(player);
CraftScriptContext scriptContext = new CraftScriptContext(this, getServer(), getConfiguration(), session, player, args);
CraftScriptEngine engine = null;
CraftScriptEngine engine;
try {
engine = new RhinoCraftScriptEngine();
@ -739,20 +665,6 @@ public class WorldEdit {
return editSessionFactory;
}
/**
* @deprecated EditSessionFactories are no longer used. Please register an {@link EditSessionEvent} event
* with the event bus in order to override or catch changes to the world
*/
@Deprecated
public void setEditSessionFactory(EditSessionFactory factory) {
checkNotNull(factory);
logger.severe("Got request to set EditSessionFactory of type " +
factory.getClass().getName() + " from " + factory.getClass().getPackage().getName() +
" but EditSessionFactories have been removed in favor of extending EditSession's extents.\n\n" +
"This may mean that any block logger / intercepters addons/plugins/mods that you have installed will not " +
"intercept WorldEdit's changes! Please notify the maintainer of the other addon about this.");
}
/**
* Get the version.
*
@ -782,11 +694,4 @@ public class WorldEdit {
return version;
}
/**
* @deprecated Declare your platform version with {@link Platform#getPlatformVersion()}
*/
@Deprecated
public static void setVersion(String version) {
}
}

View File

@ -0,0 +1,114 @@
/*
* 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.blocks.type;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.sk89q.worldedit.world.registry.state.State;
import com.sk89q.worldedit.world.registry.state.value.SimpleStateValue;
import java.util.HashMap;
import java.util.Map;
/**
* An immutable class that represents the state a block can be in.
*/
public class BlockState {
private final BlockType blockType;
private final Map<State<SimpleStateValue>, SimpleStateValue> values;
// Neighbouring state table.
private Table<State<SimpleStateValue>, SimpleStateValue, BlockState> states;
BlockState(BlockType blockType) {
this.blockType = blockType;
this.values = new HashMap<>();
}
public void populate(Map<Map<State<SimpleStateValue>, SimpleStateValue>, BlockState> stateMap) {
final Table<State<SimpleStateValue>, SimpleStateValue, BlockState> states = HashBasedTable.create();
for(final Map.Entry<State<SimpleStateValue>, SimpleStateValue> entry : this.values.entrySet()) {
final State<SimpleStateValue> state = entry.getKey();
state.getValues().forEach(value -> {
if(value != entry.getValue()) {
states.put(state, value, stateMap.get(this.withValue(state, value)));
}
});
}
this.states = states.isEmpty() ? states : ArrayTable.create(states);
}
private Map<State<SimpleStateValue>, SimpleStateValue> withValue(final State<SimpleStateValue> property, final SimpleStateValue value) {
final Map<State<SimpleStateValue>, SimpleStateValue> values = Maps.newHashMap(this.values);
values.put(property, value);
return values;
}
/**
* Get the block type
*
* @return The type
*/
public BlockType getBlockType() {
return this.blockType;
}
/**
* Returns a BlockState with the given state and value applied.
*
* @param state The state
* @param value The value
* @return The modified state, or same if could not be applied
*/
public BlockState with(State<SimpleStateValue> state, SimpleStateValue value) {
BlockState result = states.get(state, value);
return result == null ? this : result;
}
/**
* Gets the value at the given state
*
* @param state The state
* @return The value
*/
public SimpleStateValue getState(State<SimpleStateValue> state) {
return this.values.get(state);
}
/**
* Internal method used for creating the initial BlockState.
*
* Sets a value. DO NOT USE THIS.
*
* @param state The state
* @param value The value
* @return The blockstate, for chaining
*/
BlockState setState(State<SimpleStateValue> state, SimpleStateValue value) {
this.values.put(state, value);
return this;
}
}

View File

@ -21,22 +21,61 @@ package com.sk89q.worldedit.blocks.type;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.function.Function;
public class BlockType {
private String id;
private BlockState defaultState;
public BlockType(String id) {
this(id, null);
}
public BlockType(String id, Function<BlockState, BlockState> values) {
// If it has no namespace, assume minecraft.
if (!id.contains(":")) {
id = "minecraft:" + id;
}
this.id = id;
this.defaultState = new BlockState(this);
if (values != null) {
this.defaultState = values.apply(this.defaultState);
}
}
/**
* Gets the ID of this block.
*
* @return The id
*/
public String getId() {
return this.id;
}
/**
* Gets the name of this block, or the ID if the name cannot be found.
*
* @return The name, or ID
*/
public String getName() {
BundledBlockData.BlockEntry entry = BundledBlockData.getInstance().findById(this.id);
if (entry == null) {
return getId();
} else {
return entry.localizedName;
}
}
/**
* Gets the default state of this block type.
*
* @return The default state
*/
public BlockState getDefaultState() {
return this.defaultState;
}
/**
* Gets the legacy ID. Needed for legacy reasons.
*

View File

@ -34,8 +34,8 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.regions.Region;
@ -624,26 +624,22 @@ public class SelectionCommands {
aliases = { "/count" },
usage = "<block>",
desc = "Counts the number of a certain type of block",
flags = "d",
min = 1,
max = 1
)
@CommandPermissions("worldedit.analysis.count")
public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
boolean useData = args.hasFlag('d');
if (args.getString(0).contains(":")) {
useData = true; //override d flag, if they specified data they want it
}
if (useData) {
Set<BaseBlock> searchBlocks = we.getBlocks(player, args.getString(0), true);
int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks);
player.print("Counted: " + count);
} else {
Set<Integer> searchIDs = we.getBlockIDs(player, args.getString(0), true);
int count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs);
player.print("Counted: " + count);
}
ParserContext context = new ParserContext();
context.setActor(player);
context.setExtent(player.getExtent());
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(false);
Set<BaseBlock> searchBlocks = we.getBlockFactory().parseFromListInput(args.getString(0), context);
int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks);
player.print("Counted: " + count);
}
@Command(
@ -662,49 +658,32 @@ public class SelectionCommands {
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
int size;
boolean useData = args.hasFlag('d');
List<Countable<Integer>> distribution = null;
List<Countable<BaseBlock>> distributionData = null;
List<Countable<BaseBlock>> distributionData;
if (args.hasFlag('c')) {
// TODO: Update for new clipboard
throw new CommandException("Needs to be re-written again");
} else {
if (useData) {
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
} else {
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()));
}
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
size = session.getSelection(player.getWorld()).getArea();
}
if ((useData && distributionData.size() <= 0)
|| (!useData && distribution.size() <= 0)) { // *Should* always be false
if (distributionData.size() <= 0) { // *Should* always be false
player.printError("No blocks counted.");
return;
}
player.print("# total blocks: " + size);
if (useData) {
for (Countable<BaseBlock> c : distributionData) {
String name = BlockType.fromID(c.getID().getId()).getName();
String str = String.format("%-7s (%.3f%%) %s #%d:%d",
String.valueOf(c.getAmount()),
c.getAmount() / (double) size * 100,
name == null ? "Unknown" : name,
c.getID().getType(), c.getID().getData());
player.print(str);
}
} else {
for (Countable<Integer> c : distribution) {
BlockType block = BlockType.fromID(c.getID());
String str = String.format("%-7s (%.3f%%) %s #%d",
String.valueOf(c.getAmount()),
c.getAmount() / (double) size * 100,
block == null ? "Unknown" : block.getName(), c.getID());
player.print(str);
}
for (Countable<BaseBlock> c : distributionData) {
String name = c.getID().getType().getName();
String str = String.format("%-7s (%.3f%%) %s #%s%s",
String.valueOf(c.getAmount()),
c.getAmount() / (double) size * 100,
name,
c.getID().getType().getId(),
c.getID().getStates());
player.print(str);
}
}

View File

@ -100,7 +100,14 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.replacer")
public void repl(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
BaseBlock targetBlock = we.getBlock(player, args.getString(0));
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(true);
context.setPreferringWildcard(false);
BaseBlock targetBlock = we.getBlockFactory().parseFromInput(args.getString(0), context);
session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock));
player.print("Block replacer tool bound to "
+ ItemType.toHeldName(player.getItemInHand()) + ".");
@ -189,8 +196,16 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.lrbuild")
public void longrangebuildtool(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
BaseBlock secondary = we.getBlock(player, args.getString(0));
BaseBlock primary = we.getBlock(player, args.getString(1));
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(true);
context.setPreferringWildcard(false);
BaseBlock secondary = we.getBlockFactory().parseFromInput(args.getString(0), context);
BaseBlock primary = we.getBlockFactory().parseFromInput(args.getString(1), context);
session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary));
player.print("Long-range building tool bound to " + ItemType.toHeldName(player.getItemInHand()) + ".");
player.print("Left-click set to " + ItemType.toName(secondary.getType().getLegacyId()) + "; right-click set to "

View File

@ -250,7 +250,14 @@ public class UtilityCommands {
@Logging(PLACEMENT)
public void removeNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
BaseBlock block = we.getBlock(player, args.getString(0), true);
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(false);
context.setPreferringWildcard(false);
BaseBlock block = we.getBlockFactory().parseFromInput(args.getString(0), context);
int size = Math.max(1, args.getInteger(1, 50));
we.checkMaxRadius(size);

View File

@ -50,7 +50,7 @@ public class AreaPickaxe implements BlockTool {
int ox = clicked.getBlockX();
int oy = clicked.getBlockY();
int oz = clicked.getBlockZ();
BlockType initialType = ((World) clicked.getExtent()).getBlock(clicked.toVector()).getType();
BlockType initialType = clicked.getExtent().getBlock(clicked.toVector()).getType();
if (initialType == BlockTypes.AIR) {
return true;
@ -72,7 +72,7 @@ public class AreaPickaxe implements BlockTool {
continue;
}
((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType.getLegacyId(), clicked.toVector().distanceSq(pos));
((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toVector().distanceSq(pos));
editSession.setBlock(pos, air);
}

View File

@ -26,7 +26,6 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.world.World;
/**
* A mode that replaces one block.
@ -66,10 +65,9 @@ public class BlockReplacer implements DoubleActionBlockTool {
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
World world = (World) clicked.getExtent();
EditSession editSession = session.createEditSession(player);
targetBlock = (editSession).getBlock(clicked.toVector());
BlockType type = BlockType.fromID(targetBlock.getType().getLegacyId());
BlockType type = targetBlock.getType().getLegacyType();
if (type != null) {
player.print("Replacer tool switched to: " + type.getName());

View File

@ -102,7 +102,7 @@ public class FloatingTreeRemover implements BlockTool {
return true;
}
Vector[] recurseDirections = {
private Vector[] recurseDirections = {
PlayerDirection.NORTH.vector(),
PlayerDirection.EAST.vector(),
PlayerDirection.SOUTH.vector(),

View File

@ -67,8 +67,8 @@ public class FloodFillTool implements BlockTool {
EditSession editSession = session.createEditSession(player);
try {
recurse(server, editSession, world, clicked.toVector().toBlockVector(),
clicked.toVector(), range, initialType.getLegacyId(), new HashSet<>());
recurse(editSession, clicked.toVector().toBlockVector(),
clicked.toVector(), range, initialType, new HashSet<>());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
@ -78,7 +78,7 @@ public class FloodFillTool implements BlockTool {
return true;
}
private void recurse(Platform server, EditSession editSession, World world, BlockVector pos, Vector origin, int size, int initialType,
private void recurse(EditSession editSession, BlockVector pos, Vector origin, int size, BlockType initialType,
Set<BlockVector> visited) throws MaxChangedBlocksException {
if (origin.distance(pos) > size || visited.contains(pos)) {
@ -87,23 +87,23 @@ public class FloodFillTool implements BlockTool {
visited.add(pos);
if (editSession.getBlock(pos).getType().getLegacyId() == initialType) {
if (editSession.getBlock(pos).getType() == initialType) {
editSession.setBlock(pos, pattern.apply(pos));
} else {
return;
}
recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(),
recurse(editSession, pos.add(1, 0, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(),
recurse(editSession, pos.add(-1, 0, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(),
recurse(editSession, pos.add(0, 0, 1).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(),
recurse(editSession, pos.add(0, 0, -1).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(),
recurse(editSession, pos.add(0, 1, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(),
recurse(editSession, pos.add(0, -1, 0).toBlockVector(),
origin, size, initialType, visited);
}

View File

@ -93,7 +93,7 @@ public class RecursivePickaxe implements BlockTool {
return;
}
world.queueBlockBreakEffect(server, pos, initialType.getLegacyId(), distanceSq);
world.queueBlockBreakEffect(server, pos, initialType, distanceSq);
editSession.setBlock(pos, air);

View File

@ -24,7 +24,7 @@ import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
@ -44,8 +44,8 @@ public class SinglePickaxe implements BlockTool {
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
World world = (World) clicked.getExtent();
final int blockType = world.getLazyBlock(clicked.toVector()).getId();
if (blockType == BlockID.BEDROCK
final BlockType blockType = world.getLazyBlock(clicked.toVector()).getType();
if (blockType == BlockTypes.BEDROCK
&& !player.canDestroyBedrock()) {
return true;
}
@ -61,7 +61,7 @@ public class SinglePickaxe implements BlockTool {
editSession.flushQueue();
}
world.playEffect(clicked.toVector(), 2001, blockType);
world.playEffect(clicked.toVector(), 2001, blockType.getLegacyId());
return true;
}

View File

@ -143,7 +143,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
}
/**
* Get an item ID from an item name or an item ID number.
* Get an item from an item name or an item ID number.
*
* @param input input to parse
* @param allAllowed true to ignore blacklists
@ -152,7 +152,14 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws DisallowedItemException
*/
public BaseBlock getBlock(String input, boolean allAllowed) throws WorldEditException {
return controller.getBlock(player, input, allAllowed);
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(!allAllowed);
context.setPreferringWildcard(false);
return controller.getBlockFactory().parseFromListInput(input, context).stream().findFirst().orElse(null);
}
/**
@ -164,7 +171,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws DisallowedItemException
*/
public BaseBlock getBlock(String id) throws WorldEditException {
return controller.getBlock(player, id, false);
return getBlock(id, false);
}
/**
@ -192,27 +199,13 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws UnknownItemException
* @throws DisallowedItemException
*/
public Set<Integer> getBlockIDs(String list, boolean allBlocksAllowed) throws WorldEditException {
return controller.getBlockIDs(player, list, allBlocksAllowed);
}
/**
* Gets the path to a file. This method will check to see if the filename
* has valid characters and has an extension. It also prevents directory
* traversal exploits by checking the root directory and the file directory.
* On success, a {@code java.io.File} object will be returned.
*
* <p>Use this method if you need to read a file from a directory.</p>
*
* @param folder sub-directory to look in
* @param filename filename (user-submitted)
* @return a file
* @throws FilenameException
*/
@Deprecated
public File getSafeFile(String folder, String filename) throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeOpenFile(player, dir, filename, null, (String[]) null);
public Set<BaseBlock> getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException {
ParserContext context = new ParserContext();
context.setActor(player);
context.setWorld(player.getWorld());
context.setSession(session);
context.setRestricted(!allBlocksAllowed);
return controller.getBlockFactory().parseFromListInput(list, context);
}
/**

View File

@ -180,7 +180,7 @@ public abstract class AbstractWorld implements World {
}
@Override
public boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority) {
public boolean queueBlockBreakEffect(Platform server, Vector position, com.sk89q.worldedit.blocks.type.BlockType blockType, double priority) {
if (taskId == -1) {
taskId = server.schedule(0, 1, () -> {
int max = Math.max(1, Math.min(30, effectQueue.size() / 3));
@ -196,7 +196,7 @@ public abstract class AbstractWorld implements World {
return false;
}
effectQueue.offer(new QueuedEffect(position, blockId, priority));
effectQueue.offer(new QueuedEffect(position, blockType, priority));
return true;
}
@ -218,17 +218,17 @@ public abstract class AbstractWorld implements World {
private class QueuedEffect implements Comparable<QueuedEffect> {
private final Vector position;
private final int blockId;
private final com.sk89q.worldedit.blocks.type.BlockType blockType;
private final double priority;
private QueuedEffect(Vector position, int blockId, double priority) {
private QueuedEffect(Vector position, com.sk89q.worldedit.blocks.type.BlockType blockType, double priority) {
this.position = position;
this.blockId = blockId;
this.blockType = blockType;
this.priority = priority;
}
public void play() {
playEffect(position, 2001, blockId);
playEffect(position, 2001, blockType.getLegacyId());
}
@Override

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
@ -262,11 +263,11 @@ public interface World extends Extent {
*
* @param server the server
* @param position the position
* @param blockId the block ID
* @param blockType the block type
* @param priority the priority
* @return true if the effect was played
*/
boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority);
boolean queueBlockBreakEffect(Platform server, Vector position, BlockType blockType, double priority);
/**
* Get the data for blocks and so on for this world.

View File

@ -98,7 +98,7 @@ public class BundledBlockData {
* @return the entry, or null
*/
@Nullable
private BlockEntry findById(String id) {
public BlockEntry findById(String id) {
// If it has no namespace, assume minecraft.
if (!id.contains(":")) {
id = "minecraft:" + id;
@ -190,10 +190,11 @@ public class BundledBlockData {
return INSTANCE;
}
private static class BlockEntry {
public static class BlockEntry {
private int legacyId;
private String id;
private String unlocalizedName;
public String localizedName;
private List<String> aliases;
private Map<String, SimpleState> states = new HashMap<>();
private SimpleBlockMaterial material = new SimpleBlockMaterial();

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.world.registry.state;
import com.sk89q.worldedit.world.registry.state.value.DirectionalStateValue;
import java.util.List;
public class DirectionalState extends SimpleState<DirectionalStateValue> {
public DirectionalState(List<DirectionalStateValue> values) {
super(values);
}
}

View File

@ -21,17 +21,24 @@ package com.sk89q.worldedit.world.registry.state;
import com.sk89q.worldedit.world.registry.state.value.SimpleStateValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SimpleState<T extends SimpleStateValue> implements State<T> {
private List<T> values = new ArrayList<>();
private List<T> values;
/**
* Creates a state with values
*
* @param values The values
*/
public SimpleState(List<T> values) {
this.values = values;
}
@Override
public List<T> getValues() {
return Collections.unmodifiableList(values);
}
}