mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2026-09-16 14:21:24 +00:00
Let pocket computer on lecterns wrap the peripheral below
- Shuffle some of the accessors in PocketComputerItem around, to make them easier to use in the lectern code. I still don't think we've got a good interface here. We could possibly move more of the update code into PocketBrain, and just have PocketComputerItem responsible for syncing brain<->stack state. Something to fiddle with, but not sure it would be any cleaner. - Set the bottom peripheral when the pocket computer is placed in the lectern (and on block updates, etc...), and clear it when removed. Again, the code here is uglier than I would like (particularly with all the instanceofs). I did wonder about having some LecternBehaviour class, which holds the printout/pocket-specific state, but there's so many places we need to hook in (and they're so different between the two), I'm not sure it's worth it right now. Fixes #2126, closes #2223.
This commit is contained in:
+21
@@ -4,10 +4,14 @@
|
||||
|
||||
package dan200.computercraft.shared.lectern;
|
||||
|
||||
import dan200.computercraft.core.computer.ComputerSide;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.media.items.PrintoutItem;
|
||||
import dan200.computercraft.shared.pocket.core.PocketHolder;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import dan200.computercraft.shared.util.BlockEntityHelpers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.RandomSource;
|
||||
@@ -21,6 +25,7 @@ import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LecternBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -102,6 +107,16 @@ public class CustomLecternBlock extends LecternBlock {
|
||||
return new ItemStack(Items.LECTERN);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public final void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean isMoving) {
|
||||
if (!level.isClientSide() && pos.relative(Direction.DOWN).equals(neighbourPos)
|
||||
&& level.getBlockEntity(pos) instanceof CustomLecternBlockEntity lectern && lectern.getItem().getItem() instanceof PocketComputerItem
|
||||
) {
|
||||
lectern.markRefreshPeripheral();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
// If we've no lectern, remove it.
|
||||
@@ -133,6 +148,12 @@ public class CustomLecternBlock extends LecternBlock {
|
||||
var entity = new ItemEntity(level, pos.getX() + 0.5 + dx, pos.getY() + 1, pos.getZ() + 0.5 + dz, stack);
|
||||
entity.setDefaultPickUpDelay();
|
||||
level.addFreshEntity(entity);
|
||||
|
||||
// If we're a pocket computer, update the holder and clear the peripheral.
|
||||
if (stack.getItem() instanceof PocketComputerItem pocket) {
|
||||
var brain = pocket.getBrain(new PocketHolder.ItemEntityHolder(entity), stack);
|
||||
if (brain != null) brain.computer().setPeripheral(ComputerSide.BOTTOM, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+37
-4
@@ -4,17 +4,22 @@
|
||||
|
||||
package dan200.computercraft.shared.lectern;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.computer.ComputerSide;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.container.BasicContainer;
|
||||
import dan200.computercraft.shared.container.SingleContainerData;
|
||||
import dan200.computercraft.shared.media.PrintoutMenu;
|
||||
import dan200.computercraft.shared.media.items.PrintoutItem;
|
||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||
import dan200.computercraft.shared.platform.ComponentAccess;
|
||||
import dan200.computercraft.shared.platform.PlatformHelper;
|
||||
import dan200.computercraft.shared.pocket.core.PocketBrain;
|
||||
import dan200.computercraft.shared.pocket.core.PocketHolder;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import dan200.computercraft.shared.util.BlockEntityHelpers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
@@ -30,6 +35,7 @@ import net.minecraft.world.level.block.LecternBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.List;
|
||||
@@ -46,10 +52,21 @@ public final class CustomLecternBlockEntity extends BlockEntity {
|
||||
private ItemStack item = ItemStack.EMPTY;
|
||||
private int page, pageCount;
|
||||
|
||||
private final PocketHolder.LecternHolder pocketHolder = new PocketHolder.LecternHolder(this);
|
||||
private @Nullable PocketBrain activePocketBrain;
|
||||
private final ComponentAccess<IPeripheral> peripherals = PlatformHelper.get().createPeripheralAccess(this, d -> markRefreshPeripheral());
|
||||
private boolean refreshPeripheral;
|
||||
|
||||
public CustomLecternBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModRegistry.BlockEntities.LECTERN.get(), pos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRemoved() {
|
||||
refreshPeripheral = true;
|
||||
super.clearRemoved();
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
@@ -79,11 +96,27 @@ public final class CustomLecternBlockEntity extends BlockEntity {
|
||||
} else {
|
||||
pageCount = page = 0;
|
||||
}
|
||||
|
||||
activePocketBrain = null;
|
||||
}
|
||||
|
||||
void markRefreshPeripheral() {
|
||||
refreshPeripheral = true;
|
||||
}
|
||||
|
||||
void tick() {
|
||||
if (item.getItem() instanceof PocketComputerItem pocket) {
|
||||
pocket.tick(item, new PocketHolder.LecternHolder(this), false);
|
||||
// Get our pocket computer, and tick it.
|
||||
var brain = pocket.getOrCreateBrain(pocketHolder, item);
|
||||
brain.computer().keepAlive();
|
||||
pocket.tick(item, pocketHolder, brain);
|
||||
|
||||
// Update the peripheral if the peripheral or brain has changed.
|
||||
if (refreshPeripheral || brain != activePocketBrain) {
|
||||
refreshPeripheral = false;
|
||||
activePocketBrain = brain;
|
||||
brain.computer().setPeripheral(ComputerSide.BOTTOM, peripherals.get(Direction.DOWN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +171,11 @@ public final class CustomLecternBlockEntity extends BlockEntity {
|
||||
new PrintoutContainerData()
|
||||
), getItem().getDisplayName()));
|
||||
} else if (item.getItem() instanceof PocketComputerItem pocket) {
|
||||
var holder = new PocketHolder.LecternHolder(this);
|
||||
var computer = pocket.getAndTurnOnServerComputer(item, holder);
|
||||
var computer = pocket.getOrCreateBrain(pocketHolder, item).computer();
|
||||
computer.turnOn();
|
||||
PlatformHelper.get().openMenu(
|
||||
player, item.getHoverName(),
|
||||
(id, inv, entity) -> new PocketComputerLecternMenu(id, inv, holder, computer),
|
||||
(id, inv, entity) -> new PocketComputerLecternMenu(id, inv, pocketHolder, computer),
|
||||
new PocketComputerLecternMenu.Data(new ComputerContainerData(computer, item), getBlockPos())
|
||||
);
|
||||
}
|
||||
|
||||
+33
-37
@@ -31,7 +31,6 @@ import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@@ -80,25 +79,16 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
/**
|
||||
* Tick a pocket computer.
|
||||
*
|
||||
* @param stack The current pocket computer stack.
|
||||
* @param holder The entity holding the pocket item.
|
||||
* @param passive If set, the pocket computer will not be created if it doesn't exist, and will not be kept alive.
|
||||
* @param stack The current pocket computer stack.
|
||||
* @param holder The entity holding the pocket item.
|
||||
* @param brain The pocket brain.
|
||||
*/
|
||||
public void tick(ItemStack stack, PocketHolder holder, boolean passive) {
|
||||
PocketBrain brain;
|
||||
if (passive) {
|
||||
var computer = getServerComputer(holder.level().getServer(), stack);
|
||||
if (computer == null) return;
|
||||
brain = computer.getBrain();
|
||||
} else {
|
||||
brain = getOrCreateBrain(holder.level(), holder, stack);
|
||||
brain.computer().keepAlive();
|
||||
}
|
||||
|
||||
public void tick(ItemStack stack, PocketHolder holder, PocketBrain brain) {
|
||||
// Update pocket upgrade
|
||||
var upgrade = brain.getUpgrade();
|
||||
if (upgrade != null) upgrade.upgrade().update(brain, brain.computer().getPeripheral(ComputerSide.BACK));
|
||||
|
||||
// Sync pocket state back to the item
|
||||
if (updateItem(stack, brain)) holder.setChanged();
|
||||
}
|
||||
|
||||
@@ -150,7 +140,10 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
if (slot < 0) return;
|
||||
|
||||
// If we're in the inventory, create a computer and keep it alive.
|
||||
tick(stack, new PocketHolder.PlayerHolder(player, slot), false);
|
||||
var holder = new PocketHolder.PlayerHolder(player, slot);
|
||||
var brain = getOrCreateBrain(holder, stack);
|
||||
brain.computer().keepAlive();
|
||||
tick(stack, holder, brain);
|
||||
}
|
||||
|
||||
@ForgeOverride
|
||||
@@ -160,7 +153,9 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
|
||||
// If we're an item entity, tick an already existing computer (as to update the position), but do not keep the
|
||||
// computer alive.
|
||||
tick(stack, new PocketHolder.ItemEntityHolder(entity), true);
|
||||
var holder = new PocketHolder.ItemEntityHolder(entity);
|
||||
var brain = getBrain(holder, stack);
|
||||
if (brain != null) tick(stack, holder, brain);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -175,7 +170,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
var stack = player.getItemInHand(hand);
|
||||
if (!world.isClientSide) {
|
||||
var holder = new PocketHolder.PlayerHolder((ServerPlayer) player, InventoryUtil.getHandSlot(player, hand));
|
||||
var brain = getOrCreateBrain((ServerLevel) world, holder, stack);
|
||||
var brain = getOrCreateBrain(holder, stack);
|
||||
var computer = brain.computer();
|
||||
computer.turnOn();
|
||||
|
||||
@@ -239,8 +234,16 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
return ComputerCraftAPI.MOD_ID;
|
||||
}
|
||||
|
||||
private PocketBrain getOrCreateBrain(ServerLevel level, PocketHolder holder, ItemStack stack) {
|
||||
var registry = ServerContext.get(level.getServer()).registry();
|
||||
/**
|
||||
* Get (or create) the pocket brain and turn it on, ready for the player to interact with.
|
||||
*
|
||||
* @param stack The pocket computer stack.
|
||||
* @param holder The holder of the pocket computer.
|
||||
* @return The pocket brain.
|
||||
*/
|
||||
public PocketBrain getOrCreateBrain(PocketHolder holder, ItemStack stack) {
|
||||
var server = holder.level().getServer();
|
||||
var registry = ServerContext.get(server).registry();
|
||||
{
|
||||
var computer = getServerComputer(registry, stack);
|
||||
if (computer != null) {
|
||||
@@ -252,7 +255,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
|
||||
var computerID = getComputerID(stack);
|
||||
if (computerID < 0) {
|
||||
computerID = ComputerCraftAPI.createUniqueNumberedSaveDir(level.getServer(), IDAssigner.COMPUTER);
|
||||
computerID = ComputerCraftAPI.createUniqueNumberedSaveDir(server, IDAssigner.COMPUTER);
|
||||
setComputerID(stack, computerID);
|
||||
}
|
||||
|
||||
@@ -275,18 +278,13 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
return brain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (or create) the pocket server computer and turn it on, ready for the player to interact with.
|
||||
*
|
||||
* @param stack The pocket computer stack.
|
||||
* @param holder The holder of the pocket computer.
|
||||
* @return The pocket server computer.
|
||||
*/
|
||||
public ServerComputer getAndTurnOnServerComputer(ItemStack stack, PocketHolder holder) {
|
||||
var brain = getOrCreateBrain(holder.level(), holder, stack);
|
||||
var computer = brain.computer();
|
||||
computer.turnOn();
|
||||
return computer;
|
||||
public @Nullable PocketBrain getBrain(PocketHolder holder, ItemStack stack) {
|
||||
var computer = getServerComputer(holder.level().getServer(), stack);
|
||||
if (computer == null) return null;
|
||||
|
||||
var brain = computer.getBrain();
|
||||
brain.updateHolder(holder);
|
||||
return brain;
|
||||
}
|
||||
|
||||
public static boolean isServerComputer(ServerComputer computer, ItemStack stack) {
|
||||
@@ -294,13 +292,11 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
|
||||
&& getServerComputer(computer.getLevel().getServer(), stack) == computer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PocketServerComputer getServerComputer(ServerComputerRegistry registry, ItemStack stack) {
|
||||
private static @Nullable PocketServerComputer getServerComputer(ServerComputerRegistry registry, ItemStack stack) {
|
||||
return (PocketServerComputer) registry.get(getSessionID(stack), getInstanceID(stack));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PocketServerComputer getServerComputer(MinecraftServer server, ItemStack stack) {
|
||||
private static @Nullable PocketServerComputer getServerComputer(MinecraftServer server, ItemStack stack) {
|
||||
return getServerComputer(ServerContext.get(server).registry(), stack);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user