#938: Various Sound API improvements

By: Jishuna <joshl5324@gmail.com>
This commit is contained in:
Bukkit/Spigot 2023-11-17 19:54:43 +13:00
parent 44cbcb80d4
commit 1f322369a0
4 changed files with 203 additions and 35 deletions

View file

@ -9,110 +9,123 @@ public enum Instrument {
/**
* Piano is the standard instrument for a note block.
*/
PIANO(0x0),
PIANO(0x0, Sound.BLOCK_NOTE_BLOCK_HARP),
/**
* Bass drum is normally played when a note block is on top of a
* stone-like block.
*/
BASS_DRUM(0x1),
BASS_DRUM(0x1, Sound.BLOCK_NOTE_BLOCK_BASEDRUM),
/**
* Snare drum is normally played when a note block is on top of a sandy
* block.
*/
SNARE_DRUM(0x2),
SNARE_DRUM(0x2, Sound.BLOCK_NOTE_BLOCK_SNARE),
/**
* Sticks are normally played when a note block is on top of a glass
* block.
*/
STICKS(0x3),
STICKS(0x3, Sound.BLOCK_NOTE_BLOCK_HAT),
/**
* Bass guitar is normally played when a note block is on top of a wooden
* block.
*/
BASS_GUITAR(0x4),
BASS_GUITAR(0x4, Sound.BLOCK_NOTE_BLOCK_BASS),
/**
* Flute is normally played when a note block is on top of a clay block.
*/
FLUTE(0x5),
FLUTE(0x5, Sound.BLOCK_NOTE_BLOCK_FLUTE),
/**
* Bell is normally played when a note block is on top of a gold block.
*/
BELL(0x6),
BELL(0x6, Sound.BLOCK_NOTE_BLOCK_BELL),
/**
* Guitar is normally played when a note block is on top of a woolen block.
*/
GUITAR(0x7),
GUITAR(0x7, Sound.BLOCK_NOTE_BLOCK_GUITAR),
/**
* Chime is normally played when a note block is on top of a packed ice
* block.
*/
CHIME(0x8),
CHIME(0x8, Sound.BLOCK_NOTE_BLOCK_CHIME),
/**
* Xylophone is normally played when a note block is on top of a bone block.
*/
XYLOPHONE(0x9),
XYLOPHONE(0x9, Sound.BLOCK_NOTE_BLOCK_XYLOPHONE),
/**
* Iron Xylophone is normally played when a note block is on top of a iron block.
*/
IRON_XYLOPHONE(0xA),
IRON_XYLOPHONE(0xA, Sound.BLOCK_NOTE_BLOCK_IRON_XYLOPHONE),
/**
* Cow Bell is normally played when a note block is on top of a soul sand block.
*/
COW_BELL(0xB),
COW_BELL(0xB, Sound.BLOCK_NOTE_BLOCK_COW_BELL),
/**
* Didgeridoo is normally played when a note block is on top of a pumpkin block.
*/
DIDGERIDOO(0xC),
DIDGERIDOO(0xC, Sound.BLOCK_NOTE_BLOCK_DIDGERIDOO),
/**
* Bit is normally played when a note block is on top of a emerald block.
*/
BIT(0xD),
BIT(0xD, Sound.BLOCK_NOTE_BLOCK_BIT),
/**
* Banjo is normally played when a note block is on top of a hay block.
*/
BANJO(0xE),
BANJO(0xE, Sound.BLOCK_NOTE_BLOCK_BANJO),
/**
* Pling is normally played when a note block is on top of a glowstone block.
*/
PLING(0xF),
PLING(0xF, Sound.BLOCK_NOTE_BLOCK_PLING),
/**
* Zombie is normally played when a Zombie Head is on top of the note block.
*/
ZOMBIE,
ZOMBIE(Sound.BLOCK_NOTE_BLOCK_IMITATE_ZOMBIE),
/**
* Skeleton is normally played when a Skeleton Head is on top of the note block.
*/
SKELETON,
SKELETON(Sound.BLOCK_NOTE_BLOCK_IMITATE_SKELETON),
/**
* Creeper is normally played when a Creeper Head is on top of the note block.
*/
CREEPER,
CREEPER(Sound.BLOCK_NOTE_BLOCK_IMITATE_CREEPER),
/**
* Dragon is normally played when a Dragon Head is on top of the note block.
*/
DRAGON,
DRAGON(Sound.BLOCK_NOTE_BLOCK_IMITATE_ENDER_DRAGON),
/**
* Wither Skeleton is normally played when a Wither Skeleton Head is on top of the note block.
*/
WITHER_SKELETON,
WITHER_SKELETON(Sound.BLOCK_NOTE_BLOCK_IMITATE_WITHER_SKELETON),
/**
* Piglin is normally played when a Piglin Head is on top of the note block.
*/
PIGLIN,
PIGLIN(Sound.BLOCK_NOTE_BLOCK_IMITATE_PIGLIN),
/**
* Custom Sound is normally played when a Player Head with the required data is on top of the note block.
*/
CUSTOM_HEAD;
CUSTOM_HEAD(null);
private final byte type;
private final Sound sound;
private static final Map<Byte, Instrument> BY_DATA = Maps.newHashMap();
private Instrument() {
this(-1);
private Instrument(final Sound sound) {
this(-1, sound);
}
private Instrument(final int type) {
private Instrument(final int type, final Sound sound) {
this.type = (byte) type;
this.sound = sound;
}
/**
* Gets the sound associated with this instrument. <br>
* Will be null for {@link Instrument#CUSTOM_HEAD}
*
* @return the sound or null
*/
@Nullable
public Sound getSound() {
return this.sound;
}
/**

View file

@ -118,6 +118,14 @@ public class Note {
}
}
private static final float[] pitchArray = new float[25];
static {
for (int i = 0; i <= 24; i++) {
// See https://minecraft.wiki/w/Note_Block#Notes
pitchArray[i] = (float) Math.pow(2, (i - 12) / 12f);
}
}
private final byte note;
/**
@ -254,6 +262,16 @@ public class Note {
return Tone.getById(note).isSharped(note);
}
/**
* Gets the pitch of this note. This is the value used with
* {@link World#playSound} or the /playsound command.
*
* @return the pitch
*/
public float getPitch() {
return pitchArray[this.note];
}
@Override
public int hashCode() {
final int prime = 31;

View file

@ -2109,6 +2109,18 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*/
void setSpawnLimit(@NotNull SpawnCategory spawnCategory, int limit);
/**
* Play a note at the provided Location in the World. <br>
* This <i>will</i> work with cake.
* <p>
* This method will fail silently when called with {@link Instrument#CUSTOM_HEAD}.
*
* @param loc The location to play the note
* @param instrument The instrument
* @param note The note
*/
void playNote(@NotNull Location loc, @NotNull Instrument instrument, @NotNull Note note);
/**
* Play a Sound at the provided Location in the World.
* <p>
@ -2163,6 +2175,38 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*/
void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch);
/**
* Play a Sound at the provided Location in the World. For sounds with multiple
* variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Location or Sound are null.
*
* @param location The location to play the sound
* @param sound The sound to play
* @param category the category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a Sound at the provided Location in the World. For sounds with multiple
* variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Location or Sound are null. No sound will
* be heard by the players if their clients do not have the respective sound for
* the value passed.
*
* @param location The location to play the sound
* @param sound The internal sound name to play
* @param category the category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a Sound at the location of the provided entity in the World.
* <p>
@ -2213,6 +2257,38 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*/
void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch);
/**
* Play a Sound at the location of the provided entity in the World. For sounds
* with multiple variations passing the same seed will always play the same
* variation.
* <p>
* This function will fail silently if Entity or Sound are null.
*
* @param entity The entity to play the sound
* @param sound The sound to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a Sound at the location of the provided entity in the World. For sounds
* with multiple variations passing the same seed will always play the same
* variation.
* <p>
* This function will fail silently if Entity or Sound are null.
*
* @param entity The entity to play the sound
* @param sound The sound to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Get an array containing the names of all the {@link GameRule}s.
*

View file

@ -391,11 +391,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
public void setBedSpawnLocation(@Nullable Location location, boolean force);
/**
* Play a note for a player at a location. This requires a note block
* at the particular location (as far as the client is concerned). This
* will not work without a note block. This will not work with cake.
* Play a note for the player at a location. <br>
* This <i>will</i> work with cake.
*
* @param loc The location of a note block.
* @param loc The location to play the note
* @param instrument The instrument ID.
* @param note The note ID.
* @deprecated Magic value
@ -404,11 +403,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
public void playNote(@NotNull Location loc, byte instrument, byte note);
/**
* Play a note for a player at a location. This requires a note block
* at the particular location (as far as the client is concerned). This
* will not work without a note block. This will not work with cake.
*
* @param loc The location of a note block
* Play a note for the player at a location. <br>
* This <i>will</i> work with cake.
* <p>
* This method will fail silently when called with {@link Instrument#CUSTOM_HEAD}.
* @param loc The location to play the note
* @param instrument The instrument
* @param note The note
*/
@ -469,6 +468,38 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch);
/**
* Play a sound for a player at the location. For sounds with multiple
* variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Location or Sound are null.
*
* @param location The location to play the sound
* @param sound The sound to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a sound for a player at the location. For sounds with multiple
* variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Location or Sound are null. No sound
* will be heard by the player if their client does not have the respective
* sound for the value passed.
*
* @param location The location to play the sound
* @param sound The internal sound name to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a sound for a player at the location of the entity.
* <p>
@ -519,6 +550,36 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch);
/**
* Play a sound for a player at the location of the entity. For sounds with
* multiple variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Entity or Sound are null.
*
* @param entity The entity to play the sound
* @param sound The sound to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
public void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Play a sound for a player at the location of the entity. For sounds with
* multiple variations passing the same seed will always play the same variation.
* <p>
* This function will fail silently if Entity or Sound are null.
*
* @param entity The entity to play the sound
* @param sound The sound to play
* @param category The category of the sound
* @param volume The volume of the sound
* @param pitch The pitch of the sound
* @param seed The seed for the sound
*/
public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed);
/**
* Stop the specified sound from playing.
*