diff --git a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java index 9d40b8efc..61c27d7a8 100644 --- a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java +++ b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java @@ -62,10 +62,9 @@ public abstract class TileGeneric extends BlockEntity return 8.0; } - public boolean isUsable( Player player, boolean ignoreRange ) + public boolean isUsable( Player player ) { if( player == null || !player.isAlive() || getLevel().getBlockEntity( getBlockPos() ) != this ) return false; - if( ignoreRange ) return true; double range = getInteractRange( player ); BlockPos pos = getBlockPos(); diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java index 09825a162..a564d807b 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java @@ -115,12 +115,12 @@ public class TileCommandComputer extends TileComputer } @Override - public boolean isUsable( Player player, boolean ignoreRange ) + public boolean isUsable( Player player ) { - return isUsable( player ) && super.isUsable( player, ignoreRange ); + return isCommandUsable( player ) && super.isUsable( player ); } - public static boolean isUsable( Player player ) + public static boolean isCommandUsable( Player player ) { MinecraftServer server = player.getServer(); if( server == null || !server.isCommandBlockEnabled() ) diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java index 11874c773..4e7a56c58 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java @@ -54,7 +54,7 @@ public class TileComputer extends TileComputerBase protected boolean isUsableByPlayer( Player player ) { - return isUsable( player, false ); + return isUsable( player ); } @Override diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java index 455b755cd..a6807712f 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java @@ -25,13 +25,11 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.Nameable; +import net.minecraft.world.*; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -57,6 +55,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT private int invalidSides = 0; private final NonNullConsumer[] invalidate; + private LockCode lockCode = LockCode.NO_LOCK; + private final ComputerFamily family; public TileComputerBase( BlockEntityType type, BlockPos pos, BlockState state, ComputerFamily family ) @@ -111,6 +111,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT return false; } + @Override + public boolean isUsable( Player player ) + { + return super.isUsable( player ) && BaseContainerBlockEntity.canUnlock( player, lockCode, getDisplayName() ); + } + @Nonnull @Override public InteractionResult onActivate( Player player, InteractionHand hand, BlockHitResult hit ) @@ -129,7 +135,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT else if( !player.isCrouching() ) { // Regular right click to activate computer - if( !getLevel().isClientSide && isUsable( player, false ) ) + if( !getLevel().isClientSide && isUsable( player ) ) { createServerComputer().turnOn(); new ComputerContainerData( createServerComputer() ).open( player, this ); @@ -196,6 +202,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT if( label != null ) nbt.putString( NBT_LABEL, label ); nbt.putBoolean( NBT_ON, on ); + lockCode.addToTag( nbt ); + super.saveAdditional( nbt ); } @@ -208,6 +216,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; on = startOn = nbt.getBoolean( NBT_ON ); + + lockCode = LockCode.fromTag( nbt ); } protected boolean isPeripheralBlockedOnSide( ComputerSide localSide ) diff --git a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java index c40e6a11a..8e43305c2 100644 --- a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java @@ -43,7 +43,7 @@ public class ContainerViewComputer extends ComputerMenuWithoutInventory } // If we're a command computer then ensure we're in creative - if( computer.getFamily() == ComputerFamily.COMMAND && !TileCommandComputer.isUsable( player ) ) + if( computer.getFamily() == ComputerFamily.COMMAND && !TileCommandComputer.isCommandUsable( player ) ) { return false; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java index d8cba9ddd..b2782408d 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java @@ -23,15 +23,13 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.Nameable; +import net.minecraft.world.*; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -61,6 +59,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory } Component customName; + private LockCode lockCode; private final Map computers = new HashMap<>(); @@ -95,6 +94,12 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory peripheralCap = CapabilityUtil.invalidate( peripheralCap ); } + @Override + public boolean isUsable( Player player ) + { + return super.isUsable( player ) && BaseContainerBlockEntity.canUnlock( player, lockCode, getDisplayName() ); + } + @Nonnull @Override public InteractionResult onActivate( Player player, InteractionHand hand, BlockHitResult hit ) @@ -114,7 +119,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory else { // Open the GUI - if( !getLevel().isClientSide ) NetworkHooks.openGui( (ServerPlayer) player, this ); + if( !getLevel().isClientSide && isUsable( player ) ) + { + NetworkHooks.openGui( (ServerPlayer) player, this ); + } return InteractionResult.SUCCESS; } } @@ -135,6 +143,8 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory diskStack = ItemStack.of( item ); diskMount = null; } + + lockCode = LockCode.fromTag( nbt ); } @Override @@ -148,6 +158,9 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory diskStack.save( item ); nbt.put( NBT_ITEM, item ); } + + lockCode.addToTag( nbt ); + super.saveAdditional( nbt ); } @@ -298,7 +311,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory @Override public boolean stillValid( @Nonnull Player player ) { - return isUsable( player, false ); + return isUsable( player ); } @Override diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java index b289ef99a..f788fa5f2 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java @@ -25,6 +25,7 @@ import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -55,6 +56,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent private static final int[] SIDE_SLOTS = new int[] { 0 }; Component customName; + private LockCode lockCode; private final NonNullList inventory = NonNullList.withSize( SLOTS, ItemStack.EMPTY ); private final SidedCaps itemHandlerCaps = @@ -84,13 +86,22 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent peripheralCap = CapabilityUtil.invalidate( peripheralCap ); } + @Override + public boolean isUsable( Player player ) + { + return super.isUsable( player ) && BaseContainerBlockEntity.canUnlock( player, lockCode, getDisplayName() ); + } + @Nonnull @Override public InteractionResult onActivate( Player player, InteractionHand hand, BlockHitResult hit ) { if( player.isCrouching() ) return InteractionResult.PASS; - if( !getLevel().isClientSide ) NetworkHooks.openGui( (ServerPlayer) player, this ); + if( !getLevel().isClientSide && isUsable( player ) ) + { + NetworkHooks.openGui( (ServerPlayer) player, this ); + } return InteractionResult.SUCCESS; } @@ -111,6 +122,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent // Read inventory ContainerHelper.loadAllItems( nbt, inventory ); + + lockCode = LockCode.fromTag( nbt ); } @Override @@ -129,6 +142,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent // Write inventory ContainerHelper.saveAllItems( nbt, inventory ); + lockCode.addToTag( nbt ); + super.saveAdditional( nbt ); } @@ -231,7 +246,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent @Override public boolean stillValid( @Nonnull Player playerEntity ) { - return isUsable( playerEntity, false ); + return isUsable( playerEntity ); } // ISidedInventory implementation diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index 2787a158c..ebd093b18 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -50,6 +50,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I private static final String NBT_UPGRADE = "Upgrade"; private static final String NBT_UPGRADE_INFO = "UpgradeInfo"; public static final String NBT_LIGHT = "Light"; + private static final String NBT_ON = "On"; private static final String NBT_INSTANCE = "Instanceid"; private static final String NBT_SESSION = "SessionId"; @@ -105,6 +106,13 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I setLabel( stack, label ); } + boolean on = computer.isOn(); + if( on != isMarkedOn( stack ) ) + { + changed = true; + stack.getOrCreateTag().putBoolean( NBT_ON, on ); + } + // Update pocket upgrade if( upgrade != null ) upgrade.update( computer, computer.getPeripheral( ComputerSide.BACK ) ); @@ -247,6 +255,10 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I computer.updateValues( entity, stack, getUpgrade( stack ) ); computer.addAPI( new PocketAPI( computer ) ); ComputerCraft.serverComputerRegistry.add( instanceID, computer ); + + // Only turn on when initially creating the computer, rather than each tick. + if( isMarkedOn( stack ) && entity instanceof Player ) computer.turnOn(); + if( inventory != null ) inventory.setChanged(); } computer.setLevel( world ); @@ -362,6 +374,12 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I stack.getOrCreateTag().putInt( NBT_SESSION, sessionID ); } + private static boolean isMarkedOn( @Nonnull ItemStack stack ) + { + CompoundTag nbt = stack.getTag(); + return nbt != null && nbt.getBoolean( NBT_ON ); + } + public static ComputerState getState( @Nonnull ItemStack stack ) { ClientComputer computer = getClientComputer( stack ); diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java index 59bcc55e8..d255db7eb 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java @@ -487,7 +487,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default @Override public boolean stillValid( @Nonnull Player player ) { - return isUsable( player, false ); + return isUsable( player ); } private void onInventoryDefinitelyChanged()