diff --git a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java index 0411cfecb..9532c7d4f 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java @@ -19,9 +19,9 @@ import net.minecraftforge.client.event.RenderItemInFrameEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import static dan200.computercraft.client.render.PrintoutRenderer.*; import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH; -import static dan200.computercraft.client.render.PrintoutRenderer.*; import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; @@ -88,7 +88,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2; // Non-books will be left aligned - if( !book ) width += offsetAt( pages ); + if( !book ) width += offsetAt( pages - 1 ); double visualWidth = width, visualHeight = height; diff --git a/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java b/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java deleted file mode 100644 index aadc32309..000000000 --- a/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ComputerCraft - http://www.computercraft.info - * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. - * Send enquiries to dratcliffe@gmail.com - */ -package dan200.computercraft.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import dan200.computercraft.shared.turtle.core.TurtlePlayer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.EntityRenderer; -import net.minecraft.client.renderer.entity.EntityRendererProvider; -import net.minecraft.resources.ResourceLocation; - -import javax.annotation.Nonnull; - -public class TurtlePlayerRenderer extends EntityRenderer -{ - public TurtlePlayerRenderer( EntityRendererProvider.Context renderManager ) - { - super( renderManager ); - } - - @Nonnull - @Override - public ResourceLocation getTextureLocation( @Nonnull TurtlePlayer entity ) - { - return ComputerBorderRenderer.BACKGROUND_NORMAL; - } - - @Override - public void render( @Nonnull TurtlePlayer entityIn, float entityYaw, float partialTicks, @Nonnull PoseStack transform, @Nonnull MultiBufferSource buffer, int packedLightIn ) - { - } -} diff --git a/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java b/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java index 3ac5a6092..e52988174 100644 --- a/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java +++ b/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java @@ -6,10 +6,10 @@ package dan200.computercraft.client.sound; import dan200.computercraft.ComputerCraft; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.phys.Vec3; /** * An instance of a speaker, which is either playing a {@link DfpwmStream} stream or a normal sound. @@ -43,7 +43,7 @@ public class SpeakerInstance } } - public void playAudio( Vec3 position, float volume ) + public void playAudio( SpeakerPosition position, float volume ) { var soundManager = Minecraft.getInstance().getSoundManager(); @@ -62,7 +62,7 @@ public class SpeakerInstance } } - public void playSound( Vec3 position, ResourceLocation location, float volume, float pitch ) + public void playSound( SpeakerPosition position, ResourceLocation location, float volume, float pitch ) { var soundManager = Minecraft.getInstance().getSoundManager(); currentStream = null; @@ -77,7 +77,7 @@ public class SpeakerInstance soundManager.play( sound ); } - void setPosition( Vec3 position ) + void setPosition( SpeakerPosition position ) { if( sound != null ) sound.setPosition( position ); } diff --git a/src/main/java/dan200/computercraft/client/sound/SpeakerManager.java b/src/main/java/dan200/computercraft/client/sound/SpeakerManager.java index 1c9cf029e..b9b357667 100644 --- a/src/main/java/dan200/computercraft/client/sound/SpeakerManager.java +++ b/src/main/java/dan200/computercraft/client/sound/SpeakerManager.java @@ -5,7 +5,7 @@ */ package dan200.computercraft.client.sound; -import net.minecraft.world.phys.Vec3; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.sound.PlayStreamingSourceEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -44,7 +44,7 @@ public class SpeakerManager if( sound != null ) sound.stop(); } - public static void moveSound( UUID source, Vec3 position ) + public static void moveSound( UUID source, SpeakerPosition position ) { SpeakerInstance sound = sounds.get( source ); if( sound != null ) sound.setPosition( position ); diff --git a/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java b/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java index 171583ee8..120cb5547 100644 --- a/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java +++ b/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java @@ -6,6 +6,7 @@ package dan200.computercraft.client.sound; import com.mojang.blaze3d.audio.Channel; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.client.resources.sounds.AbstractSoundInstance; import net.minecraft.client.resources.sounds.Sound; import net.minecraft.client.resources.sounds.TickableSoundInstance; @@ -13,7 +14,7 @@ import net.minecraft.client.sounds.AudioStream; import net.minecraft.client.sounds.SoundBufferLibrary; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundSource; -import net.minecraft.world.phys.Vec3; +import net.minecraft.world.entity.Entity; import javax.annotation.Nonnull; import java.util.concurrent.CompletableFuture; @@ -25,7 +26,11 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound Executor executor; DfpwmStream stream; - SpeakerSound( ResourceLocation sound, DfpwmStream stream, Vec3 position, float volume, float pitch ) + private Entity entity; + + private boolean stopped = false; + + SpeakerSound( ResourceLocation sound, DfpwmStream stream, SpeakerPosition position, float volume, float pitch ) { super( sound, SoundSource.RECORDS ); setPosition( position ); @@ -35,22 +40,35 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound attenuation = Attenuation.LINEAR; } - void setPosition( Vec3 position ) + void setPosition( SpeakerPosition position ) { - x = (float) position.x(); - y = (float) position.y(); - z = (float) position.z(); + x = position.position().x; + y = position.position().y; + z = position.position().z; + entity = position.entity(); } @Override public boolean isStopped() { - return false; + return stopped; } @Override public void tick() { + if( entity == null ) return; + if( !entity.isAlive() ) + { + stopped = true; + looping = false; + } + else + { + x = entity.getX(); + y = entity.getY(); + z = entity.getZ(); + } } @Nonnull diff --git a/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java index 386b8cab0..102807dd1 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java @@ -7,8 +7,8 @@ package dan200.computercraft.shared.network.client; import dan200.computercraft.client.sound.SpeakerManager; import dan200.computercraft.shared.network.NetworkMessage; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.network.NetworkEvent; @@ -27,14 +27,14 @@ import java.util.UUID; public class SpeakerAudioClientMessage implements NetworkMessage { private final UUID source; - private final Vec3 pos; + private final SpeakerPosition.Message pos; private final ByteBuffer content; private final float volume; - public SpeakerAudioClientMessage( UUID source, Vec3 pos, float volume, ByteBuffer content ) + public SpeakerAudioClientMessage( UUID source, SpeakerPosition pos, float volume, ByteBuffer content ) { this.source = source; - this.pos = pos; + this.pos = pos.asMessage(); this.content = content; this.volume = volume; } @@ -42,7 +42,7 @@ public class SpeakerAudioClientMessage implements NetworkMessage public SpeakerAudioClientMessage( FriendlyByteBuf buf ) { source = buf.readUUID(); - pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); + pos = SpeakerPosition.Message.read( buf ); volume = buf.readFloat(); SpeakerManager.getSound( source ).pushAudio( buf ); @@ -53,9 +53,7 @@ public class SpeakerAudioClientMessage implements NetworkMessage public void toBytes( @Nonnull FriendlyByteBuf buf ) { buf.writeUUID( source ); - buf.writeDouble( pos.x() ); - buf.writeDouble( pos.y() ); - buf.writeDouble( pos.z() ); + pos.write( buf ); buf.writeFloat( volume ); buf.writeBytes( content.duplicate() ); } @@ -64,6 +62,6 @@ public class SpeakerAudioClientMessage implements NetworkMessage @OnlyIn( Dist.CLIENT ) public void handle( NetworkEvent.Context context ) { - SpeakerManager.getSound( source ).playAudio( pos, volume ); + SpeakerManager.getSound( source ).playAudio( pos.reify(), volume ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/SpeakerMoveClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/SpeakerMoveClientMessage.java index 9218c04d0..b02b417ab 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/SpeakerMoveClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/SpeakerMoveClientMessage.java @@ -7,8 +7,8 @@ package dan200.computercraft.shared.network.client; import dan200.computercraft.client.sound.SpeakerManager; import dan200.computercraft.shared.network.NetworkMessage; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.network.NetworkEvent; @@ -26,33 +26,31 @@ import java.util.UUID; public class SpeakerMoveClientMessage implements NetworkMessage { private final UUID source; - private final Vec3 pos; + private final SpeakerPosition.Message pos; - public SpeakerMoveClientMessage( UUID source, Vec3 pos ) + public SpeakerMoveClientMessage( UUID source, SpeakerPosition pos ) { this.source = source; - this.pos = pos; + this.pos = pos.asMessage(); } public SpeakerMoveClientMessage( FriendlyByteBuf buf ) { source = buf.readUUID(); - pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); + pos = SpeakerPosition.Message.read( buf ); } @Override public void toBytes( @Nonnull FriendlyByteBuf buf ) { buf.writeUUID( source ); - buf.writeDouble( pos.x() ); - buf.writeDouble( pos.y() ); - buf.writeDouble( pos.z() ); + pos.write( buf ); } @Override @OnlyIn( Dist.CLIENT ) public void handle( NetworkEvent.Context context ) { - SpeakerManager.moveSound( source, pos ); + SpeakerManager.moveSound( source, pos.reify() ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/SpeakerPlayClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/SpeakerPlayClientMessage.java index be341b49c..fe1e142b9 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/SpeakerPlayClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/SpeakerPlayClientMessage.java @@ -7,9 +7,9 @@ package dan200.computercraft.shared.network.client; import dan200.computercraft.client.sound.SpeakerManager; import dan200.computercraft.shared.network.NetworkMessage; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.network.NetworkEvent; @@ -27,15 +27,15 @@ import java.util.UUID; public class SpeakerPlayClientMessage implements NetworkMessage { private final UUID source; - private final Vec3 pos; + private final SpeakerPosition.Message pos; private final ResourceLocation sound; private final float volume; private final float pitch; - public SpeakerPlayClientMessage( UUID source, Vec3 pos, ResourceLocation event, float volume, float pitch ) + public SpeakerPlayClientMessage( UUID source, SpeakerPosition pos, ResourceLocation event, float volume, float pitch ) { this.source = source; - this.pos = pos; + this.pos = pos.asMessage(); sound = event; this.volume = volume; this.pitch = pitch; @@ -44,7 +44,7 @@ public class SpeakerPlayClientMessage implements NetworkMessage public SpeakerPlayClientMessage( FriendlyByteBuf buf ) { source = buf.readUUID(); - pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); + pos = SpeakerPosition.Message.read( buf ); sound = buf.readResourceLocation(); volume = buf.readFloat(); pitch = buf.readFloat(); @@ -54,9 +54,7 @@ public class SpeakerPlayClientMessage implements NetworkMessage public void toBytes( @Nonnull FriendlyByteBuf buf ) { buf.writeUUID( source ); - buf.writeDouble( pos.x() ); - buf.writeDouble( pos.y() ); - buf.writeDouble( pos.z() ); + pos.write( buf ); buf.writeResourceLocation( sound ); buf.writeFloat( volume ); buf.writeFloat( pitch ); @@ -66,6 +64,6 @@ public class SpeakerPlayClientMessage implements NetworkMessage @OnlyIn( Dist.CLIENT ) public void handle( NetworkEvent.Context context ) { - SpeakerManager.getSound( source ).playSound( pos, sound, volume, pitch ); + SpeakerManager.getSound( source ).playSound( pos.reify(), sound, volume, pitch ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index 7e4bf03b8..ed9970a5c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -29,7 +29,6 @@ import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.phys.Vec3; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.*; import static dan200.computercraft.api.lua.LuaValues.checkFinite; @@ -57,7 +56,7 @@ public abstract class SpeakerPeripheral implements IPeripheral private long clock = 0; private long lastPositionTime; - private Vec3 lastPosition; + private SpeakerPosition lastPosition; private long lastPlayTime; @@ -72,8 +71,9 @@ public abstract class SpeakerPeripheral implements IPeripheral { clock++; - Vec3 pos = getPosition(); - Level level = getLevel(); + SpeakerPosition position = getPosition(); + Level level = position.level(); + Vec3 pos = position.position(); if( level == null ) return; MinecraftServer server = level.getServer(); @@ -125,20 +125,20 @@ public abstract class SpeakerPeripheral implements IPeripheral { lastPlayTime = clock; NetworkHandler.sendToAllAround( - new SpeakerPlayClientMessage( getSource(), pos, sound.location, sound.volume, sound.pitch ), + new SpeakerPlayClientMessage( getSource(), position, sound.location, sound.volume, sound.pitch ), level, pos, sound.volume * 16 ); - syncedPosition( pos ); + syncedPosition( position ); } else if( dfpwmState != null && dfpwmState.shouldSendPending( now ) ) { // If clients need to receive another batch of audio, send it and then notify computers our internal buffer is // free again. NetworkHandler.sendToAllTracking( - new SpeakerAudioClientMessage( getSource(), pos, dfpwmState.getVolume(), dfpwmState.pullPending( now ) ), - getLevel().getChunkAt( new BlockPos( pos ) ) + new SpeakerAudioClientMessage( getSource(), position, dfpwmState.getVolume(), dfpwmState.pullPending( now ) ), + level.getChunkAt( new BlockPos( pos ) ) ); - syncedPosition( pos ); + syncedPosition( position ); // And notify computers that we have space for more audio. synchronized( computers ) @@ -153,25 +153,19 @@ public abstract class SpeakerPeripheral implements IPeripheral // Push position updates to any speakers which have ever played a note, // have moved by a non-trivial amount and haven't had a position update // in the last second. - if( lastPosition != null && (clock - lastPositionTime) >= 20 ) + if( lastPosition != null && (clock - lastPositionTime) >= 20 && !lastPosition.withinDistance( position, 0.1 ) ) { - Vec3 position = getPosition(); - if( lastPosition.distanceToSqr( position ) >= 0.1 ) - { - NetworkHandler.sendToAllTracking( - new SpeakerMoveClientMessage( getSource(), position ), - getLevel().getChunkAt( new BlockPos( position ) ) - ); - syncedPosition( position ); - } + // TODO: What to do when entities move away? How do we notify people left behind that they're gone. + NetworkHandler.sendToAllTracking( + new SpeakerMoveClientMessage( getSource(), position ), + level.getChunkAt( new BlockPos( pos ) ) + ); + syncedPosition( position ); } } - @Nullable - public abstract Level getLevel(); - @Nonnull - public abstract Vec3 getPosition(); + public abstract SpeakerPosition getPosition(); @Nonnull public UUID getSource() @@ -373,7 +367,7 @@ public abstract class SpeakerPeripheral implements IPeripheral shouldStop = true; } - private void syncedPosition( Vec3 position ) + private void syncedPosition( SpeakerPosition position ) { lastPosition = position; lastPositionTime = clock; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java new file mode 100644 index 000000000..5d602ea16 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java @@ -0,0 +1,88 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ +package dan200.computercraft.shared.peripheral.speaker; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.OptionalInt; + +public record SpeakerPosition(@Nullable Level level, @Nonnull Vec3 position, @Nullable Entity entity) +{ + public static SpeakerPosition of( @Nullable Level level, @Nonnull Vec3 position ) + { + return new SpeakerPosition( level, position, null ); + } + + public static SpeakerPosition of( @Nonnull Entity entity ) + { + return new SpeakerPosition( entity.level, entity.getEyePosition( 1 ), entity ); + } + + public boolean withinDistance( SpeakerPosition other, double distanceSq ) + { + return level == other.level && entity == other.entity && position.distanceToSqr( other.position ) <= distanceSq; + } + + public Message asMessage() + { + if( level == null ) throw new NullPointerException( "Cannot send a position without a level" ); + return new Message( level.dimension().getRegistryName(), position, entity == null ? OptionalInt.empty() : OptionalInt.of( entity.getId() ) ); + } + + public static final class Message + { + private final ResourceLocation level; + private final Vec3 position; + private final OptionalInt entity; + + private Message( ResourceLocation level, Vec3 position, OptionalInt entity ) + { + this.level = level; + this.position = position; + this.entity = entity; + } + + public static Message read( @Nonnull FriendlyByteBuf buffer ) + { + ResourceLocation level = buffer.readResourceLocation(); + Vec3 position = new Vec3( buffer.readDouble(), buffer.readDouble(), buffer.readDouble() ); + OptionalInt entity = buffer.readBoolean() ? OptionalInt.of( buffer.readInt() ) : OptionalInt.empty(); + return new Message( level, position, entity ); + } + + public void write( @Nonnull FriendlyByteBuf buffer ) + { + buffer.writeResourceLocation( level ); + + buffer.writeDouble( position.x ); + buffer.writeDouble( position.y ); + buffer.writeDouble( position.z ); + + buffer.writeBoolean( entity.isPresent() ); + if( entity.isPresent() ) buffer.writeInt( entity.getAsInt() ); + } + + @Nonnull + public SpeakerPosition reify() + { + Minecraft minecraft = Minecraft.getInstance(); + Level level = minecraft.level; + if( level != null && !level.dimension().getRegistryName().equals( this.level ) ) level = null; + + return new SpeakerPosition( + level, position, + level != null && entity.isPresent() ? level.getEntity( entity.getAsInt() ) : null + ); + } + } +} diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java index c44b460c4..11527a3b5 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java @@ -12,7 +12,6 @@ import dan200.computercraft.shared.network.client.SpeakerStopClientMessage; import dan200.computercraft.shared.util.CapabilityUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; @@ -79,17 +78,11 @@ public class TileSpeaker extends TileGeneric this.speaker = speaker; } - @Override - public Level getLevel() - { - return speaker.getLevel(); - } - @Nonnull @Override - public Vec3 getPosition() + public SpeakerPosition getPosition() { - return Vec3.atCenterOf( speaker.getBlockPos() ); + return SpeakerPosition.of( speaker.getLevel(), Vec3.atCenterOf( speaker.getBlockPos() ) ); } @Override diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index 374bb1f23..f47b2efb9 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -21,6 +21,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +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.item.ItemStack; @@ -60,6 +61,10 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces { return living.getMainHandItem() == stack || living.getOffhandItem() == stack ? entity : null; } + else if( entity instanceof ItemEntity itemEntity ) + { + return itemEntity.getItem() == stack ? entity : null; + } else { return null; diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java index 959cfcca6..d18630336 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java @@ -10,7 +10,6 @@ import dan200.computercraft.api.pocket.AbstractPocketUpgrade; import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; import javax.annotation.Nonnull; @@ -27,21 +26,13 @@ public class PocketSpeaker extends AbstractPocketUpgrade @Override public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) { - return new PocketSpeakerPeripheral(); + return new PocketSpeakerPeripheral( access ); } @Override public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) { - if( !(peripheral instanceof PocketSpeakerPeripheral speaker) ) return; - - Entity entity = access.getEntity(); - if( entity != null ) - { - speaker.setLocation( entity.getCommandSenderWorld(), entity.getEyePosition( 1 ) ); - } - - speaker.update(); - access.setLight( speaker.madeSound() ? 0x3320fc : -1 ); + if( !(peripheral instanceof PocketSpeakerPeripheral) ) return; + ((PocketSpeakerPeripheral) peripheral).update(); } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java index 38869fda4..ed28046ac 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java @@ -6,7 +6,10 @@ package dan200.computercraft.shared.pocket.peripherals; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -14,26 +17,21 @@ import javax.annotation.Nonnull; public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral { - private Level world = null; + private final IPocketAccess access; + private Level level; private Vec3 position = Vec3.ZERO; - void setLocation( Level world, Vec3 position ) + public PocketSpeakerPeripheral( IPocketAccess access ) { - this.position = position; - this.world = world; - } - - @Override - public Level getLevel() - { - return world; + this.access = access; } @Nonnull @Override - public Vec3 getPosition() + public SpeakerPosition getPosition() { - return world != null ? position : null; + Entity entity = access.getEntity(); + return entity == null ? SpeakerPosition.of( level, position ) : SpeakerPosition.of( entity ); } @Override @@ -41,4 +39,19 @@ public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral { return other instanceof PocketSpeakerPeripheral; } + + @Override + public void update() + { + Entity entity = access.getEntity(); + if( entity != null ) + { + level = entity.level; + position = entity.position(); + } + + super.update(); + + access.setLight( madeSound() ? 0x3320fc : -1 ); + } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java index 650a4fa10..33f694f69 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java @@ -11,11 +11,11 @@ import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleUpgradeType; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -36,17 +36,11 @@ public class TurtleSpeaker extends AbstractTurtleUpgrade this.turtle = turtle; } - @Override - public Level getLevel() - { - return turtle.getLevel(); - } - @Nonnull @Override - public Vec3 getPosition() + public SpeakerPosition getPosition() { - return Vec3.atCenterOf( turtle.getPosition() ); + return SpeakerPosition.of( turtle.getLevel(), Vec3.atCenterOf( turtle.getPosition() ) ); } @Override