diff --git a/src/main/java/li/cil/oc2/api/util/RobotOperationSide.java b/src/main/java/li/cil/oc2/api/util/RobotOperationSide.java index b3a9694e..639db76c 100644 --- a/src/main/java/li/cil/oc2/api/util/RobotOperationSide.java +++ b/src/main/java/li/cil/oc2/api/util/RobotOperationSide.java @@ -7,21 +7,15 @@ import javax.annotation.Nullable; +import com.google.gson.annotations.SerializedName; + /** * A more restrictive version of {@link Side}, intended for robot operation APIs. */ public enum RobotOperationSide { - FRONT(Direction.SOUTH), - front(FRONT), - f(FRONT), - - UP(Direction.UP), - up(UP), - u(UP), - - DOWN(Direction.DOWN), - down(DOWN), - d(DOWN), + @SerializedName(value="front", alternate={"FRONT", "f"}) FRONT(Direction.SOUTH), + @SerializedName(value="up", alternate={"TOP", "top", "UP", "u"}) UP(Direction.UP), + @SerializedName(value="down", alternate={"BOTTOM", "bottom", "DOWN", "d"}) DOWN(Direction.DOWN), ; private final Direction direction; diff --git a/src/main/java/li/cil/oc2/api/util/Side.java b/src/main/java/li/cil/oc2/api/util/Side.java index 84c2048f..9cb23c09 100644 --- a/src/main/java/li/cil/oc2/api/util/Side.java +++ b/src/main/java/li/cil/oc2/api/util/Side.java @@ -3,12 +3,15 @@ package li.cil.oc2.api.util; import net.minecraft.core.Direction; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; -import javax.annotation.Nullable; +import com.google.gson.annotations.SerializedName; /** - * This enum indicates a side of a block device. + * This enum indicates a side of a block device. It can be either a local side (eg. {@code FRONT}) or a global side + * (eg. {@code SOUTH}. *

* It is intended to be used by {@link li.cil.oc2.api.bus.device.rpc.RPCDevice} APIs, * providing both convenience for the caller by providing a range of aliases, and also @@ -16,65 +19,169 @@ * enum at some time in the future. */ public enum Side { - DOWN(Direction.DOWN), - down(DOWN), - d(DOWN), - - UP(Direction.UP), - up(UP), - u(UP), - - NORTH(Direction.NORTH), - north(NORTH), - n(NORTH), - BACK(NORTH), - back(NORTH), - b(NORTH), - - SOUTH(Direction.SOUTH), - south(SOUTH), - s(SOUTH), - FRONT(SOUTH), - front(SOUTH), - f(SOUTH), - - WEST(Direction.WEST), - west(WEST), - w(WEST), - LEFT(WEST), - left(WEST), - l(WEST), - - EAST(Direction.EAST), - east(EAST), - e(EAST), - RIGHT(EAST), - right(EAST), - r(EAST), + // Vertical: Primarily global but also used for local + @SerializedName(value="down", alternate={"BOTTOM", "bottom", "DOWN", "d"}) DOWN(Direction.DOWN), + @SerializedName(value="up", alternate={"TOP", "top", "UP", "u"}) UP(Direction.UP), + + // Horizontal, global only + @SerializedName(value="north", alternate={"NORTH", "n"}) NORTH(Direction.NORTH), + @SerializedName(value="south", alternate={"SOUTH", "s"}) SOUTH(Direction.SOUTH), + @SerializedName(value="west", alternate={"WEST", "w"}) WEST(Direction.WEST), + @SerializedName(value="east", alternate={"EAST", "e"}) EAST(Direction.EAST), + + // Horizontal, local only + @SerializedName(value="back", alternate={"BACK", "b"}) BACK(Direction.NORTH, true), + @SerializedName(value="front", alternate={"FRONT", "f"}) FRONT(Direction.SOUTH, true), + @SerializedName(value="left", alternate={"LEFT", "l"}) LEFT(Direction.WEST, true), + @SerializedName(value="right", alternate={"RIGHT", "r"}) RIGHT(Direction.EAST, true), ; - @Nullable private final Side base; + // Static fields + public static final int VERTICAL_DIRECTION_COUNT = 2; + public static final int HORIZONTAL_DIRECTION_COUNT = 4; + public static final int GLOBAL_DIRECTION_COUNT = VERTICAL_DIRECTION_COUNT + HORIZONTAL_DIRECTION_COUNT; + + // Note: Ideally these should be calculated not hardcoded + private static final Side[] BY_LOCAL_INDEX = {DOWN, UP, BACK, FRONT, LEFT, RIGHT}; + private static final Side[] BY_GLOBAL_INDEX = {DOWN, UP, NORTH, SOUTH, WEST, EAST}; + private static final Side[] BY_LOCAL_2D_INDEX = {FRONT, LEFT, BACK, RIGHT}; + + // Instance fields private final Direction direction; + private final boolean local; + // Constructors Side(final Direction direction) { - this.base = null; - this.direction = direction; + this(direction, false); } - Side(final Side side) { - this.base = side; - this.direction = side.direction; + Side(final Direction direction, final boolean local) { + this.direction = direction; + this.local = local; } - public Direction getDirection() { + // Getters + /** + * Get the base minecraft {@link Direction} this block {@code Side} is built from. + *

+ * Note that this method does not understand rotation. If this is a relative {@code Side} (eg. {@code FRONT}), then + * the return value will only make sense for a block facing South. + * + * @return The base absolute direction this Side is built from. + */ + public Direction getBaseDirection() { return direction; } + /** + * Whether this specifies a local direction that changes with 2d orientation (eg {@code FRONT}, or a fixed global + * direction (eg {code #SOUTH}). + *

+ * Note that {@code UP} and {@code DOWN} can usually be used as local directions but are technically global. + */ + public boolean isLocal() { + return local; + } + @Override public String toString() { - return base != null ? base.toString() : super.toString(); + return super.toString().toLowerCase(); + } + + // Global/local conversions + /** + * Given a global {@link Direction}, get the corresponding global block {@code Side} + * + * @see #toGlobal(BlockState) + * @param direction A global {@link Direction} + * @return A global Side corresponding to the same direction + */ + public static Side fromGlobal(Direction direction) { + return BY_GLOBAL_INDEX[direction.get3DDataValue()]; + } + + /** + * Given a local index value, get the corresponding local block {@code Side}. This is roughly equivalent to + * {@link Direction#from3DDataValue(int)} but for local instead of global sides. + *

+ * The local index value can be used as an index into arrays for data that should be stored per local side of a + * block. The order of indices is down, up, back, front, left, right. + * + * @see #toLocalIndex(BlockState) + * @param index A number from 0-5 representing the local index of the side of a block + * @return the corresponding Side + */ + public static Side fromLocalIndex(int index) { + return BY_LOCAL_INDEX[index]; + } + + /** + * Given a block {@code Side} which might be global or local, return the equivalent local {@code Side}. As an + * example, if the {@code blockState} indicates a block facing west, then both {@code WEST} and {@code FRONT} + * would return {@code FRONT}. + * + * @param blockState The state of the local block, for converting global sides to local ones + * @return the indicated local side of the block + */ + public Side toLocal(BlockState blockState) { + if (direction.getAxis().isVertical() || local) { + // Already local + return this; + } + if (!blockState.hasProperty(HorizontalDirectionalBlock.FACING)) { + // No orientation data + return BY_LOCAL_INDEX[direction.get3DDataValue()]; + } + + final Direction facing = blockState.getValue(HorizontalDirectionalBlock.FACING); + final int index2d = direction.get2DDataValue(); + final int toLocal2d = -facing.get2DDataValue(); + final int rotatedIndex2d = (index2d + toLocal2d + HORIZONTAL_DIRECTION_COUNT) % HORIZONTAL_DIRECTION_COUNT; + return BY_LOCAL_2D_INDEX[rotatedIndex2d]; + } + + /** + * Given a block {@code Side} which might be global or local, return a local index value between 0 and 5. This is + * roughly equivalent to {@link Direction#get3DDataValue()} but for local instead of global sides. As an example, + * if the blockState indicates a block facing west, then both {@code WEST} and {@code FRONT} would return {@code 3}, + * the index for front. + *

+ * The local index value can be used as an index into arrays for data that should be stored per local side of a + * block. The order of indices is down, up, back, front, left, right. + * + * @see #fromLocalIndex(int) + * @param blockState The state of the local block, for converting global sides to local indices + * @return the indicated local index of the block + */ + public int toLocalIndex(BlockState blockState) { + return toLocal(blockState).direction.get3DDataValue(); + } + + /** + * Given a Side which might be global or local, return a global {@link Direction} representing it. As an example, if + * the {@code blockState} indicates a block facing west, then both {@code WEST} and {@code FRONT} would return + * {@link Direction#WEST}. + * + * @see #fromGlobal(Direction) + * @param blockState The state of the local block, for converting local sides to global directions + * @return the global direction corresponding to this block side + */ + public Direction toGlobal(BlockState blockState) { + if (direction.getAxis().isVertical() || !local) { + return direction; + } + if (!blockState.hasProperty(HorizontalDirectionalBlock.FACING)) { + return direction; + } + + final Direction facing = blockState.getValue(HorizontalDirectionalBlock.FACING); + final int index = direction.get2DDataValue(); + final int toGlobal = facing.get2DDataValue(); + final int rotatedIndex = (index + toGlobal) % HORIZONTAL_DIRECTION_COUNT; + return Direction.from2DDataValue(rotatedIndex); } + // Direction calculation public static Direction relativeDirection(BlockPos from, BlockPos to) { int dx = to.getX() - from.getX(); int dy = to.getY() - from.getY(); diff --git a/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java index b5578f45..2504381a 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java @@ -164,10 +164,9 @@ public LazyOptional getCapability(final Capability capability, @Nullab return optional; } - final Direction localSide = HorizontalBlockUtils.toLocal(getBlockState(), side); for (final Device device : virtualMachine.busController.getDevices()) { if (device instanceof final ICapabilityProvider capabilityProvider) { - final LazyOptional value = capabilityProvider.getCapability(capability, localSide); + final LazyOptional value = capabilityProvider.getCapability(capability, side); if (value.isPresent()) { return value; } diff --git a/src/main/java/li/cil/oc2/common/blockentity/RedstoneInterfaceBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/RedstoneInterfaceBlockEntity.java index 16908285..904c3e4a 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/RedstoneInterfaceBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/RedstoneInterfaceBlockEntity.java @@ -8,7 +8,6 @@ import li.cil.oc2.api.util.Side; import li.cil.oc2.common.Constants; import li.cil.oc2.common.integration.util.BundledRedstone; -import li.cil.oc2.common.util.HorizontalBlockUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -82,10 +81,9 @@ public void load(final CompoundTag tag) { } public int getOutputForDirection(final Direction direction) { - final Direction localDirection = HorizontalBlockUtils.toLocal(getBlockState(), direction); - assert localDirection != null; + final int localDirection = Side.fromGlobal(direction).toLocalIndex(getBlockState()); - return output[localDirection.get3DDataValue()]; + return output[localDirection]; } @Callback(name = GET_REDSTONE_INPUT) @@ -97,7 +95,7 @@ public int getRedstoneInput(@Parameter(SIDE) @Nullable final Side side) { } final BlockPos pos = getBlockPos(); - final Direction direction = HorizontalBlockUtils.toGlobal(getBlockState(), side); + final Direction direction = side.toGlobal(getBlockState()); assert direction != null; final BlockPos neighborPos = pos.relative(direction); @@ -112,7 +110,7 @@ public int getRedstoneInput(@Parameter(SIDE) @Nullable final Side side) { @Callback(name = GET_REDSTONE_OUTPUT, synchronize = false) public int getRedstoneOutput(@Parameter(SIDE) @Nullable final Side side) { if (side == null) throw new IllegalArgumentException(); - final int index = side.getDirection().get3DDataValue(); + final int index = side.toLocalIndex(getBlockState()); return output[index]; } @@ -120,7 +118,7 @@ public int getRedstoneOutput(@Parameter(SIDE) @Nullable final Side side) { @Callback(name = SET_REDSTONE_OUTPUT) public void setRedstoneOutput(@Parameter(SIDE) @Nullable final Side side, @Parameter(VALUES) final int value) { if (side == null) throw new IllegalArgumentException(); - final int index = side.getDirection().get3DDataValue(); + final int index = side.toLocalIndex(getBlockState()); final byte clampedValue = (byte) Mth.clamp(value, 0, 15); if (clampedValue == output[index]) { @@ -129,7 +127,7 @@ public void setRedstoneOutput(@Parameter(SIDE) @Nullable final Side side, @Param output[index] = clampedValue; - final Direction direction = HorizontalBlockUtils.toGlobal(getBlockState(), side); + final Direction direction = side.toGlobal(getBlockState()); if (direction != null) { notifyNeighbor(direction); } @@ -145,7 +143,7 @@ public byte[] getBundledInput(@Parameter(SIDE) @Nullable final Side side) { BundledRedstone bundledRedstone = BundledRedstone.getInstance(); if (bundledRedstone.isAvailable()) { - return bundledRedstone.getBundledInput(this.level, this.getBlockPos(), side.getDirection().getOpposite()); + return bundledRedstone.getBundledInput(this.level, this.getBlockPos(), side.toGlobal(getBlockState())); } else { return new byte[Constants.BLOCK_FACE_COUNT]; } @@ -156,7 +154,7 @@ public byte[] getBundledOutput(@Parameter(SIDE) @Nullable final Side side) { if(!ModList.get().isLoaded("projectred_transmission")) throw new IllegalStateException(); if (side == null) throw new IllegalArgumentException(); - final int index = side.getDirection().get3DDataValue(); + final int index = side.toLocalIndex(getBlockState()); return bundled_output[index]; } @@ -166,7 +164,7 @@ public void setBundledOutput(@Parameter(SIDE) @Nullable final Side side, @Parame if (side == null) throw new IllegalArgumentException(); boolean changed = false; - final int index = side.getDirection().getOpposite().get3DDataValue(); + final int index = side.toLocalIndex(getBlockState()); final byte clampedValue = (byte) Mth.clamp(value, 0, 255); final byte clampedColor = (byte) Mth.clamp(color, 0, 15); /*for (int i=0; i < values.length; i++) { @@ -183,7 +181,7 @@ public void setBundledOutput(@Parameter(SIDE) @Nullable final Side side, @Parame } if (changed) { - final Direction direction = HorizontalBlockUtils.toGlobal(getBlockState(), side); + final Direction direction = side.toGlobal(getBlockState()); if (direction != null) { notifyNeighbor(direction); } @@ -198,7 +196,7 @@ public void setBundledOutputs(@Parameter(SIDE) @Nullable final Side side, @Param if (side == null) throw new IllegalArgumentException(); boolean changed = false; - final int index = side.getDirection().getOpposite().get3DDataValue(); + final int index = side.toLocalIndex(getBlockState()); for (int i=0; i < values.length; i++) { final byte clampedValue = (byte) Mth.clamp(values[i], 0, 255); if (clampedValue != bundled_output[index][i]) { @@ -208,7 +206,7 @@ public void setBundledOutputs(@Parameter(SIDE) @Nullable final Side side, @Param } if (changed) { - final Direction direction = HorizontalBlockUtils.toGlobal(getBlockState(), side); + final Direction direction = side.toGlobal(getBlockState()); if (direction != null) { notifyNeighbor(direction); } @@ -229,7 +227,7 @@ public void getDeviceDocumentation(final DeviceVisitor visitor) { "Note that if the current output level on the specified side is not " + "zero, this will affect the measured level.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device.") + "the side may depend on the orientation of the device.") .returnValueDescription("the current received level on the specified side.") .parameterDescription(SIDE, "the side to read the input level from."); @@ -237,13 +235,13 @@ public void getDeviceDocumentation(final DeviceVisitor visitor) { .description("Get the current redstone level transmitted on the specified side. " + "This will return the value last set via setRedstoneOutput().\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device.") + "the side may depend on the orientation of the device.") .returnValueDescription("the current transmitted level on the specified side.") .parameterDescription(SIDE, "the side to read the output level from."); visitor.visitCallback(SET_REDSTONE_OUTPUT) .description("Set the new redstone level transmitted on the specified side.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device.") + "the side may depend on the orientation of the device.") .parameterDescription(SIDE, "the side to write the output level to.") .parameterDescription(VALUE, "the output level to set, will be clamped to [0, 15]."); @@ -258,14 +256,14 @@ public void getDeviceDocumentation(final DeviceVisitor visitor) { visitor.visitCallback(SET_BUNDLED_OUTPUT) .description("Set the new bundled level transmitted for a specific color on the specified side.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device.") + "the side may depend on the orientation of the device.") .parameterDescription(SIDE, "the side to write the output level to.") .parameterDescription(VALUE, "the output level to set, will be clamped to [0, 255].") .parameterDescription(COLOUR, "the colour wire this sets, as int [0, 15]"); visitor.visitCallback(SET_BUNDLED_OUTPUTS) .description("Set the new bundled levels transmitted on the specified side.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device.") + "the side may depend on the orientation of the device.") .parameterDescription(SIDE, "the side to write the output level to.") .parameterDescription(VALUES, "the output levels to set in array form, each value will be clamped to [0, 255], 16 entries."); } @@ -284,7 +282,7 @@ private void notifyNeighbor(final Direction direction) { @Nullable public byte[] getBundledSignal(Direction direction) { - final int index = direction.get3DDataValue(); + final int index = Side.fromGlobal(direction).toLocalIndex(getBlockState()); return this.bundled_output[index]; } @@ -317,6 +315,7 @@ public void neighborChanged(BlockPos fromPos) { JsonObject msg = new JsonObject(); msg.addProperty("event", "redstone"); msg.addProperty("side", ""+direction); + msg.addProperty("face", ""+Side.fromGlobal(direction).toLocal(getBlockState())); msg.addProperty("level", sl); for (var subscriber : subscribers.entrySet()) { diff --git a/src/main/java/li/cil/oc2/common/bus/device/rpc/item/RedstoneInterfaceCardItemDevice.java b/src/main/java/li/cil/oc2/common/bus/device/rpc/item/RedstoneInterfaceCardItemDevice.java index b5b04648..589cf5ed 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/rpc/item/RedstoneInterfaceCardItemDevice.java +++ b/src/main/java/li/cil/oc2/common/bus/device/rpc/item/RedstoneInterfaceCardItemDevice.java @@ -9,7 +9,6 @@ import li.cil.oc2.api.util.Side; import li.cil.oc2.common.Constants; import li.cil.oc2.common.capabilities.Capabilities; -import li.cil.oc2.common.util.HorizontalBlockUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -59,7 +58,7 @@ public RedstoneInterfaceCardItemDevice(final ItemStack identity, final BlockEnti @Override public LazyOptional getCapability(@Nonnull final Capability capability, @Nullable final Direction side) { if (capability == Capabilities.redstoneEmitter() && side != null) { - final int index = side.get3DDataValue(); + final int index = Side.fromGlobal(side).toLocalIndex(blockEntity.getBlockState()); return LazyOptional.of(() -> capabilities[index]).cast(); } @@ -89,7 +88,7 @@ public int getRedstoneInput(@Parameter(SIDE) @Nullable final Side side) { } final BlockPos pos = blockEntity.getBlockPos(); - final Direction direction = HorizontalBlockUtils.toGlobal(blockEntity.getBlockState(), side); + final Direction direction = side.toGlobal(blockEntity.getBlockState()); assert direction != null; final BlockPos neighborPos = pos.relative(direction); @@ -104,7 +103,7 @@ public int getRedstoneInput(@Parameter(SIDE) @Nullable final Side side) { @Callback(name = GET_REDSTONE_OUTPUT, synchronize = false) public int getRedstoneOutput(@Parameter(SIDE) @Nullable final Side side) { if (side == null) throw new IllegalArgumentException(); - final int index = side.getDirection().get3DDataValue(); + final int index = side.toLocalIndex(blockEntity.getBlockState()); return output[index]; } @@ -112,7 +111,7 @@ public int getRedstoneOutput(@Parameter(SIDE) @Nullable final Side side) { @Callback(name = SET_REDSTONE_OUTPUT) public void setRedstoneOutput(@Parameter(SIDE) @Nullable final Side side, @Parameter(VALUE) final int value) { if (side == null) throw new IllegalArgumentException(); - final int index = side.getDirection().get3DDataValue(); + final int index = side.toLocalIndex(blockEntity.getBlockState()); final byte clampedValue = (byte) Mth.clamp(value, 0, 15); if (clampedValue == output[index]) { @@ -121,7 +120,7 @@ public void setRedstoneOutput(@Parameter(SIDE) @Nullable final Side side, @Param output[index] = clampedValue; - final Direction direction = HorizontalBlockUtils.toGlobal(blockEntity.getBlockState(), side); + final Direction direction = side.toGlobal(blockEntity.getBlockState()); if (direction != null) { notifyNeighbor(direction); } @@ -134,7 +133,7 @@ public void getDeviceDocumentation(final DocumentedDevice.DeviceVisitor visitor) "Note that if the current output level on the specified side is not " + "zero, this will affect the measured level.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device's container.") + "the side may depend on the orientation of the device's container.") .returnValueDescription("the current received level on the specified side.") .parameterDescription(SIDE, "the side to read the input level from."); @@ -142,13 +141,13 @@ public void getDeviceDocumentation(final DocumentedDevice.DeviceVisitor visitor) .description("Get the current redstone level transmitted on the specified side. " + "This will return the value last set via setRedstoneOutput().\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device's container.") + "the side may depend on the orientation of the device's container.") .returnValueDescription("the current transmitted level on the specified side.") .parameterDescription(SIDE, "the side to read the output level from."); visitor.visitCallback(SET_REDSTONE_OUTPUT) .description("Set the new redstone level transmitted on the specified side.\n" + "Sides may be specified by name or zero-based index. Please note that " + - "the side depends on the orientation of the device's container.") + "the side may depend on the orientation of the device's container.") .parameterDescription(SIDE, "the side to write the output level to.") .parameterDescription(VALUE, "the output level to set, will be clamped to [0, 15]."); } diff --git a/src/main/java/li/cil/oc2/common/util/HorizontalBlockUtils.java b/src/main/java/li/cil/oc2/common/util/HorizontalBlockUtils.java deleted file mode 100644 index 8a82d3f5..00000000 --- a/src/main/java/li/cil/oc2/common/util/HorizontalBlockUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -package li.cil.oc2.common.util; - -import li.cil.oc2.api.util.Side; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.HorizontalDirectionalBlock; -import net.minecraft.world.level.block.state.BlockState; - -import javax.annotation.Nullable; - -public final class HorizontalBlockUtils { - public static final int HORIZONTAL_DIRECTION_COUNT = 4; - - /////////////////////////////////////////////////////////////////// - - @Nullable - public static Direction toLocal(final BlockState blockState, @Nullable final Direction direction) { - if (direction == null) { - return null; - } - - if (direction.getAxis().isVertical()) { - return direction; - } - if (!blockState.hasProperty(HorizontalDirectionalBlock.FACING)) { - return direction; - } - - final Direction facing = blockState.getValue(HorizontalDirectionalBlock.FACING); - final int index = direction.get2DDataValue(); - final int toLocal = -facing.get2DDataValue(); - final int rotatedIndex = (index + toLocal + HORIZONTAL_DIRECTION_COUNT) % HORIZONTAL_DIRECTION_COUNT; - return Direction.from2DDataValue(rotatedIndex); - } - - @Nullable - public static Direction toGlobal(final BlockState blockState, @Nullable final Side side) { - if (side == null) { - return null; - } - - final Direction direction = side.getDirection(); - if (direction.getAxis().isVertical()) { - return direction; - } - if (!blockState.hasProperty(HorizontalDirectionalBlock.FACING)) { - return direction; - } - - final Direction facing = blockState.getValue(HorizontalDirectionalBlock.FACING); - final int index = direction.get2DDataValue(); - final int toGlobal = facing.get2DDataValue(); - final int rotatedIndex = (index + toGlobal) % HORIZONTAL_DIRECTION_COUNT; - return Direction.from2DDataValue(rotatedIndex); - } -} diff --git a/src/main/resources/assets/oc2r/doc/en_us/block/redstone_interface.md b/src/main/resources/assets/oc2r/doc/en_us/block/redstone_interface.md index e2d964b4..4c7869e4 100644 --- a/src/main/resources/assets/oc2r/doc/en_us/block/redstone_interface.md +++ b/src/main/resources/assets/oc2r/doc/en_us/block/redstone_interface.md @@ -14,14 +14,17 @@ This is a high level device. It must be controlled using the high level device A Device name: *redstone* ### Sides -The side parameter in the following methods represents a side local to the device block. Valid values are: *up*, *down*, *left*, *right*, *front*, *back*, *north*, *south*, *west* and *east*. - -Each face of the block has an indicator for convenience. Side names represent the names with the block seen from the primary face (indicated by a single marking). When looking at the primary face: -- *front* and *south* is the face we are looking at. -- *back* and *north* is the face behind the block. -- *left* and *west* is the face to our left. -- *right* and *east* is the face to our right. -- *up* and *down* are the top and bottom faces. +The side parameter in the following methods represents a side of the device block. The valid values are listed below. +Some variations of these names, such as just using the first letter, also work, as do the numbers 0 through 9 for the +sides *down*, *up*, *north*, *south*, *west*, *east*, *back*, *front*, *left*, and *right* in that order. + +Each face of the block has an indicator for convenience. Local side names represent the names with the block seen from the primary face (indicated by a single marking). When looking at the primary face: +- *front* is the face we are looking at (small dot). +- *back* is the face behind the block (a line and a dot). +- *left* is the face to our left (one line). +- *right* is the face to our right (two lines). +- *up* and *down* are the top and bottom faces (four dots on top, and no marking on bottom). +- *north*, *south*, *west*, and *east* are the sides in those absolute directions. ### Methods *getRedstoneInput(side):number* gets the received redstone signal for the specified side.