diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java index cf16a836e..e0d539a1d 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java @@ -9,8 +9,10 @@ import dan200.computercraft.api.upgrades.UpgradeData; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.ApiStatus; import javax.annotation.Nullable; @@ -21,6 +23,20 @@ */ @ApiStatus.NonExtendable public interface IPocketAccess { + /** + * Get the level in which the pocket computer exists. + * + * @return The pocket computer's level. + */ + ServerLevel getLevel(); + + /** + * Get the position of the pocket computer. + * + * @return The pocket computer's position. + */ + Vec3 getPosition(); + /** * Gets the entity holding this item. *

diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java index 5348c1dab..33b5e8231 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java @@ -16,8 +16,10 @@ import dan200.computercraft.shared.pocket.items.PocketComputerItem; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; import java.util.Collections; @@ -34,6 +36,7 @@ public final class PocketBrain implements IPocketAccess { private final PocketServerComputer computer; private PocketHolder holder; + private Vec3 position; private boolean dirty = false; private @Nullable UpgradeData upgrade; @@ -43,6 +46,7 @@ public final class PocketBrain implements IPocketAccess { public PocketBrain(PocketHolder holder, int computerID, @Nullable String label, ComputerFamily family, @Nullable UpgradeData upgrade) { this.computer = new PocketServerComputer(this, holder, computerID, label, family); this.holder = holder; + this.position = holder.pos(); this.upgrade = UpgradeData.copyOf(upgrade); invalidatePeripheral(); } @@ -66,6 +70,7 @@ PocketHolder holder() { * @param newHolder The new holder */ public void updateHolder(PocketHolder newHolder) { + position = newHolder.pos(); computer.setPosition(newHolder.level(), newHolder.blockPos()); var oldHolder = this.holder; @@ -94,6 +99,18 @@ public boolean updateItem(ItemStack stack) { return true; } + @Override + public ServerLevel getLevel() { + return computer.getLevel(); + } + + @Override + public Vec3 getPosition() { + // This method can be called from off-thread, and so we must use the cached position rather than rereading + // from the holder. + return position; + } + @Override public @Nullable Entity getEntity() { return holder instanceof PocketHolder.EntityHolder entity && holder.isValid(computer) ? entity.entity() : null; diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java index 5e6187a56..16dc81a5d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java @@ -11,6 +11,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.phys.Vec3; /** * An object that holds a pocket computer item. @@ -23,6 +24,13 @@ public sealed interface PocketHolder permits PocketHolder.EntityHolder { */ ServerLevel level(); + /** + * The position of this holder. + * + * @return The position of this holder. + */ + Vec3 pos(); + /** * The block position of this holder. * @@ -59,6 +67,11 @@ default ServerLevel level() { return (ServerLevel) entity().level(); } + @Override + default Vec3 pos() { + return entity().getEyePosition(); + } + @Override default BlockPos blockPos() { return entity().blockPosition(); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java index 273c5e8a4..6ab3469a0 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java @@ -31,8 +31,6 @@ public IPeripheral createPeripheral(IPocketAccess access) { public void update(IPocketAccess access, @Nullable IPeripheral peripheral) { if (!(peripheral instanceof PocketModemPeripheral modem)) return; - modem.setLocation(access); - var state = modem.getModemState(); if (state.pollChanged()) access.setLight(state.isOpen() ? 0xBA0000 : -1); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java index a55c7fa16..bd1d8b289 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java @@ -14,31 +14,21 @@ import javax.annotation.Nullable; public class PocketModemPeripheral extends WirelessModemPeripheral { - private @Nullable Level level = null; - private Vec3 position = Vec3.ZERO; + private final IPocketAccess access; public PocketModemPeripheral(boolean advanced, IPocketAccess access) { super(new ModemState(), advanced); - setLocation(access); - } - - void setLocation(IPocketAccess access) { - var entity = access.getEntity(); - if (entity != null) { - level = entity.level(); - position = entity.getEyePosition(1); - } + this.access = access; } @Override public Level getLevel() { - if (level == null) throw new IllegalStateException("Using modem before position has been defined"); - return level; + return access.getLevel(); } @Override public Vec3 getPosition() { - return position; + return access.getPosition(); } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java index 538790560..58a8df873 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java @@ -8,15 +8,11 @@ import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral { private final IPocketAccess access; - private @Nullable Level level; - private Vec3 position = Vec3.ZERO; public PocketSpeakerPeripheral(IPocketAccess access) { this.access = access; @@ -25,7 +21,7 @@ public PocketSpeakerPeripheral(IPocketAccess access) { @Override public SpeakerPosition getPosition() { var entity = access.getEntity(); - return entity == null ? SpeakerPosition.of(level, position) : SpeakerPosition.of(entity); + return entity == null ? SpeakerPosition.of(access.getLevel(), access.getPosition()) : SpeakerPosition.of(entity); } @Override @@ -35,12 +31,6 @@ public boolean equals(@Nullable IPeripheral other) { @Override public void update() { - var entity = access.getEntity(); - if (entity != null) { - level = entity.level(); - position = entity.position(); - } - super.update(); access.setLight(madeSound() ? 0x3320fc : -1);