Expanded the scope of item brushes (/br apply item, /br paint item).

They now additionally take a direction in which the simulated item usage
should be facing.
Also allow the item parser to parse "hand" and "offhand" as items, to
allow platforms with NBT item support return items with NBT (since
parsing is a slightly more complex task).
This commit is contained in:
wizjany 2019-06-09 00:30:57 -04:00
parent 62e2a76d78
commit f2f9c26602
14 changed files with 287 additions and 118 deletions

View File

@ -116,7 +116,7 @@ public class MobSpawnerBlock extends BaseBlock {
@Override
public String getNbtId() {
return "MobSpawner";
return "minecraft:mob_spawner";
}
@Override
@ -154,8 +154,8 @@ public class MobSpawnerBlock extends BaseBlock {
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("MobSpawner")) {
throw new RuntimeException("'MobSpawner' tile entity expected");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals(getNbtId())) {
throw new RuntimeException(String.format("'%s' tile entity expected", getNbtId()));
}
CompoundTag spawnDataTag;
@ -169,6 +169,7 @@ public class MobSpawnerBlock extends BaseBlock {
throw new InvalidFormatException("No spawn id.");
}
this.mobType = mobType;
this.spawnData = spawnDataTag;
} catch (InvalidFormatException ignored) {
throw new RuntimeException("Invalid mob spawner data: no SpawnData and/or no Delay");
}

View File

