From f2474bbfa2ad99b1580b5ef4431b3ee1ce70d22b Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 28 Apr 2022 17:41:07 +0100 Subject: [PATCH 1/3] Remove redundant class --- .../client/render/TurtlePlayerRenderer.java | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java 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 2a0371264..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.matrix.MatrixStack; -import dan200.computercraft.shared.turtle.core.TurtlePlayer; -import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.entity.EntityRenderer; -import net.minecraft.client.renderer.entity.EntityRendererManager; -import net.minecraft.util.ResourceLocation; - -import javax.annotation.Nonnull; - -public class TurtlePlayerRenderer extends EntityRenderer -{ - public TurtlePlayerRenderer( EntityRendererManager 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 MatrixStack transform, @Nonnull IRenderTypeBuffer buffer, int packedLightIn ) - { - } -} From 118b89ea415aea9e10637eb221dc29c338339041 Mon Sep 17 00:00:00 2001 From: Cloud Chagnon Date: Thu, 28 Apr 2022 17:42:04 +0100 Subject: [PATCH 2/3] Fix off by one error in printout renderer Fixes printouts being drawn slightly offset to the left in all cases, noticeable mainly when in item frames. --- .../computercraft/client/render/ItemPrintoutRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java index 17333c73c..77d44df09 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java @@ -86,7 +86,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; From 9cb7a5bec72db375e1111f7355bb3c58dd70ba35 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 28 Apr 2022 19:54:28 +0100 Subject: [PATCH 3/3] Track owning entity when sending sounds This allows us to sync the position to the entity immediately, rather than the sound jumping about. Someone has set up rick-rolling pocket computers (<3 to whoever did this), and the lag on them irritates me enough to fix this. Fixes #1074 --- .../client/sound/SpeakerInstance.java | 8 +- .../client/sound/SpeakerManager.java | 4 +- .../client/sound/SpeakerSound.java | 32 +++-- .../client/SpeakerAudioClientMessage.java | 16 ++- .../client/SpeakerMoveClientMessage.java | 16 ++- .../client/SpeakerPlayClientMessage.java | 16 ++- .../peripheral/speaker/SpeakerPeripheral.java | 50 ++++---- .../peripheral/speaker/SpeakerPosition.java | 117 ++++++++++++++++++ .../peripheral/speaker/TileSpeaker.java | 11 +- .../pocket/core/PocketServerComputer.java | 6 + .../pocket/peripherals/PocketSpeaker.java | 15 +-- .../peripherals/PocketSpeakerPeripheral.java | 37 ++++-- .../shared/turtle/upgrades/TurtleSpeaker.java | 12 +- 13 files changed, 229 insertions(+), 111 deletions(-) create mode 100644 src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java diff --git a/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java b/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java index 62fed7d8c..d6c94dbba 100644 --- a/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java +++ b/src/main/java/dan200/computercraft/client/sound/SpeakerInstance.java @@ -6,11 +6,11 @@ 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.client.audio.SoundHandler; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.vector.Vector3d; /** * An instance of a speaker, which is either playing a {@link DfpwmStream} stream or a normal sound. @@ -44,7 +44,7 @@ public class SpeakerInstance } } - public void playAudio( Vector3d position, float volume ) + public void playAudio( SpeakerPosition position, float volume ) { SoundHandler soundManager = Minecraft.getInstance().getSoundManager(); @@ -63,7 +63,7 @@ public class SpeakerInstance } } - public void playSound( Vector3d position, ResourceLocation location, float volume, float pitch ) + public void playSound( SpeakerPosition position, ResourceLocation location, float volume, float pitch ) { SoundHandler soundManager = Minecraft.getInstance().getSoundManager(); currentStream = null; @@ -78,7 +78,7 @@ public class SpeakerInstance soundManager.play( sound ); } - void setPosition( Vector3d 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 0f28c562e..2879d52d3 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.util.math.vector.Vector3d; +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; @@ -48,7 +48,7 @@ public class SpeakerManager if( sound != null ) sound.stop(); } - public static void moveSound( UUID source, Vector3d 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 d39390993..e1ef98159 100644 --- a/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java +++ b/src/main/java/dan200/computercraft/client/sound/SpeakerSound.java @@ -5,13 +5,14 @@ */ package dan200.computercraft.client.sound; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.client.audio.IAudioStream; import net.minecraft.client.audio.ITickableSound; import net.minecraft.client.audio.LocatableSound; import net.minecraft.client.audio.SoundSource; +import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.vector.Vector3d; import javax.annotation.Nullable; import java.util.concurrent.Executor; @@ -22,7 +23,11 @@ public class SpeakerSound extends LocatableSound implements ITickableSound Executor executor; DfpwmStream stream; - SpeakerSound( ResourceLocation sound, DfpwmStream stream, Vector3d 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, SoundCategory.RECORDS ); setPosition( position ); @@ -32,22 +37,35 @@ public class SpeakerSound extends LocatableSound implements ITickableSound attenuation = AttenuationType.LINEAR; } - void setPosition( Vector3d 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(); + } } @Nullable 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 6aec3ed58..57f8ba342 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.PacketBuffer; -import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.network.NetworkEvent; @@ -27,14 +27,14 @@ import java.util.UUID; public class SpeakerAudioClientMessage implements NetworkMessage { private final UUID source; - private final Vector3d pos; + private final SpeakerPosition.Message pos; private final ByteBuffer content; private final float volume; - public SpeakerAudioClientMessage( UUID source, Vector3d 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( PacketBuffer buf ) { source = buf.readUUID(); - pos = new Vector3d( 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 PacketBuffer 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 9082d2457..2fc17a053 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.PacketBuffer; -import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.network.NetworkEvent; @@ -26,33 +26,31 @@ import java.util.UUID; public class SpeakerMoveClientMessage implements NetworkMessage { private final UUID source; - private final Vector3d pos; + private final SpeakerPosition.Message pos; - public SpeakerMoveClientMessage( UUID source, Vector3d pos ) + public SpeakerMoveClientMessage( UUID source, SpeakerPosition pos ) { this.source = source; - this.pos = pos; + this.pos = pos.asMessage(); } public SpeakerMoveClientMessage( PacketBuffer buf ) { source = buf.readUUID(); - pos = new Vector3d( buf.readDouble(), buf.readDouble(), buf.readDouble() ); + pos = SpeakerPosition.Message.read( buf ); } @Override public void toBytes( @Nonnull PacketBuffer 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 419bb6ae4..692eb7733 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.PacketBuffer; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.network.NetworkEvent; @@ -27,15 +27,15 @@ import java.util.UUID; public class SpeakerPlayClientMessage implements NetworkMessage { private final UUID source; - private final Vector3d pos; + private final SpeakerPosition.Message pos; private final ResourceLocation sound; private final float volume; private final float pitch; - public SpeakerPlayClientMessage( UUID source, Vector3d 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( PacketBuffer buf ) { source = buf.readUUID(); - pos = new Vector3d( 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 PacketBuffer 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 43dc185ba..56ff2c96b 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.util.math.vector.Vector3d; import net.minecraft.world.World; 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 Vector3d lastPosition; + private SpeakerPosition lastPosition; private long lastPlayTime; @@ -72,10 +71,11 @@ public abstract class SpeakerPeripheral implements IPeripheral { clock++; - Vector3d pos = getPosition(); - World world = getWorld(); - if( world == null ) return; - MinecraftServer server = world.getServer(); + SpeakerPosition position = getPosition(); + World level = position.level(); + Vector3d pos = position.position(); + if( level == null ) return; + MinecraftServer server = level.getServer(); synchronized( pendingNotes ) { @@ -83,7 +83,7 @@ public abstract class SpeakerPeripheral implements IPeripheral { lastPlayTime = clock; server.getPlayerList().broadcast( - null, pos.x, pos.y, pos.z, sound.volume * 16, world.dimension(), + null, pos.x, pos.y, pos.z, sound.volume * 16, level.dimension(), new SPlaySoundPacket( sound.location, SoundCategory.RECORDS, pos, sound.volume, sound.pitch ) ); } @@ -125,20 +125,20 @@ public abstract class SpeakerPeripheral implements IPeripheral { lastPlayTime = clock; NetworkHandler.sendToAllAround( - new SpeakerPlayClientMessage( getSource(), pos, sound.location, sound.volume, sound.pitch ), - world, pos, sound.volume * 16 + 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 ) ), - getWorld().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 ) ) { - Vector3d position = getPosition(); - if( lastPosition.distanceToSqr( position ) >= 0.1 ) - { - NetworkHandler.sendToAllTracking( - new SpeakerMoveClientMessage( getSource(), position ), - getWorld().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 World getWorld(); - @Nonnull - public abstract Vector3d getPosition(); + public abstract SpeakerPosition getPosition(); @Nonnull public UUID getSource() @@ -373,7 +367,7 @@ public abstract class SpeakerPeripheral implements IPeripheral shouldStop = true; } - private void syncedPosition( Vector3d 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..6331e76d3 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java @@ -0,0 +1,117 @@ +/* + * 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.entity.Entity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.OptionalInt; + +public final class SpeakerPosition +{ + private final World level; + private final Vector3d position; + private final Entity entity; + + private SpeakerPosition( @Nullable World level, @Nonnull Vector3d position, @Nullable Entity entity ) + { + this.level = level; + this.position = position; + this.entity = entity; + } + + public static SpeakerPosition of( @Nullable World level, @Nonnull Vector3d position ) + { + return new SpeakerPosition( level, position, null ); + } + + public static SpeakerPosition of( @Nonnull Entity entity ) + { + return new SpeakerPosition( entity.level, entity.getEyePosition( 1 ), entity ); + } + + @Nullable + public World level() + { + return level; + } + + @Nonnull + public Vector3d position() + { + return position; + } + + @Nullable + public Entity entity() + { + return 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 Vector3d position; + private final OptionalInt entity; + + private Message( ResourceLocation level, Vector3d position, OptionalInt entity ) + { + this.level = level; + this.position = position; + this.entity = entity; + } + + public static Message read( @Nonnull PacketBuffer buffer ) + { + ResourceLocation level = buffer.readResourceLocation(); + Vector3d position = new Vector3d( 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 PacketBuffer 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(); + World 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 4c78ea7c2..6b8b8d5a0 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java @@ -14,7 +14,6 @@ import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; @@ -79,17 +78,11 @@ public class TileSpeaker extends TileGeneric implements ITickableTileEntity this.speaker = speaker; } - @Override - public World getWorld() - { - return speaker.getLevel(); - } - @Nonnull @Override - public Vector3d getPosition() + public SpeakerPosition getPosition() { - return Vector3d.atCenterOf( speaker.getBlockPos() ); + return SpeakerPosition.of( speaker.getLevel(), Vector3d.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 e3066c5ff..9d894980c 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -17,6 +17,7 @@ import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.ServerPlayerEntity; @@ -61,6 +62,11 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces LivingEntity living = (LivingEntity) entity; return living.getMainHandItem() == stack || living.getOffhandItem() == stack ? entity : null; } + else if( entity instanceof ItemEntity ) + { + ItemEntity itemEntity = (ItemEntity) entity; + 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 cb58ee99d..2299ea554 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java @@ -9,7 +9,6 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.AbstractPocketUpgrade; import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.shared.Registry; -import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; import javax.annotation.Nonnull; @@ -26,23 +25,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) ) return; - - PocketSpeakerPeripheral speaker = (PocketSpeakerPeripheral) peripheral; - - Entity entity = access.getEntity(); - if( entity != null ) - { - speaker.setLocation( entity.getCommandSenderWorld(), entity.getEyePosition( 1 ) ); - } - - speaker.update(); - access.setLight( speaker.madeSound() ? 0x3320fc : -1 ); + ((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 e86762b62..fd00ccc28 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.entity.Entity; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; @@ -14,26 +17,21 @@ import javax.annotation.Nonnull; public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral { - private World world = null; + private final IPocketAccess access; + private World level; private Vector3d position = Vector3d.ZERO; - void setLocation( World world, Vector3d position ) + public PocketSpeakerPeripheral( IPocketAccess access ) { - this.position = position; - this.world = world; - } - - @Override - public World getWorld() - { - return world; + this.access = access; } @Nonnull @Override - public Vector3d 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 1188a28bc..988acffd0 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java @@ -12,11 +12,11 @@ import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleUpgradeType; import dan200.computercraft.shared.Registry; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; import net.minecraft.client.renderer.model.ModelResourceLocation; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.world.World; 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 World getWorld() - { - return turtle.getWorld(); - } - @Nonnull @Override - public Vector3d getPosition() + public SpeakerPosition getPosition() { - return Vector3d.atCenterOf( turtle.getPosition() ); + return SpeakerPosition.of( turtle.getWorld(), Vector3d.atCenterOf( turtle.getPosition() ) ); } @Override