From 2f9c7f19f504d861f0b24477bb5e2fdeb82abcbd Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Tue, 22 Jan 2019 21:59:20 +1000 Subject: [PATCH] Added support for 'rotation' BlockState values. --- .../transform/BlockTransformExtent.java | 20 +++++ .../com/sk89q/worldedit/util/Direction.java | 89 +++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index 535f32436..2f5db2bef 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.registry.state.BooleanProperty; import com.sk89q.worldedit.registry.state.DirectionalProperty; import com.sk89q.worldedit.registry.state.EnumProperty; +import com.sk89q.worldedit.registry.state.IntegerProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BaseBlock; @@ -39,6 +40,8 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.OptionalInt; import java.util.Set; import java.util.stream.Collectors; @@ -160,6 +163,23 @@ public class BlockTransformExtent extends AbstractDelegateExtent { } } } + } else if (property instanceof IntegerProperty) { + IntegerProperty intProp = (IntegerProperty) property; + if (property.getName().equals("rotation")) { + if (intProp.getValues().size() == 16) { + Optional direction = Direction.fromRotationIndex(block.getState(intProp)); + int horizontalFlags = Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL; + if (direction.isPresent()) { + Vector3 vec = getNewStateValue(Direction.valuesOf(horizontalFlags), transform, direction.get().toVector()); + if (vec != null) { + OptionalInt newRotation = Direction.findClosest(vec, horizontalFlags).toRotationIndex(); + if (newRotation.isPresent()) { + result = result.with(intProp, newRotation.getAsInt()); + } + } + } + } + } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java index 59bb6c789..dea0528d0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java @@ -24,6 +24,8 @@ import com.sk89q.worldedit.math.Vector3; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; import javax.annotation.Nullable; @@ -170,6 +172,93 @@ public enum Direction { return directions; } + /** + * Converts a rotation index into a Direction. + * + *

+ * Rotation indexes are used in BlockStates, such as sign posts. + *

+ * + * @param rotation The rotation index + * @return The direction, if applicable + */ + public static Optional fromRotationIndex(int rotation) { + switch (rotation) { + case 0: + return Optional.of(SOUTH); + case 1: + return Optional.of(SOUTH_SOUTHWEST); + case 2: + return Optional.of(SOUTHWEST); + case 3: + return Optional.of(WEST_SOUTHWEST); + case 4: + return Optional.of(WEST); + case 5: + return Optional.of(WEST_NORTHWEST); + case 6: + return Optional.of(NORTHWEST); + case 7: + return Optional.of(NORTH_NORTHWEST); + case 8: + return Optional.of(NORTH); + case 9: + return Optional.of(NORTH_NORTHEAST); + case 10: + return Optional.of(NORTHEAST); + case 11: + return Optional.of(EAST_NORTHEAST); + case 12: + return Optional.of(EAST); + case 13: + return Optional.of(EAST_SOUTHEAST); + case 14: + return Optional.of(SOUTHEAST); + case 15: + return Optional.of(SOUTH_SOUTHEAST); + } + + return Optional.empty(); + } + + public OptionalInt toRotationIndex() { + switch (this) { + case SOUTH: + return OptionalInt.of(0); + case SOUTH_SOUTHWEST: + return OptionalInt.of(1); + case SOUTHWEST: + return OptionalInt.of(2); + case WEST_SOUTHWEST: + return OptionalInt.of(3); + case WEST: + return OptionalInt.of(4); + case WEST_NORTHWEST: + return OptionalInt.of(5); + case NORTHWEST: + return OptionalInt.of(6); + case NORTH_NORTHWEST: + return OptionalInt.of(7); + case NORTH: + return OptionalInt.of(8); + case NORTH_NORTHEAST: + return OptionalInt.of(9); + case NORTHEAST: + return OptionalInt.of(10); + case EAST_NORTHEAST: + return OptionalInt.of(11); + case EAST: + return OptionalInt.of(12); + case EAST_SOUTHEAST: + return OptionalInt.of(13); + case SOUTHEAST: + return OptionalInt.of(14); + case SOUTH_SOUTHEAST: + return OptionalInt.of(15); + } + return OptionalInt.empty(); + } + /** * Flags to use with {@link #findClosest(Vector3, int)}. */