diff --git a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java index cde191e64..b68120948 100644 --- a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java +++ b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java @@ -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 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"); } diff --git a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java index 4cc0e5bcb..0f1811e13 100644 --- a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java +++ b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java @@ -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"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index c9e926222..fa60eb72f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -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. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java index 25c1dbdc1..67bb630bd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java @@ -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( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java index e3c92236b..ea929ec49 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java @@ -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( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/AbstractDirectionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/AbstractDirectionConverter.java new file mode 100644 index 000000000..bd2a28067 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/AbstractDirectionConverter.java @@ -0,0 +1,119 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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 implements ArgumentConverter { + + @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 void register(CommandManager commandManager, AbstractDirectionConverter converter, + Class 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 ORTHOGONAL = ImmutableSet.of( + "north", "south", "east", "west", "up", "down" + ); + private static final ImmutableSet RELATIVE = ImmutableSet.of( + "me", "forward", "back", "left", "right" + ); + private static final ImmutableSet DIAGONAL = ImmutableSet.of( + "northeast", "northwest", "southeast", "southwest" + ); + + private final WorldEdit worldEdit; + private final boolean includeDiagonals; + private final ImmutableList suggestions; + + protected AbstractDirectionConverter(WorldEdit worldEdit, boolean includeDiagonals) { + this.worldEdit = worldEdit; + this.includeDiagonals = includeDiagonals; + suggestions = ImmutableList.builder() + .addAll(ORTHOGONAL) + .addAll(RELATIVE) + .addAll(includeDiagonals ? DIAGONAL : ImmutableList.of()) + .build(); + } + + @Override + public ConversionResult 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 getSuggestions(String input) { + return limitByPrefix(suggestions.stream(), input); + } + + protected WorldEdit getWorldEdit() { + return worldEdit; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionConverter.java index 78d702aa9..22e0b2fbe 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionConverter.java @@ -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 { -public class DirectionConverter implements ArgumentConverter { - - @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 NON_DIAGONALS = ImmutableSet.of( - "north", "south", "east", "west", "up", "down" - ); - private static final ImmutableSet RELATIVE = ImmutableSet.of( - "me", "forward", "back", "left", "right" - ); - private static final ImmutableSet DIAGONALS = ImmutableSet.of( - "northeast", "northwest", "southeast", "southwest" - ); - - private final WorldEdit worldEdit; - private final boolean includeDiagonals; - private final ImmutableList suggestions; - - private DirectionConverter(WorldEdit worldEdit, boolean includeDiagonals) { - this.worldEdit = worldEdit; - this.includeDiagonals = includeDiagonals; - suggestions = ImmutableList.builder() - .addAll(NON_DIAGONALS) - .addAll(RELATIVE) - .addAll(includeDiagonals ? DIAGONALS : ImmutableList.of()) - .build(); - } - - @Override - public ConversionResult 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 getSuggestions(String input) { - return limitByPrefix(suggestions.stream(), input); - } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionVectorConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionVectorConverter.java new file mode 100644 index 000000000..1295fbceb --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/DirectionVectorConverter.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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 { + + 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); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/ItemUseFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/ItemUseFactory.java index a099a78a1..7ad8866c3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/ItemUseFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/ItemUseFactory.java @@ -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 { 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 diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 9f4402715..55a9089b0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -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 { Property propertyKey = (Property) 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 { } } - 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] : ""; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java index 450538f28..631fed2dd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java @@ -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 { } } + 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 { } } + 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!"); + } + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index 2de667d08..3086613ec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -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++) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/ItemUseFunction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/ItemUseFunction.java index 4e439f0c3..905ccd3e6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/ItemUseFunction.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/ItemUseFunction.java @@ -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); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java index d12503f19..e48444094 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java @@ -93,15 +93,16 @@ public final class LegacyMapper { for (Map.Entry 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); } } }