package net.knarcraft.minstrel.music; import net.knarcraft.minstrel.MinstrelPlugin; import net.knarcraft.minstrel.trait.MinstrelTrait; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.SoundCategory; import org.bukkit.entity.Player; import java.util.HashSet; import java.util.Set; /** * A representation of a song playable by a minstrel * *
Note: Any custom song has to be mono to fade out like a normal jukebox. If it's stereo, you'll end up with a * global song instead.
*/ public class Song { private final int durationSeconds; private final SoundCategory category; private final String sound; private boolean isPlaying = false; private final SetThe category the song belongs to
* @param soundThe song to use
* @param durationSecondsThe duration of the song, in seconds
*/ public Song(SoundCategory category, String sound, int durationSeconds) { this.category = category; this.sound = sound; this.durationSeconds = durationSeconds; } /** * Plays this song at the given minstrel's location, but only for the given player * *Volume of 1 means the max volume, which can be heard up to 1 chunk away. Setting it to 2 means it can be * heard 2 chunks away.
* * @param traitThe minstrel to play this song
* @param playerThe player to play this song for
* @param volumeThe volume to play this song at
* @param pitchThe pitch to play this song at
*/ public void play(MinstrelTrait trait, Player player, float volume, float pitch) { playingFor.add(player); play(player, trait.getLocation(), volume, pitch); } /** * Plays this song at the given minstrel's location * *Volume of 1 means the max volume, which can be heard up to 1 chunk away. Setting it to 2 means it can be * heard 2 chunks away.
* * @param traitThe minstrel to play this song
* @param volumeThe volume to play this song at
* @param pitchThe pitch to play this song at
*/ public void play(MinstrelTrait trait, float volume, float pitch) { for (Player player : Bukkit.getOnlinePlayers()) { play(player, trait.getLocation(), volume, pitch); } this.isPlaying = true; //Mark this song as ended, once Bukkit.getScheduler().runTaskLater(MinstrelPlugin.getInstance(), () -> this.isPlaying = false, durationSeconds * 20L); } /** * Gets the duration of this song, in seconds * * @returnThe duration of this song
*/ public int getDuration() { return durationSeconds; } /** * Stops this song for the given player * * @param playerThe player to stop this song for
*/ public void stop(Player player) { //Don't bother stopping if not playing if (!playingFor.contains(player) && !isPlaying) { return; } playingFor.remove(player); if (this.category == null) { player.stopSound(this.sound); } else { player.stopSound(this.sound, this.category); } } /** * Plays this song for the given player, at the given location * * @param playerThe player to play this song for
* @param locationThe location to play the song at
* @param volumeThe volume to play at
* @param pitchThe pitch to play at
*/ private void play(Player player, Location location, float volume, float pitch) { if (this.category == null) { player.playSound(location, this.sound, volume, pitch); } else { player.playSound(location, this.sound, this.category, volume, pitch); } } @Override public String toString() { String songString = this.category + ":" + this.sound + ":" + this.durationSeconds; if (this.isPlaying) { return ">" + songString; } else { return songString; } } /** * Gets the category of this song * *Note: The category is only used to tell which volume slider affects the song volume, and which type of sounds * may prevent this from playing. RECORDS is preferable for minstrels.
* * @returnThe category of this song
*/ public SoundCategory getCategory() { return category; } /** * Gets the identifier for this song's sound * * @returnThe identifier for this song's sound
*/ public String getSound() { return this.sound; } }