mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-06 07:20:30 +00:00
Rewrite speaker networking code
Speakers now play sounds using a custom set of packets. - When playing a sound, we send the resource id, position, volume, pitch and a UUID for the _speaker_ to all nearby clients. - This UUID is then used when we need to update the sound. When the speaker is moved or destroyed, we send a new packet to clients and update accordingly. This does have one side effect, that speakers can now only play one sound at a time. I think this is accceptable - otherwise it's possible to spam ward in a loop. Notes still use the old networking code, and so will not be affected. Closes #823
This commit is contained in:
parent
2fab1a3054
commit
de6f27ceaf
@ -22,6 +22,7 @@ public class ClientHooks
|
||||
if( event.getWorld().isClientSide() )
|
||||
{
|
||||
ClientMonitor.destroyAll();
|
||||
SoundManager.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
84
src/main/java/dan200/computercraft/client/SoundManager.java
Normal file
84
src/main/java/dan200/computercraft/client/SoundManager.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.ISound;
|
||||
import net.minecraft.client.audio.ITickableSound;
|
||||
import net.minecraft.client.audio.LocatableSound;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SoundManager
|
||||
{
|
||||
private static final Map<UUID, MoveableSound> sounds = new HashMap<>();
|
||||
|
||||
public static void playSound( UUID source, Vec3d position, SoundEvent event, float volume, float pitch )
|
||||
{
|
||||
SoundHandler soundManager = Minecraft.getInstance().getSoundManager();
|
||||
|
||||
MoveableSound oldSound = sounds.get( source );
|
||||
if( oldSound != null ) soundManager.stop( oldSound );
|
||||
|
||||
MoveableSound newSound = new MoveableSound( event, position, volume, pitch );
|
||||
sounds.put( source, newSound );
|
||||
soundManager.play( newSound );
|
||||
}
|
||||
|
||||
public static void stopSound( UUID source )
|
||||
{
|
||||
ISound sound = sounds.remove( source );
|
||||
if( sound == null ) return;
|
||||
|
||||
Minecraft.getInstance().getSoundManager().stop( sound );
|
||||
}
|
||||
|
||||
public static void moveSound( UUID source, Vec3d position )
|
||||
{
|
||||
MoveableSound sound = sounds.get( source );
|
||||
if( sound != null ) sound.setPosition( position );
|
||||
}
|
||||
|
||||
public static void reset()
|
||||
{
|
||||
sounds.clear();
|
||||
}
|
||||
|
||||
private static class MoveableSound extends LocatableSound implements ITickableSound
|
||||
{
|
||||
protected MoveableSound( SoundEvent sound, Vec3d position, float volume, float pitch )
|
||||
{
|
||||
super( sound, SoundCategory.RECORDS );
|
||||
setPosition( position );
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
void setPosition( Vec3d position )
|
||||
{
|
||||
x = (float) position.x();
|
||||
y = (float) position.y();
|
||||
z = (float) position.z();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStopped()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,10 @@ import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.lua.*;
|
||||
import dan200.computercraft.api.lua.IArguments;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.lua.MethodResult;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
|
@ -6,11 +6,11 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.CommonHooks;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.data.BlockNamedEntityLootCondition;
|
||||
import dan200.computercraft.shared.data.HasComputerIdLootCondition;
|
||||
import dan200.computercraft.shared.data.PlayerCreativeLootCondition;
|
||||
import dan200.computercraft.shared.CommonHooks;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -56,6 +56,9 @@ public final class NetworkHandler
|
||||
registerMainThread( 13, NetworkDirection.PLAY_TO_CLIENT, ComputerTerminalClientMessage::new );
|
||||
registerMainThread( 14, NetworkDirection.PLAY_TO_CLIENT, PlayRecordClientMessage.class, PlayRecordClientMessage::new );
|
||||
registerMainThread( 15, NetworkDirection.PLAY_TO_CLIENT, MonitorClientMessage.class, MonitorClientMessage::new );
|
||||
registerMainThread( 16, NetworkDirection.PLAY_TO_CLIENT, SpeakerPlayClientMessage.class, SpeakerPlayClientMessage::new );
|
||||
registerMainThread( 17, NetworkDirection.PLAY_TO_CLIENT, SpeakerStopClientMessage.class, SpeakerStopClientMessage::new );
|
||||
registerMainThread( 18, NetworkDirection.PLAY_TO_CLIENT, SpeakerMoveClientMessage.class, SpeakerMoveClientMessage::new );
|
||||
}
|
||||
|
||||
public static void sendToPlayer( PlayerEntity player, NetworkMessage packet )
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.network.client;
|
||||
|
||||
import dan200.computercraft.client.SoundManager;
|
||||
import dan200.computercraft.shared.network.NetworkMessage;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Starts a sound on the client.
|
||||
*
|
||||
* Used by speakers to play sounds.
|
||||
*
|
||||
* @see dan200.computercraft.shared.peripheral.speaker.TileSpeaker
|
||||
*/
|
||||
public class SpeakerMoveClientMessage implements NetworkMessage
|
||||
{
|
||||
private final UUID source;
|
||||
private final Vec3d pos;
|
||||
|
||||
public SpeakerMoveClientMessage( UUID source, Vec3d pos )
|
||||
{
|
||||
this.source = source;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public SpeakerMoveClientMessage( PacketBuffer buf )
|
||||
{
|
||||
source = buf.readUUID();
|
||||
pos = new Vec3d( buf.readDouble(), buf.readDouble(), buf.readDouble() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes( @Nonnull PacketBuffer buf )
|
||||
{
|
||||
buf.writeUUID( source );
|
||||
buf.writeDouble( pos.x() );
|
||||
buf.writeDouble( pos.y() );
|
||||
buf.writeDouble( pos.z() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void handle( NetworkEvent.Context context )
|
||||
{
|
||||
SoundManager.moveSound( source, pos );
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.network.client;
|
||||
|
||||
import dan200.computercraft.client.SoundManager;
|
||||
import dan200.computercraft.shared.network.NetworkMessage;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Starts a sound on the client.
|
||||
*
|
||||
* Used by speakers to play sounds.
|
||||
*
|
||||
* @see dan200.computercraft.shared.peripheral.speaker.TileSpeaker
|
||||
*/
|
||||
public class SpeakerPlayClientMessage implements NetworkMessage
|
||||
{
|
||||
private final UUID source;
|
||||
private final Vec3d pos;
|
||||
private final ResourceLocation sound;
|
||||
private final float volume;
|
||||
private final float pitch;
|
||||
|
||||
public SpeakerPlayClientMessage( UUID source, Vec3d pos, ResourceLocation event, float volume, float pitch )
|
||||
{
|
||||
this.source = source;
|
||||
this.pos = pos;
|
||||
sound = event;
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public SpeakerPlayClientMessage( PacketBuffer buf )
|
||||
{
|
||||
source = buf.readUUID();
|
||||
pos = new Vec3d( buf.readDouble(), buf.readDouble(), buf.readDouble() );
|
||||
sound = buf.readResourceLocation();
|
||||
volume = buf.readFloat();
|
||||
pitch = buf.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes( @Nonnull PacketBuffer buf )
|
||||
{
|
||||
buf.writeUUID( source );
|
||||
buf.writeDouble( pos.x() );
|
||||
buf.writeDouble( pos.y() );
|
||||
buf.writeDouble( pos.z() );
|
||||
buf.writeResourceLocation( sound );
|
||||
buf.writeFloat( volume );
|
||||
buf.writeFloat( pitch );
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void handle( NetworkEvent.Context context )
|
||||
{
|
||||
SoundEvent sound = ForgeRegistries.SOUND_EVENTS.getValue( this.sound );
|
||||
if( sound != null ) SoundManager.playSound( source, pos, sound, volume, pitch );
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.network.client;
|
||||
|
||||
import dan200.computercraft.client.SoundManager;
|
||||
import dan200.computercraft.shared.network.NetworkMessage;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Stops a sound on the client
|
||||
*
|
||||
* Called when a speaker is broken.
|
||||
*
|
||||
* @see dan200.computercraft.shared.peripheral.speaker.TileSpeaker
|
||||
*/
|
||||
public class SpeakerStopClientMessage implements NetworkMessage
|
||||
{
|
||||
private final UUID source;
|
||||
|
||||
public SpeakerStopClientMessage( UUID source )
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public SpeakerStopClientMessage( PacketBuffer buf )
|
||||
{
|
||||
source = buf.readUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes( @Nonnull PacketBuffer buf )
|
||||
{
|
||||
buf.writeUUID( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void handle( NetworkEvent.Context context )
|
||||
{
|
||||
SoundManager.stopSound( source );
|
||||
}
|
||||
}
|
@ -87,7 +87,7 @@ public class BlockMonitor extends BlockGeneric
|
||||
{
|
||||
TileMonitor monitor = (TileMonitor) entity;
|
||||
// Defer the block update if we're being placed by another TE. See #691
|
||||
if ( livingEntity == null || livingEntity instanceof FakePlayer )
|
||||
if( livingEntity == null || livingEntity instanceof FakePlayer )
|
||||
{
|
||||
monitor.updateNeighborsDeferred();
|
||||
return;
|
||||
|
@ -10,17 +10,23 @@ import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.network.NetworkHandler;
|
||||
import dan200.computercraft.shared.network.client.SpeakerMoveClientMessage;
|
||||
import dan200.computercraft.shared.network.client.SpeakerPlayClientMessage;
|
||||
import net.minecraft.network.play.server.SPlaySoundPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.state.properties.NoteBlockInstrument;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.ResourceLocationException;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static dan200.computercraft.api.lua.LuaValues.checkFinite;
|
||||
@ -32,20 +38,44 @@ import static dan200.computercraft.api.lua.LuaValues.checkFinite;
|
||||
*/
|
||||
public abstract class SpeakerPeripheral implements IPeripheral
|
||||
{
|
||||
private static final int MIN_TICKS_BETWEEN_SOUNDS = 1;
|
||||
|
||||
private long clock = 0;
|
||||
private long lastPlayTime = 0;
|
||||
private final AtomicInteger notesThisTick = new AtomicInteger();
|
||||
|
||||
private long lastPositionTime;
|
||||
private Vec3d lastPosition;
|
||||
|
||||
public void update()
|
||||
{
|
||||
clock++;
|
||||
notesThisTick.set( 0 );
|
||||
|
||||
// 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( lastPlayTime > 0 && (clock - lastPositionTime) >= 20 )
|
||||
{
|
||||
Vec3d position = getPosition();
|
||||
if( lastPosition == null || lastPosition.distanceToSqr( position ) >= 0.1 )
|
||||
{
|
||||
lastPosition = position;
|
||||
lastPositionTime = clock;
|
||||
NetworkHandler.sendToAllTracking(
|
||||
new SpeakerMoveClientMessage( getSource(), position ),
|
||||
getWorld().getChunkAt( new BlockPos( position ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract World getWorld();
|
||||
|
||||
public abstract Vec3d getPosition();
|
||||
|
||||
protected abstract UUID getSource();
|
||||
|
||||
public boolean madeSound( long ticks )
|
||||
{
|
||||
return clock - lastPlayTime <= ticks;
|
||||
@ -135,26 +165,37 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
|
||||
private synchronized boolean playSound( ILuaContext context, ResourceLocation name, float volume, float pitch, boolean isNote ) throws LuaException
|
||||
{
|
||||
if( clock - lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS &&
|
||||
(!isNote || clock - lastPlayTime != 0 || notesThisTick.get() >= ComputerCraft.maxNotesPerTick) )
|
||||
if( clock - lastPlayTime < MIN_TICKS_BETWEEN_SOUNDS )
|
||||
{
|
||||
// Rate limiting occurs when we've already played a sound within the last tick, or we've
|
||||
// played more notes than allowable within the current tick.
|
||||
return false;
|
||||
// Rate limiting occurs when we've already played a sound within the last tick.
|
||||
if( !isNote ) return false;
|
||||
// Or we've played more notes than allowable within the current tick.
|
||||
if( clock - lastPlayTime != 0 || notesThisTick.get() >= ComputerCraft.maxNotesPerTick ) return false;
|
||||
}
|
||||
|
||||
World world = getWorld();
|
||||
Vec3d pos = getPosition();
|
||||
|
||||
float range = MathHelper.clamp( volume, 1.0f, 3.0f ) * 16;
|
||||
|
||||
context.issueMainThreadTask( () -> {
|
||||
MinecraftServer server = world.getServer();
|
||||
if( server == null ) return null;
|
||||
|
||||
float adjVolume = Math.min( volume, 3.0f );
|
||||
server.getPlayerList().broadcast(
|
||||
null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.dimension.getType(),
|
||||
new SPlaySoundPacket( name, SoundCategory.RECORDS, pos, adjVolume, pitch )
|
||||
);
|
||||
if( isNote )
|
||||
{
|
||||
server.getPlayerList().broadcast(
|
||||
null, pos.x, pos.y, pos.z, range, world.dimension.getType(),
|
||||
new SPlaySoundPacket( name, SoundCategory.RECORDS, pos, range, pitch )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.sendToAllAround(
|
||||
new SpeakerPlayClientMessage( getSource(), pos, name, range, pitch ),
|
||||
world, pos, range
|
||||
);
|
||||
}
|
||||
return null;
|
||||
} );
|
||||
|
||||
|
@ -7,6 +7,8 @@ package dan200.computercraft.shared.peripheral.speaker;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.network.NetworkHandler;
|
||||
import dan200.computercraft.shared.network.client.SpeakerStopClientMessage;
|
||||
import dan200.computercraft.shared.util.CapabilityUtil;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
@ -19,15 +21,15 @@ import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
|
||||
|
||||
public class TileSpeaker extends TileGeneric implements ITickableTileEntity
|
||||
{
|
||||
public static final int MIN_TICKS_BETWEEN_SOUNDS = 1;
|
||||
|
||||
private final SpeakerPeripheral peripheral;
|
||||
private LazyOptional<IPeripheral> peripheralCap;
|
||||
private final UUID source = UUID.randomUUID();
|
||||
|
||||
public TileSpeaker( TileEntityType<TileSpeaker> type )
|
||||
{
|
||||
@ -41,6 +43,13 @@ public class TileSpeaker extends TileGeneric implements ITickableTileEntity
|
||||
peripheral.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved()
|
||||
{
|
||||
super.setRemoved();
|
||||
NetworkHandler.sendToAllPlayers( new SpeakerStopClientMessage( source ) );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability( @Nonnull Capability<T> cap, @Nullable Direction side )
|
||||
@ -83,6 +92,12 @@ public class TileSpeaker extends TileGeneric implements ITickableTileEntity
|
||||
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UUID getSource()
|
||||
{
|
||||
return speaker.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( @Nullable IPeripheral other )
|
||||
{
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.peripheral.speaker;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.shared.network.NetworkHandler;
|
||||
import dan200.computercraft.shared.network.client.SpeakerStopClientMessage;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A speaker peripheral which is used on an upgrade, and so is only attached to one computer.
|
||||
*/
|
||||
public abstract class UpgradeSpeakerPeripheral extends SpeakerPeripheral
|
||||
{
|
||||
private final UUID source = UUID.randomUUID();
|
||||
|
||||
@Override
|
||||
protected final UUID getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
NetworkHandler.sendToAllPlayers( new SpeakerStopClientMessage( source ) );
|
||||
}
|
||||
}
|
@ -6,11 +6,11 @@
|
||||
package dan200.computercraft.shared.pocket.peripherals;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PocketSpeakerPeripheral extends SpeakerPeripheral
|
||||
public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral
|
||||
{
|
||||
private World world = null;
|
||||
private Vec3d position = Vec3d.ZERO;
|
||||
|
@ -715,7 +715,6 @@ public class TurtleAPI implements ILuaAPI
|
||||
* more information about the item at the cost of taking longer to run.
|
||||
* @return The command result.
|
||||
* @throws LuaException If the slot is out of range.
|
||||
* @see InventoryMethods#getItemDetail Describes the information returned by a detailed query.
|
||||
* @cc.treturn nil|table Information about the given slot, or {@code nil} if it is empty.
|
||||
* @cc.usage Print the current slot, assuming it contains 13 dirt.
|
||||
*
|
||||
@ -726,6 +725,7 @@ public class TurtleAPI implements ILuaAPI
|
||||
* -- count = 13,
|
||||
* -- }
|
||||
* }</pre>
|
||||
* @see InventoryMethods#getItemDetail Describes the information returned by a detailed query.
|
||||
*/
|
||||
@LuaFunction
|
||||
public final MethodResult getItemDetail( ILuaContext context, Optional<Integer> slot, Optional<Boolean> detailed ) throws LuaException
|
||||
|
@ -12,7 +12,7 @@ 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.SpeakerPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
|
||||
import net.minecraft.client.renderer.model.ModelResourceLocation;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -28,7 +28,7 @@ public class TurtleSpeaker extends AbstractTurtleUpgrade
|
||||
private static final ModelResourceLocation leftModel = new ModelResourceLocation( "computercraft:turtle_speaker_upgrade_left", "inventory" );
|
||||
private static final ModelResourceLocation rightModel = new ModelResourceLocation( "computercraft:turtle_speaker_upgrade_right", "inventory" );
|
||||
|
||||
private static class Peripheral extends SpeakerPeripheral
|
||||
private static class Peripheral extends UpgradeSpeakerPeripheral
|
||||
{
|
||||
ITurtleAccess turtle;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user