mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Merge branch 'mc-1.16.x' into mc-1.18.x
This commit is contained in:
		| @@ -19,9 +19,9 @@ import net.minecraftforge.client.event.RenderItemInFrameEvent; | |||||||
| import net.minecraftforge.eventbus.api.SubscribeEvent; | import net.minecraftforge.eventbus.api.SubscribeEvent; | ||||||
| import net.minecraftforge.fml.common.Mod; | 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_HEIGHT; | ||||||
| import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH; | 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.LINES_PER_PAGE; | ||||||
| import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; | 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; |         double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2; | ||||||
| 
 | 
 | ||||||
|         // Non-books will be left aligned |         // Non-books will be left aligned | ||||||
|         if( !book ) width += offsetAt( pages ); |         if( !book ) width += offsetAt( pages - 1 ); | ||||||
| 
 | 
 | ||||||
|         double visualWidth = width, visualHeight = height; |         double visualWidth = width, visualHeight = height; | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -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<TurtlePlayer> |  | ||||||
| { |  | ||||||
|     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 ) |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -6,10 +6,10 @@ | |||||||
| package dan200.computercraft.client.sound; | package dan200.computercraft.client.sound; | ||||||
| 
 | 
 | ||||||
| import dan200.computercraft.ComputerCraft; | import dan200.computercraft.ComputerCraft; | ||||||
|  | import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; | ||||||
| import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||||||
| import net.minecraft.client.Minecraft; | import net.minecraft.client.Minecraft; | ||||||
| import net.minecraft.resources.ResourceLocation; | 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. |  * 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(); |         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(); |         var soundManager = Minecraft.getInstance().getSoundManager(); | ||||||
|         currentStream = null; |         currentStream = null; | ||||||
| @@ -77,7 +77,7 @@ public class SpeakerInstance | |||||||
|         soundManager.play( sound ); |         soundManager.play( sound ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void setPosition( Vec3 position ) |     void setPosition( SpeakerPosition position ) | ||||||
|     { |     { | ||||||
|         if( sound != null ) sound.setPosition( position ); |         if( sound != null ) sound.setPosition( position ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  */ |  */ | ||||||
| package dan200.computercraft.client.sound; | 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.api.distmarker.Dist; | ||||||
| import net.minecraftforge.client.event.sound.PlayStreamingSourceEvent; | import net.minecraftforge.client.event.sound.PlayStreamingSourceEvent; | ||||||
| import net.minecraftforge.eventbus.api.SubscribeEvent; | import net.minecraftforge.eventbus.api.SubscribeEvent; | ||||||
| @@ -44,7 +44,7 @@ public class SpeakerManager | |||||||
|         if( sound != null ) sound.stop(); |         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 ); |         SpeakerInstance sound = sounds.get( source ); | ||||||
|         if( sound != null ) sound.setPosition( position ); |         if( sound != null ) sound.setPosition( position ); | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| package dan200.computercraft.client.sound; | package dan200.computercraft.client.sound; | ||||||
| 
 | 
 | ||||||
| import com.mojang.blaze3d.audio.Channel; | 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.AbstractSoundInstance; | ||||||
| import net.minecraft.client.resources.sounds.Sound; | import net.minecraft.client.resources.sounds.Sound; | ||||||
| import net.minecraft.client.resources.sounds.TickableSoundInstance; | 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.client.sounds.SoundBufferLibrary; | ||||||
| import net.minecraft.resources.ResourceLocation; | import net.minecraft.resources.ResourceLocation; | ||||||
| import net.minecraft.sounds.SoundSource; | import net.minecraft.sounds.SoundSource; | ||||||
| import net.minecraft.world.phys.Vec3; | import net.minecraft.world.entity.Entity; | ||||||
| 
 | 
 | ||||||
| import javax.annotation.Nonnull; | import javax.annotation.Nonnull; | ||||||
| import java.util.concurrent.CompletableFuture; | import java.util.concurrent.CompletableFuture; | ||||||
| @@ -25,7 +26,11 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound | |||||||
|     Executor executor; |     Executor executor; | ||||||
|     DfpwmStream stream; |     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 ); |         super( sound, SoundSource.RECORDS ); | ||||||
|         setPosition( position ); |         setPosition( position ); | ||||||
| @@ -35,22 +40,35 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound | |||||||
|         attenuation = Attenuation.LINEAR; |         attenuation = Attenuation.LINEAR; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void setPosition( Vec3 position ) |     void setPosition( SpeakerPosition position ) | ||||||
|     { |     { | ||||||
|         x = (float) position.x(); |         x = position.position().x; | ||||||
|         y = (float) position.y(); |         y = position.position().y; | ||||||
|         z = (float) position.z(); |         z = position.position().z; | ||||||
|  |         entity = position.entity(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public boolean isStopped() |     public boolean isStopped() | ||||||
|     { |     { | ||||||
|         return false; |         return stopped; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void tick() |     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 |     @Nonnull | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ package dan200.computercraft.shared.network.client; | |||||||
| 
 | 
 | ||||||
| import dan200.computercraft.client.sound.SpeakerManager; | import dan200.computercraft.client.sound.SpeakerManager; | ||||||
| import dan200.computercraft.shared.network.NetworkMessage; | import dan200.computercraft.shared.network.NetworkMessage; | ||||||
|  | import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; | ||||||
| import net.minecraft.network.FriendlyByteBuf; | import net.minecraft.network.FriendlyByteBuf; | ||||||
| import net.minecraft.world.phys.Vec3; |  | ||||||
| import net.minecraftforge.api.distmarker.Dist; | import net.minecraftforge.api.distmarker.Dist; | ||||||
| import net.minecraftforge.api.distmarker.OnlyIn; | import net.minecraftforge.api.distmarker.OnlyIn; | ||||||
| import net.minecraftforge.network.NetworkEvent; | import net.minecraftforge.network.NetworkEvent; | ||||||
| @@ -27,14 +27,14 @@ import java.util.UUID; | |||||||
| public class SpeakerAudioClientMessage implements NetworkMessage | public class SpeakerAudioClientMessage implements NetworkMessage | ||||||
| { | { | ||||||
|     private final UUID source; |     private final UUID source; | ||||||
|     private final Vec3 pos; |     private final SpeakerPosition.Message pos; | ||||||
|     private final ByteBuffer content; |     private final ByteBuffer content; | ||||||
|     private final float volume; |     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.source = source; | ||||||
|         this.pos = pos; |         this.pos = pos.asMessage(); | ||||||
|         this.content = content; |         this.content = content; | ||||||
|         this.volume = volume; |         this.volume = volume; | ||||||
|     } |     } | ||||||
| @@ -42,7 +42,7 @@ public class SpeakerAudioClientMessage implements NetworkMessage | |||||||
|     public SpeakerAudioClientMessage( FriendlyByteBuf buf ) |     public SpeakerAudioClientMessage( FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         source = buf.readUUID(); |         source = buf.readUUID(); | ||||||
|         pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); |         pos = SpeakerPosition.Message.read( buf ); | ||||||
|         volume = buf.readFloat(); |         volume = buf.readFloat(); | ||||||
| 
 | 
 | ||||||
|         SpeakerManager.getSound( source ).pushAudio( buf ); |         SpeakerManager.getSound( source ).pushAudio( buf ); | ||||||
| @@ -53,9 +53,7 @@ public class SpeakerAudioClientMessage implements NetworkMessage | |||||||
|     public void toBytes( @Nonnull FriendlyByteBuf buf ) |     public void toBytes( @Nonnull FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         buf.writeUUID( source ); |         buf.writeUUID( source ); | ||||||
|         buf.writeDouble( pos.x() ); |         pos.write( buf ); | ||||||
|         buf.writeDouble( pos.y() ); |  | ||||||
|         buf.writeDouble( pos.z() ); |  | ||||||
|         buf.writeFloat( volume ); |         buf.writeFloat( volume ); | ||||||
|         buf.writeBytes( content.duplicate() ); |         buf.writeBytes( content.duplicate() ); | ||||||
|     } |     } | ||||||
| @@ -64,6 +62,6 @@ public class SpeakerAudioClientMessage implements NetworkMessage | |||||||
|     @OnlyIn( Dist.CLIENT ) |     @OnlyIn( Dist.CLIENT ) | ||||||
|     public void handle( NetworkEvent.Context context ) |     public void handle( NetworkEvent.Context context ) | ||||||
|     { |     { | ||||||
|         SpeakerManager.getSound( source ).playAudio( pos, volume ); |         SpeakerManager.getSound( source ).playAudio( pos.reify(), volume ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ package dan200.computercraft.shared.network.client; | |||||||
| 
 | 
 | ||||||
| import dan200.computercraft.client.sound.SpeakerManager; | import dan200.computercraft.client.sound.SpeakerManager; | ||||||
| import dan200.computercraft.shared.network.NetworkMessage; | import dan200.computercraft.shared.network.NetworkMessage; | ||||||
|  | import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; | ||||||
| import net.minecraft.network.FriendlyByteBuf; | import net.minecraft.network.FriendlyByteBuf; | ||||||
| import net.minecraft.world.phys.Vec3; |  | ||||||
| import net.minecraftforge.api.distmarker.Dist; | import net.minecraftforge.api.distmarker.Dist; | ||||||
| import net.minecraftforge.api.distmarker.OnlyIn; | import net.minecraftforge.api.distmarker.OnlyIn; | ||||||
| import net.minecraftforge.network.NetworkEvent; | import net.minecraftforge.network.NetworkEvent; | ||||||
| @@ -26,33 +26,31 @@ import java.util.UUID; | |||||||
| public class SpeakerMoveClientMessage implements NetworkMessage | public class SpeakerMoveClientMessage implements NetworkMessage | ||||||
| { | { | ||||||
|     private final UUID source; |     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.source = source; | ||||||
|         this.pos = pos; |         this.pos = pos.asMessage(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public SpeakerMoveClientMessage( FriendlyByteBuf buf ) |     public SpeakerMoveClientMessage( FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         source = buf.readUUID(); |         source = buf.readUUID(); | ||||||
|         pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); |         pos = SpeakerPosition.Message.read( buf ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void toBytes( @Nonnull FriendlyByteBuf buf ) |     public void toBytes( @Nonnull FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         buf.writeUUID( source ); |         buf.writeUUID( source ); | ||||||
|         buf.writeDouble( pos.x() ); |         pos.write( buf ); | ||||||
|         buf.writeDouble( pos.y() ); |  | ||||||
|         buf.writeDouble( pos.z() ); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     @OnlyIn( Dist.CLIENT ) |     @OnlyIn( Dist.CLIENT ) | ||||||
|     public void handle( NetworkEvent.Context context ) |     public void handle( NetworkEvent.Context context ) | ||||||
|     { |     { | ||||||
|         SpeakerManager.moveSound( source, pos ); |         SpeakerManager.moveSound( source, pos.reify() ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,9 +7,9 @@ package dan200.computercraft.shared.network.client; | |||||||
| 
 | 
 | ||||||
| import dan200.computercraft.client.sound.SpeakerManager; | import dan200.computercraft.client.sound.SpeakerManager; | ||||||
| import dan200.computercraft.shared.network.NetworkMessage; | import dan200.computercraft.shared.network.NetworkMessage; | ||||||
|  | import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; | ||||||
| import net.minecraft.network.FriendlyByteBuf; | import net.minecraft.network.FriendlyByteBuf; | ||||||
| import net.minecraft.resources.ResourceLocation; | import net.minecraft.resources.ResourceLocation; | ||||||
| import net.minecraft.world.phys.Vec3; |  | ||||||
| import net.minecraftforge.api.distmarker.Dist; | import net.minecraftforge.api.distmarker.Dist; | ||||||
| import net.minecraftforge.api.distmarker.OnlyIn; | import net.minecraftforge.api.distmarker.OnlyIn; | ||||||
| import net.minecraftforge.network.NetworkEvent; | import net.minecraftforge.network.NetworkEvent; | ||||||
| @@ -27,15 +27,15 @@ import java.util.UUID; | |||||||
| public class SpeakerPlayClientMessage implements NetworkMessage | public class SpeakerPlayClientMessage implements NetworkMessage | ||||||
| { | { | ||||||
|     private final UUID source; |     private final UUID source; | ||||||
|     private final Vec3 pos; |     private final SpeakerPosition.Message pos; | ||||||
|     private final ResourceLocation sound; |     private final ResourceLocation sound; | ||||||
|     private final float volume; |     private final float volume; | ||||||
|     private final float pitch; |     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.source = source; | ||||||
|         this.pos = pos; |         this.pos = pos.asMessage(); | ||||||
|         sound = event; |         sound = event; | ||||||
|         this.volume = volume; |         this.volume = volume; | ||||||
|         this.pitch = pitch; |         this.pitch = pitch; | ||||||
| @@ -44,7 +44,7 @@ public class SpeakerPlayClientMessage implements NetworkMessage | |||||||
|     public SpeakerPlayClientMessage( FriendlyByteBuf buf ) |     public SpeakerPlayClientMessage( FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         source = buf.readUUID(); |         source = buf.readUUID(); | ||||||
|         pos = new Vec3( buf.readDouble(), buf.readDouble(), buf.readDouble() ); |         pos = SpeakerPosition.Message.read( buf ); | ||||||
|         sound = buf.readResourceLocation(); |         sound = buf.readResourceLocation(); | ||||||
|         volume = buf.readFloat(); |         volume = buf.readFloat(); | ||||||
|         pitch = buf.readFloat(); |         pitch = buf.readFloat(); | ||||||
| @@ -54,9 +54,7 @@ public class SpeakerPlayClientMessage implements NetworkMessage | |||||||
|     public void toBytes( @Nonnull FriendlyByteBuf buf ) |     public void toBytes( @Nonnull FriendlyByteBuf buf ) | ||||||
|     { |     { | ||||||
|         buf.writeUUID( source ); |         buf.writeUUID( source ); | ||||||
|         buf.writeDouble( pos.x() ); |         pos.write( buf ); | ||||||
|         buf.writeDouble( pos.y() ); |  | ||||||
|         buf.writeDouble( pos.z() ); |  | ||||||
|         buf.writeResourceLocation( sound ); |         buf.writeResourceLocation( sound ); | ||||||
|         buf.writeFloat( volume ); |         buf.writeFloat( volume ); | ||||||
|         buf.writeFloat( pitch ); |         buf.writeFloat( pitch ); | ||||||
| @@ -66,6 +64,6 @@ public class SpeakerPlayClientMessage implements NetworkMessage | |||||||
|     @OnlyIn( Dist.CLIENT ) |     @OnlyIn( Dist.CLIENT ) | ||||||
|     public void handle( NetworkEvent.Context context ) |     public void handle( NetworkEvent.Context context ) | ||||||
|     { |     { | ||||||
|         SpeakerManager.getSound( source ).playSound( pos, sound, volume, pitch ); |         SpeakerManager.getSound( source ).playSound( pos.reify(), sound, volume, pitch ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; | |||||||
| import net.minecraft.world.phys.Vec3; | import net.minecraft.world.phys.Vec3; | ||||||
| 
 | 
 | ||||||
| import javax.annotation.Nonnull; | import javax.annotation.Nonnull; | ||||||
| import javax.annotation.Nullable; |  | ||||||
| import java.util.*; | import java.util.*; | ||||||
| 
 | 
 | ||||||
| import static dan200.computercraft.api.lua.LuaValues.checkFinite; | import static dan200.computercraft.api.lua.LuaValues.checkFinite; | ||||||
| @@ -57,7 +56,7 @@ public abstract class SpeakerPeripheral implements IPeripheral | |||||||
| 
 | 
 | ||||||
|     private long clock = 0; |     private long clock = 0; | ||||||
|     private long lastPositionTime; |     private long lastPositionTime; | ||||||
|     private Vec3 lastPosition; |     private SpeakerPosition lastPosition; | ||||||
| 
 | 
 | ||||||
|     private long lastPlayTime; |     private long lastPlayTime; | ||||||
| 
 | 
 | ||||||
| @@ -72,8 +71,9 @@ public abstract class SpeakerPeripheral implements IPeripheral | |||||||
|     { |     { | ||||||
|         clock++; |         clock++; | ||||||
| 
 | 
 | ||||||
|         Vec3 pos = getPosition(); |         SpeakerPosition position = getPosition(); | ||||||
|         Level level = getLevel(); |         Level level = position.level(); | ||||||
|  |         Vec3 pos = position.position(); | ||||||
|         if( level == null ) return; |         if( level == null ) return; | ||||||
|         MinecraftServer server = level.getServer(); |         MinecraftServer server = level.getServer(); | ||||||
| 
 | 
 | ||||||
| @@ -125,20 +125,20 @@ public abstract class SpeakerPeripheral implements IPeripheral | |||||||
|         { |         { | ||||||
|             lastPlayTime = clock; |             lastPlayTime = clock; | ||||||
|             NetworkHandler.sendToAllAround( |             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 |                 level, pos, sound.volume * 16 | ||||||
|             ); |             ); | ||||||
|             syncedPosition( pos ); |             syncedPosition( position ); | ||||||
|         } |         } | ||||||
|         else if( dfpwmState != null && dfpwmState.shouldSendPending( now ) ) |         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 |             // If clients need to receive another batch of audio, send it and then notify computers our internal buffer is | ||||||
|             // free again. |             // free again. | ||||||
|             NetworkHandler.sendToAllTracking( |             NetworkHandler.sendToAllTracking( | ||||||
|                 new SpeakerAudioClientMessage( getSource(), pos, dfpwmState.getVolume(), dfpwmState.pullPending( now ) ), |                 new SpeakerAudioClientMessage( getSource(), position, dfpwmState.getVolume(), dfpwmState.pullPending( now ) ), | ||||||
|                 getLevel().getChunkAt( new BlockPos( pos ) ) |                 level.getChunkAt( new BlockPos( pos ) ) | ||||||
|             ); |             ); | ||||||
|             syncedPosition( pos ); |             syncedPosition( position ); | ||||||
| 
 | 
 | ||||||
|             // And notify computers that we have space for more audio. |             // And notify computers that we have space for more audio. | ||||||
|             synchronized( computers ) |             synchronized( computers ) | ||||||
| @@ -153,25 +153,19 @@ public abstract class SpeakerPeripheral implements IPeripheral | |||||||
|         // Push position updates to any speakers which have ever played a note, |         // 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 |         // have moved by a non-trivial amount and haven't had a position update | ||||||
|         // in the last second. |         // in the last second. | ||||||
|         if( lastPosition != null && (clock - lastPositionTime) >= 20 ) |         if( lastPosition != null && (clock - lastPositionTime) >= 20 && !lastPosition.withinDistance( position, 0.1 ) ) | ||||||
|         { |         { | ||||||
|             Vec3 position = getPosition(); |             // TODO: What to do when entities move away? How do we notify people left behind that they're gone. | ||||||
|             if( lastPosition.distanceToSqr( position ) >= 0.1 ) |             NetworkHandler.sendToAllTracking( | ||||||
|             { |                 new SpeakerMoveClientMessage( getSource(), position ), | ||||||
|                 NetworkHandler.sendToAllTracking( |                 level.getChunkAt( new BlockPos( pos ) ) | ||||||
|                     new SpeakerMoveClientMessage( getSource(), position ), |             ); | ||||||
|                     getLevel().getChunkAt( new BlockPos( position ) ) |             syncedPosition( position ); | ||||||
|                 ); |  | ||||||
|                 syncedPosition( position ); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Nullable |  | ||||||
|     public abstract Level getLevel(); |  | ||||||
| 
 |  | ||||||
|     @Nonnull |     @Nonnull | ||||||
|     public abstract Vec3 getPosition(); |     public abstract SpeakerPosition getPosition(); | ||||||
| 
 | 
 | ||||||
|     @Nonnull |     @Nonnull | ||||||
|     public UUID getSource() |     public UUID getSource() | ||||||
| @@ -373,7 +367,7 @@ public abstract class SpeakerPeripheral implements IPeripheral | |||||||
|         shouldStop = true; |         shouldStop = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void syncedPosition( Vec3 position ) |     private void syncedPosition( SpeakerPosition position ) | ||||||
|     { |     { | ||||||
|         lastPosition = position; |         lastPosition = position; | ||||||
|         lastPositionTime = clock; |         lastPositionTime = clock; | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -12,7 +12,6 @@ import dan200.computercraft.shared.network.client.SpeakerStopClientMessage; | |||||||
| import dan200.computercraft.shared.util.CapabilityUtil; | import dan200.computercraft.shared.util.CapabilityUtil; | ||||||
| import net.minecraft.core.BlockPos; | import net.minecraft.core.BlockPos; | ||||||
| import net.minecraft.core.Direction; | 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.entity.BlockEntityType; | ||||||
| import net.minecraft.world.level.block.state.BlockState; | import net.minecraft.world.level.block.state.BlockState; | ||||||
| import net.minecraft.world.phys.Vec3; | import net.minecraft.world.phys.Vec3; | ||||||
| @@ -79,17 +78,11 @@ public class TileSpeaker extends TileGeneric | |||||||
|             this.speaker = speaker; |             this.speaker = speaker; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |  | ||||||
|         public Level getLevel() |  | ||||||
|         { |  | ||||||
|             return speaker.getLevel(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Nonnull |         @Nonnull | ||||||
|         @Override |         @Override | ||||||
|         public Vec3 getPosition() |         public SpeakerPosition getPosition() | ||||||
|         { |         { | ||||||
|             return Vec3.atCenterOf( speaker.getBlockPos() ); |             return SpeakerPosition.of( speaker.getLevel(), Vec3.atCenterOf( speaker.getBlockPos() ) ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ import net.minecraft.resources.ResourceLocation; | |||||||
| import net.minecraft.server.level.ServerPlayer; | import net.minecraft.server.level.ServerPlayer; | ||||||
| import net.minecraft.world.entity.Entity; | import net.minecraft.world.entity.Entity; | ||||||
| import net.minecraft.world.entity.LivingEntity; | 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.Inventory; | ||||||
| import net.minecraft.world.entity.player.Player; | import net.minecraft.world.entity.player.Player; | ||||||
| import net.minecraft.world.item.ItemStack; | 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; |             return living.getMainHandItem() == stack || living.getOffhandItem() == stack ? entity : null; | ||||||
|         } |         } | ||||||
|  |         else if( entity instanceof ItemEntity itemEntity ) | ||||||
|  |         { | ||||||
|  |             return itemEntity.getItem() == stack ? entity : null; | ||||||
|  |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             return null; |             return null; | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ import dan200.computercraft.api.pocket.AbstractPocketUpgrade; | |||||||
| import dan200.computercraft.api.pocket.IPocketAccess; | import dan200.computercraft.api.pocket.IPocketAccess; | ||||||
| import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; | import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; | ||||||
| import net.minecraft.resources.ResourceLocation; | import net.minecraft.resources.ResourceLocation; | ||||||
| import net.minecraft.world.entity.Entity; |  | ||||||
| import net.minecraft.world.item.ItemStack; | import net.minecraft.world.item.ItemStack; | ||||||
| 
 | 
 | ||||||
| import javax.annotation.Nonnull; | import javax.annotation.Nonnull; | ||||||
| @@ -27,21 +26,13 @@ public class PocketSpeaker extends AbstractPocketUpgrade | |||||||
|     @Override |     @Override | ||||||
|     public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) |     public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) | ||||||
|     { |     { | ||||||
|         return new PocketSpeakerPeripheral(); |         return new PocketSpeakerPeripheral( access ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) |     public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) | ||||||
|     { |     { | ||||||
|         if( !(peripheral instanceof PocketSpeakerPeripheral speaker) ) return; |         if( !(peripheral instanceof PocketSpeakerPeripheral) ) return; | ||||||
| 
 |         ((PocketSpeakerPeripheral) peripheral).update(); | ||||||
|         Entity entity = access.getEntity(); |  | ||||||
|         if( entity != null ) |  | ||||||
|         { |  | ||||||
|             speaker.setLocation( entity.getCommandSenderWorld(), entity.getEyePosition( 1 ) ); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         speaker.update(); |  | ||||||
|         access.setLight( speaker.madeSound() ? 0x3320fc : -1 ); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,7 +6,10 @@ | |||||||
| package dan200.computercraft.shared.pocket.peripherals; | package dan200.computercraft.shared.pocket.peripherals; | ||||||
| 
 | 
 | ||||||
| import dan200.computercraft.api.peripheral.IPeripheral; | 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 dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; | ||||||
|  | import net.minecraft.world.entity.Entity; | ||||||
| import net.minecraft.world.level.Level; | import net.minecraft.world.level.Level; | ||||||
| import net.minecraft.world.phys.Vec3; | import net.minecraft.world.phys.Vec3; | ||||||
| 
 | 
 | ||||||
| @@ -14,26 +17,21 @@ import javax.annotation.Nonnull; | |||||||
| 
 | 
 | ||||||
| public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral | public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral | ||||||
| { | { | ||||||
|     private Level world = null; |     private final IPocketAccess access; | ||||||
|  |     private Level level; | ||||||
|     private Vec3 position = Vec3.ZERO; |     private Vec3 position = Vec3.ZERO; | ||||||
| 
 | 
 | ||||||
|     void setLocation( Level world, Vec3 position ) |     public PocketSpeakerPeripheral( IPocketAccess access ) | ||||||
|     { |     { | ||||||
|         this.position = position; |         this.access = access; | ||||||
|         this.world = world; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Level getLevel() |  | ||||||
|     { |  | ||||||
|         return world; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Nonnull |     @Nonnull | ||||||
|     @Override |     @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 |     @Override | ||||||
| @@ -41,4 +39,19 @@ public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral | |||||||
|     { |     { | ||||||
|         return other instanceof PocketSpeakerPeripheral; |         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 ); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,11 +11,11 @@ import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; | |||||||
| import dan200.computercraft.api.turtle.ITurtleAccess; | import dan200.computercraft.api.turtle.ITurtleAccess; | ||||||
| import dan200.computercraft.api.turtle.TurtleSide; | import dan200.computercraft.api.turtle.TurtleSide; | ||||||
| import dan200.computercraft.api.turtle.TurtleUpgradeType; | import dan200.computercraft.api.turtle.TurtleUpgradeType; | ||||||
|  | import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; | ||||||
| import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; | import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral; | ||||||
| import net.minecraft.client.resources.model.ModelResourceLocation; | import net.minecraft.client.resources.model.ModelResourceLocation; | ||||||
| import net.minecraft.resources.ResourceLocation; | import net.minecraft.resources.ResourceLocation; | ||||||
| import net.minecraft.world.item.ItemStack; | import net.minecraft.world.item.ItemStack; | ||||||
| import net.minecraft.world.level.Level; |  | ||||||
| import net.minecraft.world.phys.Vec3; | import net.minecraft.world.phys.Vec3; | ||||||
| import net.minecraftforge.api.distmarker.Dist; | import net.minecraftforge.api.distmarker.Dist; | ||||||
| import net.minecraftforge.api.distmarker.OnlyIn; | import net.minecraftforge.api.distmarker.OnlyIn; | ||||||
| @@ -36,17 +36,11 @@ public class TurtleSpeaker extends AbstractTurtleUpgrade | |||||||
|             this.turtle = turtle; |             this.turtle = turtle; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |  | ||||||
|         public Level getLevel() |  | ||||||
|         { |  | ||||||
|             return turtle.getLevel(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Nonnull |         @Nonnull | ||||||
|         @Override |         @Override | ||||||
|         public Vec3 getPosition() |         public SpeakerPosition getPosition() | ||||||
|         { |         { | ||||||
|             return Vec3.atCenterOf( turtle.getPosition() ); |             return SpeakerPosition.of( turtle.getLevel(), Vec3.atCenterOf( turtle.getPosition() ) ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates