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 b0ecc66ae..ac6858cc5 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 @@ -30,6 +30,7 @@ import com.sk89q.worldedit.math.Vector3; 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.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BaseBlock; @@ -49,8 +50,6 @@ import javax.annotation.Nullable; */ public class BlockTransformExtent extends AbstractDelegateExtent { - private static final double RIGHT_ANGLE = Math.toRadians(90); - private final Transform transform; /** @@ -129,15 +128,48 @@ public class BlockTransformExtent extends AbstractDelegateExtent { List properties = block.getBlockType().getProperties(); - for (Property property : properties) { + for (Property property : properties) { if (property instanceof DirectionalProperty) { Direction value = (Direction) block.getState(property); if (value != null) { - Vector3 newValue = getNewStateValue((DirectionalProperty) property, transform, value.toVector()); + Vector3 newValue = getNewStateValue((List) property.getValues(), transform, value.toVector()); if (newValue != null) { changedBlock = (T) changedBlock.with(property, Direction.findClosest(newValue, Direction.Flag.ALL)); } } + } else if (property instanceof EnumProperty) { + if (property.getName().equals("axis")) { + // We have an axis - this is something we can do the rotations to :sunglasses: + Direction value = null; + switch ((String) block.getState(property)) { + case "x": + value = Direction.EAST; + break; + case "y": + value = Direction.UP; + break; + case "z": + value = Direction.NORTH; + break; + } + if (value != null) { + Vector3 newValue = getNewStateValue(Direction.valuesOf(Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL), transform, value.toVector()); + if (newValue != null) { + String axis = null; + Direction newDir = Direction.findClosest(newValue, Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL); + if (newDir == Direction.NORTH || newDir == Direction.SOUTH) { + axis = "z"; + } else if (newDir == Direction.EAST || newDir == Direction.WEST) { + axis = "x"; + } else if (newDir == Direction.UP || newDir == Direction.DOWN) { + axis = "y"; + } + if (axis != null) { + changedBlock = (T) changedBlock.with(property, axis); + } + } + } + } } } @@ -166,19 +198,19 @@ public class BlockTransformExtent extends AbstractDelegateExtent { /** * Get the new value with the transformed direction. * - * @param state the state + * @param allowedStates the allowed states * @param transform the transform * @param oldDirection the old direction to transform * @return a new state or null if none could be found */ @Nullable - private static Vector3 getNewStateValue(DirectionalProperty state, Transform transform, Vector3 oldDirection) { + private static Vector3 getNewStateValue(List allowedStates, Transform transform, Vector3 oldDirection) { Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize(); Vector3 newValue = null; double closest = -2; boolean found = false; - for (Direction v : state.getValues()) { + for (Direction v : allowedStates) { double dot = v.toVector().normalize().dot(newDirection); if (dot >= closest) { closest = dot; 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 940bbe3e6..59bb6c789 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 @@ -22,6 +22,9 @@ package com.sk89q.worldedit.util; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; +import java.util.ArrayList; +import java.util.List; + import javax.annotation.Nullable; /** @@ -150,6 +153,23 @@ public enum Direction { return closest; } + /** + * Gets all directions with the given flags. + * + * @param flags The flags + * @return The directions that fit the flags + */ + public static List valuesOf(int flags) { + List directions = new ArrayList<>(); + for (Direction direction : values()) { + if ((~flags & direction.flags) == 0) { + directions.add(direction); + } + } + + return directions; + } + /** * Flags to use with {@link #findClosest(Vector3, int)}. */