mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-03-05 02:58:12 +00:00
Change speakers to use the SPacketCustomSound packet instead
The method to register new SoundEvents is private, which means that few (if any) mods actually register them. Consequently, one could not use the speaker to play any modded sound, as they weren't registered on the server side. Using SPacketCustomSound does mean we can no longer determine if a sound exists or not, but I think a price I'm willing to pay in order to allow playing modded sounds.
This commit is contained in:
parent
914df8b0c7
commit
e7c19bcf55
@ -8,10 +8,11 @@ package dan200.computercraft.shared.peripheral.speaker;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
import dan200.computercraft.api.lua.ILuaContext;
|
||||||
import dan200.computercraft.api.lua.ILuaTask;
|
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import net.minecraft.network.play.server.SPacketCustomSound;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
@ -19,27 +20,27 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
|
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
|
||||||
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
|
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
|
||||||
|
|
||||||
public class SpeakerPeripheral implements IPeripheral {
|
public class SpeakerPeripheral implements IPeripheral
|
||||||
private TileSpeaker m_speaker;
|
{
|
||||||
|
private final TileSpeaker m_speaker;
|
||||||
private long m_clock;
|
private long m_clock;
|
||||||
private long m_lastPlayTime;
|
private long m_lastPlayTime;
|
||||||
private int m_notesThisTick;
|
private int m_notesThisTick;
|
||||||
|
|
||||||
public SpeakerPeripheral()
|
public SpeakerPeripheral()
|
||||||
{
|
{
|
||||||
m_clock = 0;
|
this( null );
|
||||||
m_lastPlayTime = 0;
|
|
||||||
m_notesThisTick = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeakerPeripheral( TileSpeaker speaker )
|
SpeakerPeripheral( TileSpeaker speaker )
|
||||||
{
|
{
|
||||||
this();
|
m_clock = 0;
|
||||||
|
m_lastPlayTime = 0;
|
||||||
|
m_notesThisTick = 0;
|
||||||
m_speaker = speaker;
|
m_speaker = speaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +65,9 @@ public class SpeakerPeripheral implements IPeripheral {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals( IPeripheral other )
|
public boolean equals( IPeripheral other )
|
||||||
{
|
{
|
||||||
if( other != null && other instanceof SpeakerPeripheral )
|
if( other == this ) return true;
|
||||||
{
|
if( !(other instanceof SpeakerPeripheral) ) return false;
|
||||||
SpeakerPeripheral otherSpeaker = (SpeakerPeripheral) other;
|
return m_speaker == ((SpeakerPeripheral) other).m_speaker;
|
||||||
return otherSpeaker.m_speaker == m_speaker;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -100,7 +95,11 @@ public class SpeakerPeripheral implements IPeripheral {
|
|||||||
// playSound
|
// playSound
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
return playSound(args, context, false);
|
String name = getString( args, 0 );
|
||||||
|
float volume = (float) optReal( args, 1, 1.0 );
|
||||||
|
float pitch = (float) optReal( args, 2, 1.0 );
|
||||||
|
|
||||||
|
return new Object[] { playSound( context, name, volume, pitch, false ) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// playNote
|
// playNote
|
||||||
@ -124,71 +123,51 @@ public class SpeakerPeripheral implements IPeripheral {
|
|||||||
float volume = (float) optReal( arguments, 1, 1.0 );
|
float volume = (float) optReal( arguments, 1, 1.0 );
|
||||||
float pitch = (float) optReal( arguments, 2, 1.0 );
|
float pitch = (float) optReal( arguments, 2, 1.0 );
|
||||||
|
|
||||||
// Check if sound exists
|
String noteName = "block.note." + name;
|
||||||
if ( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( "block.note." + name ) ) )
|
|
||||||
|
// Check if the note exists
|
||||||
|
if( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( noteName ) ) )
|
||||||
{
|
{
|
||||||
throw new LuaException("Invalid instrument, \"" + arguments[0] + "\"!");
|
throw new LuaException( "Invalid instrument, \"" + name + "\"!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the resource location for note block notes changes, this method call will need to be updated
|
// If the resource location for note block notes changes, this method call will need to be updated
|
||||||
Object[] returnValue = playSound(
|
boolean success = playSound( context, noteName,
|
||||||
new Object[] {
|
Math.min( volume, 3f ),
|
||||||
"block.note." + name,
|
(float) Math.pow( 2.0, (pitch - 12.0) / 12.0 ), true
|
||||||
(double)Math.min( volume, 3f ),
|
|
||||||
Math.pow( 2.0f, ( pitch - 12.0f ) / 12.0f)
|
|
||||||
}, context, true
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if( returnValue[0] instanceof Boolean && (Boolean) returnValue[0] )
|
if( success ) m_notesThisTick++;
|
||||||
{
|
return new Object[] { success };
|
||||||
m_notesThisTick++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue;
|
private synchronized boolean playSound( ILuaContext context, String name, float volume, float pitch, boolean isNote ) throws LuaException
|
||||||
|
{
|
||||||
|
if( m_clock - m_lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS &&
|
||||||
|
(!isNote || m_clock - m_lastPlayTime != 0 || m_notesThisTick >= ComputerCraft.maxNotesPerTick) )
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private synchronized Object[] playSound( Object[] arguments, ILuaContext context, boolean isNote ) throws LuaException
|
|
||||||
{
|
|
||||||
String name = getString(arguments, 0);
|
|
||||||
float volume = (float) optReal( arguments, 1, 1.0 );
|
|
||||||
float pitch = (float) optReal( arguments, 2, 1.0 );
|
|
||||||
|
|
||||||
ResourceLocation resourceName = new ResourceLocation( name );
|
|
||||||
|
|
||||||
if( m_clock - m_lastPlayTime >= TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS || ( ( m_clock - m_lastPlayTime == 0 ) && ( m_notesThisTick < ComputerCraft.maxNotesPerTick ) && isNote ) )
|
|
||||||
{
|
|
||||||
if( SoundEvent.REGISTRY.containsKey(resourceName) )
|
|
||||||
{
|
|
||||||
final World world = getWorld();
|
final World world = getWorld();
|
||||||
final BlockPos pos = getPos();
|
final BlockPos pos = getPos();
|
||||||
final ResourceLocation resource = resourceName;
|
|
||||||
final float vol = volume;
|
|
||||||
final float soundPitch = pitch;
|
|
||||||
|
|
||||||
context.issueMainThreadTask(new ILuaTask()
|
context.issueMainThreadTask( () -> {
|
||||||
{
|
MinecraftServer server = world.getMinecraftServer();
|
||||||
@Nullable
|
if( server == null ) return null;
|
||||||
@Override
|
|
||||||
public Object[] execute() throws LuaException
|
double x = pos.getX() + 0.5, y = pos.getY() + 0.5, z = pos.getZ() + 0.5;
|
||||||
{
|
server.getPlayerList().sendToAllNearExcept(
|
||||||
world.playSound( null, pos, SoundEvent.REGISTRY.getObject( resource ), SoundCategory.RECORDS, Math.min( vol, 3f ), soundPitch );
|
null, x, y, z, volume > 1.0f ? 16 * volume : 16.0, world.provider.getDimension(),
|
||||||
|
new SPacketCustomSound( name, SoundCategory.RECORDS, x, y, z, volume, pitch )
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
m_lastPlayTime = m_clock;
|
m_lastPlayTime = m_clock;
|
||||||
return new Object[]{true}; // Success, return true
|
return true;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new Object[]{false}; // Failed - sound not existent, return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new Object[]{false}; // Failed - rate limited, return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user