@ -88,7 +88,7 @@ public class SignBlock extends BaseBlock {
@Override
public String getNbtId() {
return "Sign";
return "minecraft:sign";
}
@Override
@ -114,8 +114,8 @@ public class SignBlock extends BaseBlock {
text = new String[] { EMPTY, EMPTY, EMPTY, EMPTY };
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Sign")) {
throw new RuntimeException("'Sign' tile entity expected");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals(getNbtId())) {
throw new RuntimeException(String.format("'%s' tile entity expected", getNbtId()));
}
t = values.get("Text1");

View File

@ -408,15 +408,14 @@ public final class WorldEdit {
}
/**
* Get the direction vector for a player's direction. May return
* null if a direction could not be found.
* Get the direction vector for a player's direction.
*
* @param player the player
* @param dirStr the direction string
* @return a direction vector
* @throws UnknownDirectionException thrown if the direction is not known
* @throws UnknownDirectionException thrown if the direction is not known, or a relative direction is used with null player
*/
public BlockVector3 getDirection(Player player, String dirStr) throws UnknownDirectionException {
public BlockVector3 getDirection(@Nullable Player player, String dirStr) throws UnknownDirectionException {
dirStr = dirStr.toLowerCase(Locale.ROOT);
final Direction dir = getPlayerDirection(player, dirStr);
@ -429,15 +428,14 @@ public final class WorldEdit {
}
/**
* Get the direction vector for a player's direction. May return
* null if a direction could not be found.
* Get the direction vector for a player's direction.
*
* @param player the player
* @param dirStr the direction string
* @return a direction vector
* @throws UnknownDirectionException thrown if the direction is not known
* @throws UnknownDirectionException thrown if the direction is not known, or a relative direction is used with null player
*/
public BlockVector3 getDiagonalDirection(Player player, String dirStr) throws UnknownDirectionException {
public BlockVector3 getDiagonalDirection(@Nullable Player player, String dirStr) throws UnknownDirectionException {
dirStr = dirStr.toLowerCase(Locale.ROOT);
final Direction dir = getPlayerDirection(player, dirStr);
@ -450,15 +448,14 @@ public final class WorldEdit {
}
/**
* Get the direction vector for a player's direction. May return
* null if a direction could not be found.
* Get the direction vector for a player's direction.
*
* @param player the player
* @param dirStr the direction string
* @return a direction enum value
* @throws UnknownDirectionException thrown if the direction is not known
* @throws UnknownDirectionException thrown if the direction is not known, or a relative direction is used with null player
*/
private Direction getPlayerDirection(Player player, String dirStr) throws UnknownDirectionException {
private Direction getPlayerDirection(@Nullable Player player, String dirStr) throws UnknownDirectionException {
final Direction dir;
switch (dirStr.charAt(0)) {
@ -502,19 +499,19 @@ public final class WorldEdit {
case 'm': // me
case 'f': // forward
dir = player.getCardinalDirection(0);
dir = getDirectionRelative(player, 0);
break;
case 'b': // back
dir = player.getCardinalDirection(180);
dir = getDirectionRelative(player, 180);
break;
case 'l': // left
dir = player.getCardinalDirection(-90);
dir = getDirectionRelative(player, -90);
break;
case 'r': // right
dir = player.getCardinalDirection(90);
dir = getDirectionRelative(player, 90);
break;
default:
@ -523,6 +520,13 @@ public final class WorldEdit {
return dir;
}
private Direction getDirectionRelative(Player player, int yawOffset) throws UnknownDirectionException {
if (player != null) {
return player.getCardinalDirection(yawOffset);
}
throw new UnknownDirectionException("Only a player can use relative directions");
}
/**
* Flush a block bag's changes to a player.
*

View File

@ -27,17 +27,22 @@ import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.command.factory.ItemUseFactory;
import com.sk89q.worldedit.command.factory.ReplaceFactory;
import com.sk89q.worldedit.command.factory.TreeGeneratorFactory;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.PermissionCondition;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.Apply;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.CommandManagerService;
import org.enginehub.piston.CommandParameters;
@ -53,7 +58,7 @@ import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
import static org.enginehub.piston.part.CommandParts.arg;
@CommandContainer
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class ApplyBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TextComponent.of("The shape of the region"))
@ -111,11 +116,18 @@ public class ApplyBrushCommands {
name = "item",
desc = "Use an item"
)
@CommandPermissions("worldedit.brush.item")
public void item(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item) throws WorldEditException {
setApplyBrush(parameters, player, localSession, new ItemUseFactory(item));
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ", TextColor.RED, TextDecoration.BOLD)
.append("This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able," +
" and may cause strange interactions with other mods/plugins. Use at your own risk.").build());
setApplyBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}
@Command(

View File

@ -27,17 +27,22 @@ import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.command.factory.ItemUseFactory;
import com.sk89q.worldedit.command.factory.ReplaceFactory;
import com.sk89q.worldedit.command.factory.TreeGeneratorFactory;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.PermissionCondition;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.Paint;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.CommandManagerService;
import org.enginehub.piston.CommandParameters;
@ -53,7 +58,7 @@ import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
import static org.enginehub.piston.part.CommandParts.arg;
@CommandContainer
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class PaintBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TextComponent.of("The shape of the region"))
@ -117,11 +122,18 @@ public class PaintBrushCommands {
name = "item",
desc = "Use an item"
)
@CommandPermissions("worldedit.brush.item")
public void item(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item) throws WorldEditException {
setPaintBrush(parameters, player, localSession, new ItemUseFactory(item));
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ", TextColor.RED, TextDecoration.BOLD)
.append("This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able," +
" and may cause strange interactions with other mods/plugins. Use at your own risk.").build());
setPaintBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}
@Command(

View File

@ -0,0 +1,119 @@
/*
* 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.command.argument;
import com.google.auto.value.AutoAnnotation;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.MultiDirection;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.FailedConversion;
import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import javax.annotation.Nullable;
import java.util.List;
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
public abstract class AbstractDirectionConverter<D> implements ArgumentConverter<D> {
@AutoAnnotation
private static Direction direction(boolean includeDiagonals) {
return new AutoAnnotation_AbstractDirectionConverter_direction(includeDiagonals);
}
@AutoAnnotation
private static MultiDirection multiDirection(boolean includeDiagonals) {
return new AutoAnnotation_AbstractDirectionConverter_multiDirection(includeDiagonals);
}
protected static <D> void register(CommandManager commandManager, AbstractDirectionConverter<D> converter,
Class<D> keyClass, boolean includeDiagonals) {
commandManager.registerConverter(
Key.of(keyClass, direction(includeDiagonals)),
converter
);
commandManager.registerConverter(
Key.of(keyClass, multiDirection(includeDiagonals)),
CommaSeparatedValuesConverter.wrap(converter)
);
}
private static final ImmutableSet<String> ORTHOGONAL = ImmutableSet.of(
"north", "south", "east", "west", "up", "down"
);
private static final ImmutableSet<String> RELATIVE = ImmutableSet.of(
"me", "forward", "back", "left", "right"
);
private static final ImmutableSet<String> DIAGONAL = ImmutableSet.of(
"northeast", "northwest", "southeast", "southwest"
);
private final WorldEdit worldEdit;
private final boolean includeDiagonals;
private final ImmutableList<String> suggestions;
protected AbstractDirectionConverter(WorldEdit worldEdit, boolean includeDiagonals) {
this.worldEdit = worldEdit;
this.includeDiagonals = includeDiagonals;
suggestions = ImmutableList.<String>builder()
.addAll(ORTHOGONAL)
.addAll(RELATIVE)
.addAll(includeDiagonals ? DIAGONAL : ImmutableList.of())
.build();
}
@Override
public ConversionResult<D> convert(String argument, InjectedValueAccess context) {
Player player = context.injectedValue(Key.of(Player.class)).orElse(null);
try {
return SuccessfulConversion.fromSingle(convertDirection(argument, player, includeDiagonals));
} catch (Exception e) {
return FailedConversion.from(e);
}
}
protected abstract D convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException;
@Override
public Component describeAcceptableArguments() {
return TextComponent.of("`me` to use facing direction, or any "
+ (includeDiagonals ? "direction" : "non-diagonal direction"));
}
@Override
public List<String> getSuggestions(String input) {
return limitByPrefix(suggestions.stream(), input);
}
protected WorldEdit getWorldEdit() {
return worldEdit;
}
}

View File

@ -19,101 +19,37 @@
package com.sk89q.worldedit.command.argument;
import com.google.auto.value.AutoAnnotation;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.MultiDirection;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.Direction;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.FailedConversion;
import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.util.List;
import javax.annotation.Nullable;
import java.util.Optional;
import static java.util.stream.Collectors.toList;
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
public final class DirectionConverter extends AbstractDirectionConverter<Direction> {
public class DirectionConverter implements ArgumentConverter<BlockVector3> {
@AutoAnnotation
private static Direction direction(boolean includeDiagonals) {
return new AutoAnnotation_DirectionConverter_direction(includeDiagonals);
}
@AutoAnnotation
private static MultiDirection multiDirection(boolean includeDiagonals) {
return new AutoAnnotation_DirectionConverter_multiDirection(includeDiagonals);
private DirectionConverter(WorldEdit worldEdit, boolean includeDiagonals) {
super(worldEdit, includeDiagonals);
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
for (boolean includeDiagonals : new boolean[] { false, true }) {
DirectionConverter directionConverter = new DirectionConverter(worldEdit, includeDiagonals);
commandManager.registerConverter(
Key.of(BlockVector3.class, direction(includeDiagonals)),
directionConverter
);
commandManager.registerConverter(
Key.of(BlockVector3.class, multiDirection(includeDiagonals)),
CommaSeparatedValuesConverter.wrap(directionConverter)
);
}
}
private static final ImmutableSet<String> NON_DIAGONALS = ImmutableSet.of(
"north", "south", "east", "west", "up", "down"
);
private static final ImmutableSet<String> RELATIVE = ImmutableSet.of(
"me", "forward", "back", "left", "right"
);
private static final ImmutableSet<String> DIAGONALS = ImmutableSet.of(
"northeast", "northwest", "southeast", "southwest"
);
private final WorldEdit worldEdit;
private final boolean includeDiagonals;
private final ImmutableList<String> suggestions;
private DirectionConverter(WorldEdit worldEdit, boolean includeDiagonals) {
this.worldEdit = worldEdit;
this.includeDiagonals = includeDiagonals;
suggestions = ImmutableList.<String>builder()
.addAll(NON_DIAGONALS)
.addAll(RELATIVE)
.addAll(includeDiagonals ? DIAGONALS : ImmutableList.of())
.build();
}
@Override
public ConversionResult<BlockVector3> convert(String argument, InjectedValueAccess context) {
Player player = context.injectedValue(Key.of(Player.class))
.orElseThrow(() -> new IllegalStateException("No player available"));
try {
return SuccessfulConversion.fromSingle(includeDiagonals
? worldEdit.getDiagonalDirection(player, argument)
: worldEdit.getDirection(player, argument));
} catch (Exception e) {
return FailedConversion.from(e);
register(commandManager, directionConverter, Direction.class, includeDiagonals);
}
}
@Override
public Component describeAcceptableArguments() {
return TextComponent.of("`me` to use facing direction, or any "
+ (includeDiagonals ? "direction" : "non-diagonal direction"));
protected Direction convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException {
final BlockVector3 vec = includeDiagonals
? getWorldEdit().getDiagonalDirection(player, argument)
: getWorldEdit().getDirection(player, argument);
return Optional.ofNullable(Direction.findClosest(vec.toVector3(), Direction.Flag.ALL))
.orElseThrow(() -> new UnknownDirectionException(argument));
}
@Override
public List<String> getSuggestions(String input) {
return limitByPrefix(suggestions.stream(), input);
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.command.argument;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.math.BlockVector3;
import org.enginehub.piston.CommandManager;
import javax.annotation.Nullable;
public final class DirectionVectorConverter extends AbstractDirectionConverter<BlockVector3> {
private DirectionVectorConverter(WorldEdit worldEdit, boolean includeDiagonals) {
super(worldEdit, includeDiagonals);
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
for (boolean includeDiagonals : new boolean[] { false, true }) {
DirectionVectorConverter directionConverter = new DirectionVectorConverter(worldEdit, includeDiagonals);
register(commandManager, directionConverter, BlockVector3.class, includeDiagonals);
}
}
@Override
protected BlockVector3 convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException {
return includeDiagonals
? getWorldEdit().getDiagonalDirection(player, argument)
: getWorldEdit().getDirection(player, argument);
}
}

View File

@ -25,19 +25,26 @@ import com.sk89q.worldedit.function.ItemUseFunction;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
public final class ItemUseFactory implements Contextual<RegionFunction> {
private final BaseItem item;
private final Direction dir;
public ItemUseFactory(BaseItem item) {
this(item, Direction.UP);
}
public ItemUseFactory(BaseItem item, Direction dir) {
this.item = item;
this.dir = dir;
}
@Override
public RegionFunction createFromContext(EditContext input) {
World world = ((EditSession) input.getDestination()).getWorld();
return new ItemUseFunction(world, item);
return new ItemUseFunction(world, item, dir);
}
@Override

View File

@ -41,6 +41,7 @@ import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -170,9 +171,9 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
Property<Object> propertyKey = (Property<Object>) type.getPropertyMap().get(parts[0]);
if (propertyKey == null) {
if (context.getActor() != null) {
throw new NoMatchException("Unknown property " + parts[0] + " for block " + type.getName());
throw new NoMatchException("Unknown property " + parts[0] + " for block " + type.getId());
} else {
WorldEdit.logger.warn("Unknown property " + parts[0] + " for block " + type.getName());
WorldEdit.logger.warn("Unknown property " + parts[0] + " for block " + type.getId());
}
return Maps.newHashMap();
}
@ -345,7 +346,9 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
}
if (blockType == BlockTypes.SIGN || blockType == BlockTypes.WALL_SIGN) {
final BlockCategory signCategory = BlockCategory.REGISTRY.get("minecraft:signs");
if (blockType == BlockTypes.SIGN || blockType == BlockTypes.WALL_SIGN
|| signCategory != null && signCategory.contains(blockType)) {
// Allow special sign text syntax
String[] text = new String[4];
text[0] = blockAndExtraData.length > 1 ? blockAndExtraData[1] : "";

View File

@ -21,10 +21,14 @@ package com.sk89q.worldedit.extension.factory.parser;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.entity.Player;
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.internal.registry.InputParser;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
@ -65,6 +69,12 @@ public class DefaultItemParser extends InputParser<BaseItem> {
}
}
if ("hand".equalsIgnoreCase(input)) {
return getItemInHand(context.requireActor(), HandSide.MAIN_HAND);
} else if ("offhand".equalsIgnoreCase(input)) {
return getItemInHand(context.requireActor(), HandSide.OFF_HAND);
}
if (item == null) {
ItemType type = ItemTypes.get(input.toLowerCase(Locale.ROOT));
if (type != null) {
@ -79,4 +89,12 @@ public class DefaultItemParser extends InputParser<BaseItem> {
}
}
private BaseItemStack getItemInHand(Actor actor, HandSide handSide) throws InputParseException {
if (actor instanceof Player) {
return ((Player) actor).getItemInHand(handSide);
} else {
throw new InputParseException("The user is not a player!");
}
}
}

View File

@ -72,6 +72,7 @@ import com.sk89q.worldedit.command.argument.Arguments;
import com.sk89q.worldedit.command.argument.BooleanConverter;
import com.sk89q.worldedit.command.argument.CommaSeparatedValuesConverter;
import com.sk89q.worldedit.command.argument.DirectionConverter;
import com.sk89q.worldedit.command.argument.DirectionVectorConverter;
import com.sk89q.worldedit.command.argument.EntityRemoverConverter;
import com.sk89q.worldedit.command.argument.EnumConverter;
import com.sk89q.worldedit.command.argument.FactoryConverter;
@ -200,6 +201,7 @@ public final class PlatformCommandManager {
}
private void registerArgumentConverters() {
DirectionVectorConverter.register(worldEdit, commandManager);
DirectionConverter.register(worldEdit, commandManager);
FactoryConverter.register(worldEdit, commandManager);
for (int count = 2; count <= 3; count++) {

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.function;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
@ -29,14 +28,20 @@ import com.sk89q.worldedit.world.World;
public final class ItemUseFunction implements RegionFunction {
private final World world;
private final BaseItem item;
private final Direction dir;
public ItemUseFunction(World world, BaseItem item) {
this(world, item, Direction.UP);
}
public ItemUseFunction(World world, BaseItem item, Direction dir) {
this.world = world;
this.item = item;
this.dir = dir;
}
@Override
public boolean apply(BlockVector3 position) throws WorldEditException {
return world.useItem(position, item, Direction.UP);
return world.useItem(position, item, dir);
}
}

View File

@ -93,15 +93,16 @@ public final class LegacyMapper {
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
String id = blockEntry.getKey();
blockEntries.put(id, blockEntry.getValue());
final String value = blockEntry.getValue();
blockEntries.put(id, value);
try {
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(value, parserContext).toImmutableState();
blockToStringMap.put(state, id);
stringToBlockMap.put(id, state);
} catch (InputParseException e) {
boolean fixed = false;
if (fixer != null) {
String newEntry = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, blockEntry.getValue(), 1631);
String newEntry = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, value, 1631);
try {
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(newEntry, parserContext).toImmutableState();
blockToStringMap.put(state, id);
@ -111,7 +112,7 @@ public final class LegacyMapper {
}
}
if (!fixed) {
log.warn("Unknown block: " + blockEntry.getValue());
log.warn("Unknown block: " + value);
}
}
}