From 1a5dc92bd4185088be2beac4920f2b13f46090ff Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 17 Mar 2024 00:18:27 +0000 Subject: [PATCH] Some more cleanup to wired modems - Remove "initial connections" flag, and just refresh connections + peripherals on the first tick. - Remove "peripheral attached" from NBT, and just read/write it from the block state. This might cause issues with #1010, but that's sufficiently old I hope it won't! --- .../blocks/AbstractComputerBlockEntity.java | 4 +- .../modem/wired/CableBlockEntity.java | 107 ++++-------- .../modem/wired/CableModemVariant.java | 74 ++++---- .../wired/WiredModemFullBlockEntity.java | 162 ++++++++---------- .../shared/util/DirectionUtil.java | 16 ++ .../modem_test.gains_peripherals.snbt | 8 +- .../modem_test.have_peripherals.snbt | 8 +- 7 files changed, 171 insertions(+), 208 deletions(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java index cbe3c5827..cd7b27d14 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java @@ -122,7 +122,7 @@ protected void serverTick() { // Update any peripherals that have changed. if (invalidSides != 0) { for (var direction : DirectionUtil.FACINGS) { - if ((invalidSides & (1 << direction.ordinal())) != 0) refreshPeripheral(computer, direction); + if (DirectionUtil.isSet(invalidSides, direction)) refreshPeripheral(computer, direction); } } @@ -294,7 +294,7 @@ public void neighborChanged(BlockPos neighbour) { // If the position is not any adjacent one, update all inputs. This is pretty terrible, but some redstone mods // handle this incorrectly. for (var dir : DirectionUtil.FACINGS) updateRedstoneInput(computer, dir, getBlockPos().relative(dir)); - invalidSides = (1 << 6) - 1; // Mark all peripherals as dirty. + invalidSides = DirectionUtil.ALL_SIDES; // Mark all peripherals as dirty. } /** diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java index b4a6029bb..2605eeae1 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java @@ -29,12 +29,9 @@ import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; -import java.util.Map; import java.util.Objects; public class CableBlockEntity extends BlockEntity { - private static final String NBT_PERIPHERAL_ENABLED = "PeripheralAccess"; - private final class CableElement extends WiredModemElement { @Override public Level getLevel() { @@ -57,13 +54,11 @@ protected void detachPeripheral(String name) { } } - private boolean invalidPeripheral; - private boolean peripheralAccessAllowed; + private boolean refreshPeripheral; private final WiredModemLocalPeripheral peripheral = new WiredModemLocalPeripheral(PlatformHelper.get().createPeripheralAccess(this, x -> queueRefreshPeripheral())); private @Nullable Runnable modemChanged; - private boolean connectionsFormed = false; - private boolean connectionsChanged = false; + private boolean refreshConnections = false; private final WiredModemElement cable = new CableElement(); private final WiredNode node = cable.getNode(); @@ -83,23 +78,17 @@ public CableBlockEntity(BlockEntityType type, BlockP super(type, pos, state); } - private void onRemove() { - if (level == null || !level.isClientSide) { - node.remove(); - connectionsFormed = false; - } - } - @Override public void setRemoved() { super.setRemoved(); modem.removed(); - onRemove(); + if (level == null || !level.isClientSide) node.remove(); } @Override public void clearRemoved() { super.clearRemoved(); + refreshConnections = refreshPeripheral = true; TickScheduler.schedule(tickToken); } @@ -142,25 +131,17 @@ void neighborChanged(BlockPos neighbour) { return; } - if (!level.isClientSide && peripheralAccessAllowed) { + if (!level.isClientSide && isPeripheralOn()) { var facing = getDirection(); if (getBlockPos().relative(facing).equals(neighbour)) queueRefreshPeripheral(); } } private void queueRefreshPeripheral() { - if (invalidPeripheral) return; - invalidPeripheral = true; + refreshPeripheral = true; TickScheduler.schedule(tickToken); } - private void refreshPeripheral() { - invalidPeripheral = false; - if (level != null && !isRemoved() && peripheral.attach(level, getBlockPos(), getDirection())) { - updateConnectedPeripherals(); - } - } - InteractionResult use(Player player) { if (player.isCrouching() || !player.mayBuild()) return InteractionResult.PASS; if (!canAttachPeripheral()) return InteractionResult.FAIL; @@ -168,8 +149,13 @@ InteractionResult use(Player player) { if (getLevel().isClientSide) return InteractionResult.SUCCESS; var oldName = peripheral.getConnectedName(); - togglePeripheralAccess(); + if (isPeripheralOn()) { + detachPeripheral(); + } else { + attachPeripheral(); + } var newName = peripheral.getConnectedName(); + if (!Objects.equals(newName, oldName)) { if (oldName != null) { player.displayClientMessage(Component.translatable("chat.computercraft.wired_modem.peripheral_disconnected", @@ -187,14 +173,11 @@ InteractionResult use(Player player) { @Override public void load(CompoundTag nbt) { super.load(nbt); - // Fallback to the previous (incorrect) key - peripheralAccessAllowed = nbt.getBoolean(NBT_PERIPHERAL_ENABLED) || nbt.getBoolean("PeirpheralAccess"); peripheral.read(nbt, ""); } @Override public void saveAdditional(CompoundTag nbt) { - nbt.putBoolean(NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed); peripheral.write(nbt, ""); super.saveAdditional(nbt); } @@ -203,7 +186,7 @@ private void updateBlockState() { var state = getBlockState(); var oldVariant = state.getValue(CableBlock.MODEM); var newVariant = CableModemVariant - .from(oldVariant.getFacing(), modem.getModemState().isOpen(), peripheralAccessAllowed); + .from(oldVariant.getFacing(), modem.getModemState().isOpen(), peripheral.hasPeripheral()); if (oldVariant != newVariant) { level.setBlockAndUpdate(getBlockPos(), state.setValue(CableBlock.MODEM, newVariant)); @@ -213,31 +196,24 @@ private void updateBlockState() { void blockTick() { if (getLevel().isClientSide) return; - if (invalidPeripheral) refreshPeripheral(); + if (refreshPeripheral) { + refreshPeripheral = false; + if (isPeripheralOn()) attachPeripheral(); + } if (modem.getModemState().pollChanged()) updateBlockState(); - if (!connectionsFormed) { - connectionsFormed = true; - - connectionsChanged(); - if (peripheralAccessAllowed) { - peripheral.attach(level, worldPosition, getDirection()); - updateConnectedPeripherals(); - } - } - - if (connectionsChanged) connectionsChanged(); + if (refreshConnections) connectionsChanged(); } private void scheduleConnectionsChanged() { - connectionsChanged = true; + refreshConnections = true; TickScheduler.schedule(tickToken); } void connectionsChanged() { if (getLevel().isClientSide) return; - connectionsChanged = false; + refreshConnections = false; var state = getBlockState(); var world = getLevel(); @@ -266,43 +242,22 @@ void modemChanged() { if (getLevel().isClientSide) return; - // If we can no longer attach peripherals, then detach any - // which may have existed - if (!canAttachPeripheral() && peripheralAccessAllowed) { - peripheralAccessAllowed = false; - peripheral.detach(); - node.updatePeripherals(Map.of()); - setChanged(); - updateBlockState(); - } + // If we can no longer attach peripherals, then detach any which may have existed + if (!canAttachPeripheral()) detachPeripheral(); } - private void togglePeripheralAccess() { - if (!peripheralAccessAllowed) { - peripheral.attach(level, getBlockPos(), getDirection()); - if (!peripheral.hasPeripheral()) return; - - peripheralAccessAllowed = true; - node.updatePeripherals(peripheral.toMap()); - } else { - peripheral.detach(); - - peripheralAccessAllowed = false; - node.updatePeripherals(Map.of()); - } + private void attachPeripheral() { + if (peripheral.attach(getLevel(), getBlockPos(), getDirection())) updateConnectedPeripherals(); + updateBlockState(); + } + private void detachPeripheral() { + if (peripheral.detach()) updateConnectedPeripherals(); updateBlockState(); } private void updateConnectedPeripherals() { - var peripherals = peripheral.toMap(); - if (peripherals.isEmpty()) { - // If there are no peripherals then disable access and update the display state. - peripheralAccessAllowed = false; - updateBlockState(); - } - - node.updatePeripherals(peripherals); + node.updatePeripherals(peripheral.toMap()); } @Nullable @@ -315,6 +270,10 @@ public IPeripheral getPeripheral(@Nullable Direction direction) { return direction == null || getMaybeDirection() == direction ? modem : null; } + private boolean isPeripheralOn() { + return getBlockState().getValue(CableBlock.MODEM).isPeripheralOn(); + } + public void onModemChanged(Runnable callback) { modemChanged = callback; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java index 89422d12d..e27749b0e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java @@ -10,49 +10,57 @@ import javax.annotation.Nullable; public enum CableModemVariant implements StringRepresentable { - None("none", null), - DownOff("down_off", Direction.DOWN), - UpOff("up_off", Direction.UP), - NorthOff("north_off", Direction.NORTH), - SouthOff("south_off", Direction.SOUTH), - WestOff("west_off", Direction.WEST), - EastOff("east_off", Direction.EAST), - DownOn("down_on", Direction.DOWN), - UpOn("up_on", Direction.UP), - NorthOn("north_on", Direction.NORTH), - SouthOn("south_on", Direction.SOUTH), - WestOn("west_on", Direction.WEST), - EastOn("east_on", Direction.EAST), - DownOffPeripheral("down_off_peripheral", Direction.DOWN), - UpOffPeripheral("up_off_peripheral", Direction.UP), - NorthOffPeripheral("north_off_peripheral", Direction.NORTH), - SouthOffPeripheral("south_off_peripheral", Direction.SOUTH), - WestOffPeripheral("west_off_peripheral", Direction.WEST), - EastOffPeripheral("east_off_peripheral", Direction.EAST), - DownOnPeripheral("down_on_peripheral", Direction.DOWN), - UpOnPeripheral("up_on_peripheral", Direction.UP), - NorthOnPeripheral("north_on_peripheral", Direction.NORTH), - SouthOnPeripheral("south_on_peripheral", Direction.SOUTH), - WestOnPeripheral("west_on_peripheral", Direction.WEST), - EastOnPeripheral("east_on_peripheral", Direction.EAST); + None("none", null, false, false), + DownOff("down_off", Direction.DOWN, false, false), + UpOff("up_off", Direction.UP, false, false), + NorthOff("north_off", Direction.NORTH, false, false), + SouthOff("south_off", Direction.SOUTH, false, false), + WestOff("west_off", Direction.WEST, false, false), + EastOff("east_off", Direction.EAST, false, false), + DownOn("down_on", Direction.DOWN, true, false), + UpOn("up_on", Direction.UP, true, false), + NorthOn("north_on", Direction.NORTH, true, false), + SouthOn("south_on", Direction.SOUTH, true, false), + WestOn("west_on", Direction.WEST, true, false), + EastOn("east_on", Direction.EAST, true, false), + DownOffPeripheral("down_off_peripheral", Direction.DOWN, false, true), + UpOffPeripheral("up_off_peripheral", Direction.UP, false, true), + NorthOffPeripheral("north_off_peripheral", Direction.NORTH, false, true), + SouthOffPeripheral("south_off_peripheral", Direction.SOUTH, false, true), + WestOffPeripheral("west_off_peripheral", Direction.WEST, false, true), + EastOffPeripheral("east_off_peripheral", Direction.EAST, false, true), + DownOnPeripheral("down_on_peripheral", Direction.DOWN, true, true), + UpOnPeripheral("up_on_peripheral", Direction.UP, true, true), + NorthOnPeripheral("north_on_peripheral", Direction.NORTH, true, true), + SouthOnPeripheral("south_on_peripheral", Direction.SOUTH, true, true), + WestOnPeripheral("west_on_peripheral", Direction.WEST, true, true), + EastOnPeripheral("east_on_peripheral", Direction.EAST, true, true); private static final CableModemVariant[] VALUES = values(); private final String name; private final @Nullable Direction facing; + private final boolean modemOn, peripheralOn; - CableModemVariant(String name, @Nullable Direction facing) { + CableModemVariant(String name, @Nullable Direction facing, boolean modemOn, boolean peripheralOn) { this.name = name; this.facing = facing; + this.modemOn = modemOn; + this.peripheralOn = peripheralOn; + if (ordinal() != getIndex(facing, modemOn, peripheralOn)) throw new IllegalStateException("Mismatched ordinal"); } public static CableModemVariant from(Direction facing) { - return facing == null ? None : VALUES[1 + facing.get3DDataValue()]; + return VALUES[1 + facing.get3DDataValue()]; + } + + private static int getIndex(@Nullable Direction facing, boolean modem, boolean peripheral) { + var state = (modem ? 1 : 0) + (peripheral ? 2 : 0); + return facing == null ? 0 : 1 + 6 * state + facing.get3DDataValue(); } public static CableModemVariant from(@Nullable Direction facing, boolean modem, boolean peripheral) { - var state = (modem ? 1 : 0) + (peripheral ? 2 : 0); - return facing == null ? None : VALUES[1 + 6 * state + facing.get3DDataValue()]; + return VALUES[getIndex(facing, modem, peripheral)]; } @Override @@ -64,6 +72,14 @@ public String getSerializedName() { return facing; } + public boolean isModemOn() { + return modemOn; + } + + public boolean isPeripheralOn() { + return peripheralOn; + } + @Override public String toString() { return name; diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java index f441586df..f8c3013ca 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java @@ -32,8 +32,6 @@ import static dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlock.PERIPHERAL_ON; public class WiredModemFullBlockEntity extends BlockEntity { - private static final String NBT_PERIPHERAL_ENABLED = "PeripheralAccess"; - private static final class FullElement extends WiredModemElement { private final WiredModemFullBlockEntity entity; @@ -70,11 +68,9 @@ public Vec3 getPosition() { private final WiredModemPeripheral[] modems = new WiredModemPeripheral[6]; - private boolean peripheralAccessAllowed = false; private final WiredModemLocalPeripheral[] peripherals = new WiredModemLocalPeripheral[6]; - private boolean connectionsFormed = false; - private boolean connectionsChanged = false; + private boolean refreshConnections = false; private final TickScheduler.Token tickToken = new TickScheduler.Token(this); private final ModemState modemState = new ModemState(() -> TickScheduler.schedule(tickToken)); @@ -96,31 +92,32 @@ public WiredModemFullBlockEntity(BlockEntityType type @Override public void setRemoved() { super.setRemoved(); - if (level == null || !level.isClientSide) { - node.remove(); - connectionsFormed = false; + + for (var modem : modems) { + if (modem != null) modem.removed(); } + if (level == null || !level.isClientSide) node.remove(); + } + + @Override + public void clearRemoved() { + super.clearRemoved(); + refreshConnections = true; + invalidSides = DirectionUtil.ALL_SIDES; + TickScheduler.schedule(tickToken); } void neighborChanged(BlockPos neighbour) { - if (!level.isClientSide && peripheralAccessAllowed) { - for (var facing : DirectionUtil.FACINGS) { - if (getBlockPos().relative(facing).equals(neighbour)) queueRefreshPeripheral(facing); - } + if (level.isClientSide || !isPeripheralOn()) return; + + for (var facing : DirectionUtil.FACINGS) { + if (getBlockPos().relative(facing).equals(neighbour)) queueRefreshPeripheral(facing); } } private void queueRefreshPeripheral(Direction facing) { - if (invalidSides == 0) TickScheduler.schedule(tickToken); invalidSides |= 1 << facing.ordinal(); - } - - private void refreshPeripheral(Direction facing) { - invalidSides &= ~(1 << facing.ordinal()); - var peripheral = peripherals[facing.ordinal()]; - if (level != null && !isRemoved() && peripheral.attach(level, getBlockPos(), facing)) { - updateConnectedPeripherals(); - } + TickScheduler.schedule(tickToken); } public InteractionResult use(Player player) { @@ -129,7 +126,11 @@ public InteractionResult use(Player player) { // On server, we interacted if a peripheral was found var oldPeriphNames = getConnectedPeripheralNames(); - togglePeripheralAccess(); + if (isPeripheralOn()) { + detachPeripherals(); + } else { + attachPeripherals(DirectionUtil.ALL_SIDES); + } var periphNames = getConnectedPeripheralNames(); if (!Objects.equals(periphNames, oldPeriphNames)) { @@ -158,65 +159,45 @@ private static void sendPeripheralChanges(Player player, String kind, Collection @Override public void load(CompoundTag nbt) { super.load(nbt); - peripheralAccessAllowed = nbt.getBoolean(NBT_PERIPHERAL_ENABLED); for (var i = 0; i < peripherals.length; i++) peripherals[i].read(nbt, Integer.toString(i)); } @Override public void saveAdditional(CompoundTag nbt) { - nbt.putBoolean(NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed); for (var i = 0; i < peripherals.length; i++) peripherals[i].write(nbt, Integer.toString(i)); super.saveAdditional(nbt); } - private void updateBlockState() { - var state = getBlockState(); - boolean modemOn = modemState.isOpen(), peripheralOn = peripheralAccessAllowed; - if (state.getValue(MODEM_ON) == modemOn && state.getValue(PERIPHERAL_ON) == peripheralOn) return; - - getLevel().setBlockAndUpdate(getBlockPos(), state.setValue(MODEM_ON, modemOn).setValue(PERIPHERAL_ON, peripheralOn)); - } - - @Override - public void clearRemoved() { - super.clearRemoved(); - TickScheduler.schedule(tickToken); - } - void blockTick() { if (getLevel().isClientSide) return; if (invalidSides != 0) { - for (var direction : DirectionUtil.FACINGS) { - if ((invalidSides & (1 << direction.ordinal())) != 0) refreshPeripheral(direction); - } + var oldInvalidSides = invalidSides; + invalidSides = 0; + if (isPeripheralOn()) attachPeripherals(oldInvalidSides); } - if (modemState.pollChanged()) updateBlockState(); + if (modemState.pollChanged()) updateModemBlockState(); - if (!connectionsFormed) { - connectionsFormed = true; + if (refreshConnections) connectionsChanged(); + } - connectionsChanged(); - if (peripheralAccessAllowed) { - for (var facing : DirectionUtil.FACINGS) { - peripherals[facing.ordinal()].attach(level, getBlockPos(), facing); - } - updateConnectedPeripherals(); - } - } + private void updateModemBlockState() { + var state = getBlockState(); + var modemOn = modemState.isOpen(); + if (state.getValue(MODEM_ON) == modemOn) return; - if (connectionsChanged) connectionsChanged(); + getLevel().setBlockAndUpdate(getBlockPos(), state.setValue(MODEM_ON, modemOn)); } private void scheduleConnectionsChanged() { - connectionsChanged = true; + refreshConnections = true; TickScheduler.schedule(tickToken); } private void connectionsChanged() { if (getLevel().isClientSide) return; - connectionsChanged = false; + refreshConnections = false; var world = getLevel(); var current = getBlockPos(); @@ -231,57 +212,48 @@ private void connectionsChanged() { } } - private void togglePeripheralAccess() { - if (!peripheralAccessAllowed) { - var hasAny = false; - for (var facing : DirectionUtil.FACINGS) { - var peripheral = peripherals[facing.ordinal()]; - peripheral.attach(level, getBlockPos(), facing); - hasAny |= peripheral.hasPeripheral(); - } - - if (!hasAny) return; - - peripheralAccessAllowed = true; - node.updatePeripherals(getConnectedPeripherals()); - } else { - peripheralAccessAllowed = false; - - for (var peripheral : peripherals) peripheral.detach(); - node.updatePeripherals(Map.of()); - } - - updateBlockState(); - } - - private Set getConnectedPeripheralNames() { - if (!peripheralAccessAllowed) return Set.of(); - - Set peripherals = new HashSet<>(6); + private List getConnectedPeripheralNames() { + List peripherals = new ArrayList<>(6); for (var peripheral : this.peripherals) { var name = peripheral.getConnectedName(); if (name != null) peripherals.add(name); } + peripherals.sort(String::compareTo); return peripherals; } - private Map getConnectedPeripherals() { - if (!peripheralAccessAllowed) return Map.of(); + private void attachPeripherals(int sides) { + var anyChanged = false; - Map peripherals = new HashMap<>(6); - for (var peripheral : this.peripherals) peripheral.extendMap(peripherals); - return Collections.unmodifiableMap(peripherals); - } + Map attachedPeripherals = new HashMap<>(6); - private void updateConnectedPeripherals() { - var peripherals = getConnectedPeripherals(); - if (peripherals.isEmpty()) { - // If there are no peripherals then disable access and update the display state. - peripheralAccessAllowed = false; - updateBlockState(); + for (var facing : DirectionUtil.FACINGS) { + var peripheral = peripherals[facing.ordinal()]; + if (DirectionUtil.isSet(sides, facing)) anyChanged |= peripheral.attach(getLevel(), getBlockPos(), facing); + peripheral.extendMap(attachedPeripherals); } - node.updatePeripherals(peripherals); + if (anyChanged) node.updatePeripherals(attachedPeripherals); + + updatePeripheralBlocKState(!attachedPeripherals.isEmpty()); + } + + private void detachPeripherals() { + var anyChanged = false; + for (var peripheral : peripherals) anyChanged |= peripheral.detach(); + if (anyChanged) node.updatePeripherals(Map.of()); + + updatePeripheralBlocKState(false); + } + + private void updatePeripheralBlocKState(boolean peripheralOn) { + var state = getBlockState(); + if (state.getValue(PERIPHERAL_ON) == peripheralOn) return; + getLevel().setBlockAndUpdate(getBlockPos(), state.setValue(PERIPHERAL_ON, peripheralOn)); + } + + private boolean isPeripheralOn() { + return getBlockState().getValue(PERIPHERAL_ON); } public WiredElement getElement() { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java index 0e8b5e12f..9e691975b 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java @@ -11,6 +11,11 @@ public final class DirectionUtil { private DirectionUtil() { } + /** + * A bitmask indicating all sides. + */ + public static final int ALL_SIDES = (1 << 6) - 1; + public static final Direction[] FACINGS = Direction.values(); public static ComputerSide toLocal(Direction front, Direction dir) { @@ -31,4 +36,15 @@ public static float toPitchAngle(Direction dir) { default -> 0.0f; }; } + + /** + * Determine if a direction is in a bitmask. + * + * @param mask The bitmask to test + * @param direction The direction to check. + * @return Whether the direction is in a bitmask. + */ + public static boolean isSet(int mask, Direction direction) { + return (mask & (1 << direction.ordinal())) != 0; + } } diff --git a/projects/common/src/testMod/resources/data/cctest/structures/modem_test.gains_peripherals.snbt b/projects/common/src/testMod/resources/data/cctest/structures/modem_test.gains_peripherals.snbt index fa5f338ad..afb1e3ad7 100644 --- a/projects/common/src/testMod/resources/data/cctest/structures/modem_test.gains_peripherals.snbt +++ b/projects/common/src/testMod/resources/data/cctest/structures/modem_test.gains_peripherals.snbt @@ -28,7 +28,7 @@ {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, {pos: [0, 1, 0], state: "computercraft:printer{bottom:false,facing:north,top:false}", nbt: {Items: [], PageTitle: "", Printing: 0b, id: "computercraft:printer", term_bgColour: 15, term_cursorBlink: 0b, term_cursorX: 0, term_cursorY: 0, term_palette: [I; 1118481, 13388876, 5744206, 8349260, 3368652, 11691749, 5020082, 10066329, 5000268, 15905484, 8375321, 14605932, 10072818, 15040472, 15905331, 15790320], term_textBgColour_0: "fffffffffffffffffffffffff", term_textBgColour_1: "fffffffffffffffffffffffff", term_textBgColour_10: "fffffffffffffffffffffffff", term_textBgColour_11: "fffffffffffffffffffffffff", term_textBgColour_12: "fffffffffffffffffffffffff", term_textBgColour_13: "fffffffffffffffffffffffff", term_textBgColour_14: "fffffffffffffffffffffffff", term_textBgColour_15: "fffffffffffffffffffffffff", term_textBgColour_16: "fffffffffffffffffffffffff", term_textBgColour_17: "fffffffffffffffffffffffff", term_textBgColour_18: "fffffffffffffffffffffffff", term_textBgColour_19: "fffffffffffffffffffffffff", term_textBgColour_2: "fffffffffffffffffffffffff", term_textBgColour_20: "fffffffffffffffffffffffff", term_textBgColour_3: "fffffffffffffffffffffffff", term_textBgColour_4: "fffffffffffffffffffffffff", term_textBgColour_5: "fffffffffffffffffffffffff", term_textBgColour_6: "fffffffffffffffffffffffff", term_textBgColour_7: "fffffffffffffffffffffffff", term_textBgColour_8: "fffffffffffffffffffffffff", term_textBgColour_9: "fffffffffffffffffffffffff", term_textColour: 0, term_textColour_0: "0000000000000000000000000", term_textColour_1: "0000000000000000000000000", term_textColour_10: "0000000000000000000000000", term_textColour_11: "0000000000000000000000000", term_textColour_12: "0000000000000000000000000", term_textColour_13: "0000000000000000000000000", term_textColour_14: "0000000000000000000000000", term_textColour_15: "0000000000000000000000000", term_textColour_16: "0000000000000000000000000", term_textColour_17: "0000000000000000000000000", term_textColour_18: "0000000000000000000000000", term_textColour_19: "0000000000000000000000000", term_textColour_2: "0000000000000000000000000", term_textColour_20: "0000000000000000000000000", term_textColour_3: "0000000000000000000000000", term_textColour_4: "0000000000000000000000000", term_textColour_5: "0000000000000000000000000", term_textColour_6: "0000000000000000000000000", term_textColour_7: "0000000000000000000000000", term_textColour_8: "0000000000000000000000000", term_textColour_9: "0000000000000000000000000", term_text_0: " ", term_text_1: " ", term_text_10: " ", term_text_11: " ", term_text_12: " ", term_text_13: " ", term_text_14: " ", term_text_15: " ", term_text_16: " ", term_text_17: " ", term_text_18: " ", term_text_19: " ", term_text_2: " ", term_text_20: " ", term_text_3: " ", term_text_4: " ", term_text_5: " ", term_text_6: " ", term_text_7: " ", term_text_8: " ", term_text_9: " "}}, - {pos: [0, 1, 1], state: "computercraft:cable{cable:true,down:false,east:true,modem:north_on,north:true,south:false,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 1b, PeripheralId: 1, PeripheralType: "printer", id: "computercraft:cable"}}, + {pos: [0, 1, 1], state: "computercraft:cable{cable:true,down:false,east:true,modem:north_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 1b, PeripheralId: 1, PeripheralType: "printer", id: "computercraft:cable"}}, {pos: [0, 1, 2], state: "minecraft:air"}, {pos: [0, 1, 3], state: "minecraft:air"}, {pos: [0, 1, 4], state: "computercraft:monitor_advanced{facing:north,orientation:north,state:none}", nbt: {Height: 1, Width: 1, XIndex: 0, YIndex: 0, id: "computercraft:monitor_advanced"}}, @@ -36,7 +36,7 @@ {pos: [1, 1, 1], state: "computercraft:cable{cable:true,down:false,east:false,modem:none,north:false,south:true,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, {pos: [1, 1, 2], state: "computercraft:cable{cable:true,down:false,east:false,modem:none,north:true,south:true,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, {pos: [1, 1, 3], state: "computercraft:cable{cable:true,down:false,east:false,modem:none,north:true,south:true,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, - {pos: [1, 1, 4], state: "computercraft:cable{cable:true,down:false,east:false,modem:west_on,north:true,south:false,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 1b, PeripheralId: 1, PeripheralType: "monitor", id: "computercraft:cable"}}, + {pos: [1, 1, 4], state: "computercraft:cable{cable:true,down:false,east:false,modem:west_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 1b, PeripheralId: 1, PeripheralType: "monitor", id: "computercraft:cable"}}, {pos: [2, 1, 0], state: "minecraft:air"}, {pos: [2, 1, 1], state: "minecraft:air"}, {pos: [2, 1, 2], state: "minecraft:air"}, @@ -133,11 +133,11 @@ "minecraft:polished_andesite", "minecraft:air", "computercraft:printer{bottom:false,facing:north,top:false}", - "computercraft:cable{cable:true,down:false,east:true,modem:north_on,north:true,south:false,up:false,waterlogged:false,west:false}", + "computercraft:cable{cable:true,down:false,east:true,modem:north_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:false}", "computercraft:monitor_advanced{facing:north,orientation:north,state:none}", "computercraft:cable{cable:true,down:false,east:false,modem:none,north:false,south:true,up:false,waterlogged:false,west:true}", "computercraft:cable{cable:true,down:false,east:false,modem:none,north:true,south:true,up:false,waterlogged:false,west:false}", - "computercraft:cable{cable:true,down:false,east:false,modem:west_on,north:true,south:false,up:false,waterlogged:false,west:true}", + "computercraft:cable{cable:true,down:false,east:false,modem:west_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:true}", "computercraft:cable{cable:true,down:false,east:true,modem:none,north:false,south:false,up:false,waterlogged:false,west:false}", "computercraft:computer_advanced{facing:north,state:blinking}", "computercraft:cable{cable:true,down:false,east:false,modem:north_off,north:true,south:false,up:false,waterlogged:false,west:true}" diff --git a/projects/common/src/testMod/resources/data/cctest/structures/modem_test.have_peripherals.snbt b/projects/common/src/testMod/resources/data/cctest/structures/modem_test.have_peripherals.snbt index 65395414d..ffbb2819a 100644 --- a/projects/common/src/testMod/resources/data/cctest/structures/modem_test.have_peripherals.snbt +++ b/projects/common/src/testMod/resources/data/cctest/structures/modem_test.have_peripherals.snbt @@ -28,7 +28,7 @@ {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, {pos: [0, 1, 0], state: "computercraft:printer{bottom:false,facing:north,top:false}", nbt: {Items: [], PageTitle: "", Printing: 0b, id: "computercraft:printer", term_bgColour: 15, term_cursorBlink: 0b, term_cursorX: 0, term_cursorY: 0, term_palette: [I; 1118481, 13388876, 5744206, 8349260, 3368652, 11691749, 5020082, 10066329, 5000268, 15905484, 8375321, 14605932, 10072818, 15040472, 15905331, 15790320], term_textBgColour_0: "fffffffffffffffffffffffff", term_textBgColour_1: "fffffffffffffffffffffffff", term_textBgColour_10: "fffffffffffffffffffffffff", term_textBgColour_11: "fffffffffffffffffffffffff", term_textBgColour_12: "fffffffffffffffffffffffff", term_textBgColour_13: "fffffffffffffffffffffffff", term_textBgColour_14: "fffffffffffffffffffffffff", term_textBgColour_15: "fffffffffffffffffffffffff", term_textBgColour_16: "fffffffffffffffffffffffff", term_textBgColour_17: "fffffffffffffffffffffffff", term_textBgColour_18: "fffffffffffffffffffffffff", term_textBgColour_19: "fffffffffffffffffffffffff", term_textBgColour_2: "fffffffffffffffffffffffff", term_textBgColour_20: "fffffffffffffffffffffffff", term_textBgColour_3: "fffffffffffffffffffffffff", term_textBgColour_4: "fffffffffffffffffffffffff", term_textBgColour_5: "fffffffffffffffffffffffff", term_textBgColour_6: "fffffffffffffffffffffffff", term_textBgColour_7: "fffffffffffffffffffffffff", term_textBgColour_8: "fffffffffffffffffffffffff", term_textBgColour_9: "fffffffffffffffffffffffff", term_textColour: 0, term_textColour_0: "0000000000000000000000000", term_textColour_1: "0000000000000000000000000", term_textColour_10: "0000000000000000000000000", term_textColour_11: "0000000000000000000000000", term_textColour_12: "0000000000000000000000000", term_textColour_13: "0000000000000000000000000", term_textColour_14: "0000000000000000000000000", term_textColour_15: "0000000000000000000000000", term_textColour_16: "0000000000000000000000000", term_textColour_17: "0000000000000000000000000", term_textColour_18: "0000000000000000000000000", term_textColour_19: "0000000000000000000000000", term_textColour_2: "0000000000000000000000000", term_textColour_20: "0000000000000000000000000", term_textColour_3: "0000000000000000000000000", term_textColour_4: "0000000000000000000000000", term_textColour_5: "0000000000000000000000000", term_textColour_6: "0000000000000000000000000", term_textColour_7: "0000000000000000000000000", term_textColour_8: "0000000000000000000000000", term_textColour_9: "0000000000000000000000000", term_text_0: " ", term_text_1: " ", term_text_10: " ", term_text_11: " ", term_text_12: " ", term_text_13: " ", term_text_14: " ", term_text_15: " ", term_text_16: " ", term_text_17: " ", term_text_18: " ", term_text_19: " ", term_text_2: " ", term_text_20: " ", term_text_3: " ", term_text_4: " ", term_text_5: " ", term_text_6: " ", term_text_7: " ", term_text_8: " ", term_text_9: " "}}, - {pos: [0, 1, 1], state: "computercraft:cable{cable:true,down:false,east:false,modem:north_on,north:true,south:true,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 1b, PeripheralId: 0, PeripheralType: "printer", id: "computercraft:cable"}}, + {pos: [0, 1, 1], state: "computercraft:cable{cable:true,down:false,east:false,modem:north_off_peripheral,north:true,south:true,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 1b, PeripheralId: 0, PeripheralType: "printer", id: "computercraft:cable"}}, {pos: [0, 1, 2], state: "computercraft:cable{cable:true,down:false,east:true,modem:none,north:true,south:false,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, {pos: [0, 1, 3], state: "minecraft:air"}, {pos: [0, 1, 4], state: "computercraft:monitor_advanced{facing:north,orientation:north,state:none}", nbt: {Height: 1, Width: 1, XIndex: 0, YIndex: 0, id: "computercraft:monitor_advanced"}}, @@ -36,7 +36,7 @@ {pos: [1, 1, 1], state: "minecraft:air"}, {pos: [1, 1, 2], state: "computercraft:cable{cable:true,down:false,east:true,modem:none,north:false,south:true,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, {pos: [1, 1, 3], state: "computercraft:cable{cable:true,down:false,east:false,modem:none,north:true,south:true,up:false,waterlogged:false,west:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, - {pos: [1, 1, 4], state: "computercraft:cable{cable:true,down:false,east:false,modem:west_on,north:true,south:false,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 1b, PeripheralId: 0, PeripheralType: "monitor", id: "computercraft:cable"}}, + {pos: [1, 1, 4], state: "computercraft:cable{cable:true,down:false,east:false,modem:west_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 1b, PeripheralId: 0, PeripheralType: "monitor", id: "computercraft:cable"}}, {pos: [2, 1, 0], state: "minecraft:air"}, {pos: [2, 1, 1], state: "minecraft:air"}, {pos: [2, 1, 2], state: "computercraft:cable{cable:true,down:false,east:true,modem:none,north:false,south:false,up:false,waterlogged:false,west:true}", nbt: {PeripheralAccess: 0b, id: "computercraft:cable"}}, @@ -133,12 +133,12 @@ "minecraft:polished_andesite", "minecraft:air", "computercraft:printer{bottom:false,facing:north,top:false}", - "computercraft:cable{cable:true,down:false,east:false,modem:north_on,north:true,south:true,up:false,waterlogged:false,west:false}", + "computercraft:cable{cable:true,down:false,east:false,modem:north_off_peripheral,north:true,south:true,up:false,waterlogged:false,west:false}", "computercraft:cable{cable:true,down:false,east:true,modem:none,north:true,south:false,up:false,waterlogged:false,west:false}", "computercraft:monitor_advanced{facing:north,orientation:north,state:none}", "computercraft:cable{cable:true,down:false,east:true,modem:none,north:false,south:true,up:false,waterlogged:false,west:true}", "computercraft:cable{cable:true,down:false,east:false,modem:none,north:true,south:true,up:false,waterlogged:false,west:false}", - "computercraft:cable{cable:true,down:false,east:false,modem:west_on,north:true,south:false,up:false,waterlogged:false,west:true}", + "computercraft:cable{cable:true,down:false,east:false,modem:west_off_peripheral,north:true,south:false,up:false,waterlogged:false,west:true}", "computercraft:cable{cable:true,down:false,east:true,modem:none,north:false,south:false,up:false,waterlogged:false,west:true}", "computercraft:cable{cable:true,down:false,east:true,modem:east_off,north:false,south:false,up:false,waterlogged:false,west:true}", "computercraft:computer_advanced{facing:north,state:blinking}"