1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-28 18:04:47 +00:00

Merge branch 'mc-1.16.x' into mc-1.18.x

This commit is contained in:
Jonathan Coates 2022-04-28 20:27:48 +01:00
commit caa412b7d2
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
15 changed files with 198 additions and 143 deletions

View File

@ -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;

View File

@ -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 )
{
}
}

View File

@ -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 );
} }

View File

@ -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 );

View File

@ -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

View File

@ -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 );
} }
} }

View File

@ -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() );
} }
} }

View File

@ -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 );
} }
} }

View File

@ -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();
if( lastPosition.distanceToSqr( position ) >= 0.1 )
{ {
// TODO: What to do when entities move away? How do we notify people left behind that they're gone.
NetworkHandler.sendToAllTracking( NetworkHandler.sendToAllTracking(
new SpeakerMoveClientMessage( getSource(), position ), new SpeakerMoveClientMessage( getSource(), position ),
getLevel().getChunkAt( new BlockPos( position ) ) level.getChunkAt( new BlockPos( pos ) )
); );
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;

View File

@ -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
);
}
}
}

View File

@ -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

View File

@ -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;

View File

@ -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 );
} }
} }

View File

@ -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 );
}
} }

View File

@ -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