From 2babceeb870066f2b52019656d8e418701144651 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 30 Oct 2022 19:29:56 +0100 Subject: [PATCH] Adds proper playback of any song Adds several commands to control songs, volumes and pitches Moves code into proper packages Removes test song Adds loading and saving of minstrel data --- .../knarcraft/minstrel/MinstrelPlugin.java | 33 ++-- .../net/knarcraft/minstrel/MinstrelTrait.java | 44 ------ .../minstrel/command/AddSongCommand.java | 75 +++++++++ .../minstrel/command/ListSongsCommand.java | 38 +++++ .../minstrel/command/MinstrelCommand.java | 114 ++++++++++++++ .../command/MinstrelTabCompleter.java | 52 +++++++ .../minstrel/command/RemoveSongCommand.java | 50 ++++++ .../{ => listener}/PlayerListener.java | 6 +- .../minstrel/{ => music}/Playlist.java | 45 +++++- .../knarcraft/minstrel/{ => music}/Song.java | 35 ++++- .../minstrel/trait/MinstrelTrait.java | 146 ++++++++++++++++++ src/main/resources/plugin.yml | 10 ++ 12 files changed, 582 insertions(+), 66 deletions(-) delete mode 100644 src/main/java/net/knarcraft/minstrel/MinstrelTrait.java create mode 100644 src/main/java/net/knarcraft/minstrel/command/AddSongCommand.java create mode 100644 src/main/java/net/knarcraft/minstrel/command/ListSongsCommand.java create mode 100644 src/main/java/net/knarcraft/minstrel/command/MinstrelCommand.java create mode 100644 src/main/java/net/knarcraft/minstrel/command/MinstrelTabCompleter.java create mode 100644 src/main/java/net/knarcraft/minstrel/command/RemoveSongCommand.java rename src/main/java/net/knarcraft/minstrel/{ => listener}/PlayerListener.java (67%) rename src/main/java/net/knarcraft/minstrel/{ => music}/Playlist.java (74%) rename src/main/java/net/knarcraft/minstrel/{ => music}/Song.java (79%) create mode 100644 src/main/java/net/knarcraft/minstrel/trait/MinstrelTrait.java diff --git a/src/main/java/net/knarcraft/minstrel/MinstrelPlugin.java b/src/main/java/net/knarcraft/minstrel/MinstrelPlugin.java index 5db41e9..24d96e1 100644 --- a/src/main/java/net/knarcraft/minstrel/MinstrelPlugin.java +++ b/src/main/java/net/knarcraft/minstrel/MinstrelPlugin.java @@ -1,8 +1,12 @@ package net.knarcraft.minstrel; import net.citizensnpcs.api.CitizensAPI; +import net.knarcraft.minstrel.command.MinstrelCommand; +import net.knarcraft.minstrel.command.MinstrelTabCompleter; +import net.knarcraft.minstrel.listener.PlayerListener; +import net.knarcraft.minstrel.trait.MinstrelTrait; import org.bukkit.Bukkit; -import org.bukkit.SoundCategory; +import org.bukkit.command.PluginCommand; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -15,7 +19,8 @@ import java.util.List; public final class MinstrelPlugin extends JavaPlugin { private static MinstrelPlugin instance; - private static Playlist testPlaylist; + + private final List knownMinstrels = new ArrayList<>(); @Override public void onEnable() { @@ -26,28 +31,30 @@ public final class MinstrelPlugin extends JavaPlugin { CitizensAPI.getTraitFactory().registerTrait( net.citizensnpcs.api.trait.TraitInfo.create(MinstrelTrait.class).withName("minstrel")); - Song testSong = new Song(SoundCategory.RECORDS, "minecraft:records.custom.medieval_3_g_mixolydian", 114); - List songs = new ArrayList<>(); - songs.add(testSong); - testPlaylist = new Playlist(songs, true); - PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.registerEvents(new PlayerListener(), this); + + PluginCommand minstrelCommand = this.getCommand("minstrel"); + if (minstrelCommand != null) { + minstrelCommand.setExecutor(new MinstrelCommand()); + minstrelCommand.setTabCompleter(new MinstrelTabCompleter()); + } } @Override public void onDisable() { - // Plugin shutdown logic - //TODO: Stop all songs in all playlists + for (MinstrelTrait minstrelTrait : knownMinstrels) { + minstrelTrait.getPlaylist().stop(); + } } /** - * Gets the playlist which is currently hard-coded for testing + * Adds the given minstrel to the list of known minstrels * - * @return

The test playlist

+ * @param minstrelTrait

The minstrel to add

*/ - public static Playlist getTestPlaylist() { - return testPlaylist; + public void addMinstrel(MinstrelTrait minstrelTrait) { + knownMinstrels.add(minstrelTrait); } /** diff --git a/src/main/java/net/knarcraft/minstrel/MinstrelTrait.java b/src/main/java/net/knarcraft/minstrel/MinstrelTrait.java deleted file mode 100644 index 5ed2ba5..0000000 --- a/src/main/java/net/knarcraft/minstrel/MinstrelTrait.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.knarcraft.minstrel; - -import net.citizensnpcs.api.trait.Trait; -import net.citizensnpcs.api.util.DataKey; -import org.bukkit.Location; - -/** - * The minstrel trait itself, which contains all NPC data for this trait - */ -public class MinstrelTrait extends Trait { - - public MinstrelTrait() { - super("minstrel"); - } - - /** - * Gets the location of this minstrel - * - * @return

The location of this minstrel

- */ - public Location getLocation() { - return this.getNPC().getStoredLocation(); - } - - /** - * Loads all config values stored in citizens' config file for this NPC - * - * @param key

The data key used for the config root

- */ - @Override - public void load(DataKey key) { - //TODO: Actually load the playlist set to this minstrel - MinstrelPlugin.getTestPlaylist().play(this); - } - - public float getVolume() { - return 1F; - } - - public float getPitch() { - return 1F; - } - -} diff --git a/src/main/java/net/knarcraft/minstrel/command/AddSongCommand.java b/src/main/java/net/knarcraft/minstrel/command/AddSongCommand.java new file mode 100644 index 0000000..c26019f --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/command/AddSongCommand.java @@ -0,0 +1,75 @@ +package net.knarcraft.minstrel.command; + +import net.knarcraft.minstrel.music.Playlist; +import net.knarcraft.minstrel.music.Song; +import net.knarcraft.minstrel.trait.MinstrelTrait; +import org.bukkit.SoundCategory; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * The command for adding a new song to a minstrel + */ +public class AddSongCommand implements CommandExecutor { + + private final MinstrelTrait minstrelTrait; + + /** + * Instantiates a new add song command + * + * @param minstrelTrait

The minstrel to run this command on

+ */ + public AddSongCommand(MinstrelTrait minstrelTrait) { + this.minstrelTrait = minstrelTrait; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + if (args.length < 4) { + return false; + } + + String categoryString = args[1]; + String songIdString = args[2]; + String durationString = args[3]; + + Playlist playlist = minstrelTrait.getPlaylist(); + //category identifier duration + SoundCategory category = null; + int duration; + if (!categoryString.equalsIgnoreCase("null")) { + try { + category = SoundCategory.valueOf(categoryString); + } catch (IllegalArgumentException exception) { + sender.sendMessage("The specified category cannot be recognized"); + return false; + } + } + try { + duration = Integer.parseInt(durationString); + } catch (NumberFormatException exception) { + sender.sendMessage("The duration specified is not a valid number"); + return false; + } + if (duration < 1) { + sender.sendMessage("The duration specified is not positive"); + return false; + } + if (songIdString.trim().isEmpty()) { + sender.sendMessage("The song identifier is empty"); + return false; + } + Song song = new Song(category, songIdString, duration); + playlist.addSong(song); + + if (playlist.getSongs().size() == 1) { + playlist.play(minstrelTrait); + } + sender.sendMessage("New song added"); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/minstrel/command/ListSongsCommand.java b/src/main/java/net/knarcraft/minstrel/command/ListSongsCommand.java new file mode 100644 index 0000000..768297c --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/command/ListSongsCommand.java @@ -0,0 +1,38 @@ +package net.knarcraft.minstrel.command; + +import net.knarcraft.minstrel.music.Song; +import net.knarcraft.minstrel.trait.MinstrelTrait; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * The command for listing a minstrel's current songs + */ +public class ListSongsCommand implements CommandExecutor { + + private final MinstrelTrait minstrelTrait; + + /** + * Instantiates a new list songs command + * + * @param minstrelTrait

The minstrel to run this command on

+ */ + public ListSongsCommand(MinstrelTrait minstrelTrait) { + this.minstrelTrait = minstrelTrait; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + StringBuilder builder = new StringBuilder(); + builder.append("Songs:").append("\n"); + for (Song song : minstrelTrait.getPlaylist().getSongs()) { + builder.append(song).append("\n"); + } + sender.sendMessage(builder.toString()); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/minstrel/command/MinstrelCommand.java b/src/main/java/net/knarcraft/minstrel/command/MinstrelCommand.java new file mode 100644 index 0000000..e19a5e0 --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/command/MinstrelCommand.java @@ -0,0 +1,114 @@ +package net.knarcraft.minstrel.command; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.npc.NPC; +import net.knarcraft.minstrel.trait.MinstrelTrait; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class MinstrelCommand implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender); + if (npc == null || !npc.hasTrait(MinstrelTrait.class)) { + sender.sendMessage("You must select a minstrel NPC before running this command"); + return true; + } + MinstrelTrait minstrelTrait = npc.getTraitNullable(MinstrelTrait.class); + + if (args.length < 1) { + return false; + } + + switch (args[0].toLowerCase()) { + case "addsong": + return new AddSongCommand(minstrelTrait).onCommand(sender, command, label, args); + case "removesong": + return new RemoveSongCommand(minstrelTrait).onCommand(sender, command, label, args); + case "listsongs": + return new ListSongsCommand(minstrelTrait).onCommand(sender, command, label, args); + case "pitch": + return updatePitch(minstrelTrait, args.length > 1 ? args[1] : null, sender); + case "volume": + return updateVolume(minstrelTrait, args.length > 1 ? args[1] : null, sender); + } + /* Sub-commands: + AddSong category identifier duration (remember to run play again) + RemoveSong index + ListSongs + + Global sub-commands + StopAll - Stops all minstrels from playing + PlayALl - Starts playing for all minstrels + + //TODO: Perhaps split this into two plugins instead? Or make this a generic plugin which happens to add a Minstrel trait? + CreatePlaylist name + AddSong playlist category identifier duration + Play playlist - Plays the specified playlist at the executor's location + */ + return false; + } + + /** + * Updates the pitch for a minstrel if possible + * + * @param minstrelTrait

The minstrel to update the pitch for

+ * @param newPitch

The new pitch for the minstrel

+ * @param sender

The sender to send error/success messages to

+ * @return

True if the pitch was successfully updated

+ */ + private boolean updatePitch(MinstrelTrait minstrelTrait, String newPitch, CommandSender sender) { + if (newPitch == null) { + sender.sendMessage("Current pitch: " + minstrelTrait.getPitch()); + return true; + } + + try { + float pitch = Float.parseFloat(newPitch); + if (pitch < 0) { + sender.sendMessage("The pitch cannot be negative"); + } else { + minstrelTrait.setPitch(pitch); + } + } catch (NumberFormatException exception) { + sender.sendMessage("The given pitch is not a number!"); + return false; + } + sender.sendMessage("Pitch set to " + newPitch); + return true; + } + + /** + * Updates the volume for a minstrel if possible + * + * @param minstrelTrait

The minstrel to update the pitch for

+ * @param newVolume

The new volume for the minstrel

+ * @param sender

The sender to send error/success messages to

+ * @return

True if the volume was successfully updated

+ */ + private boolean updateVolume(MinstrelTrait minstrelTrait, String newVolume, CommandSender sender) { + if (newVolume == null) { + sender.sendMessage("Current volume: " + minstrelTrait.getVolume()); + return true; + } + + try { + float volume = Float.parseFloat(newVolume); + if (volume <= 0) { + sender.sendMessage("The volume must be greater than 0"); + } else { + minstrelTrait.setVolume(volume); + } + } catch (NumberFormatException exception) { + sender.sendMessage("The given volume is not a number!"); + return false; + } + sender.sendMessage("Volume set to " + newVolume); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/minstrel/command/MinstrelTabCompleter.java b/src/main/java/net/knarcraft/minstrel/command/MinstrelTabCompleter.java new file mode 100644 index 0000000..0db2839 --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/command/MinstrelTabCompleter.java @@ -0,0 +1,52 @@ +package net.knarcraft.minstrel.command; + +import org.bukkit.SoundCategory; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class MinstrelTabCompleter implements TabCompleter { + + private final List baseCommands; + private final List soundCategories; + + public MinstrelTabCompleter() { + baseCommands = new ArrayList<>(); + baseCommands.add("addsong"); + baseCommands.add("removesong"); + baseCommands.add("listsongs"); + baseCommands.add("pitch"); + baseCommands.add("volume"); + soundCategories = new ArrayList<>(); + for (SoundCategory category : SoundCategory.values()) { + soundCategories.add(category.name()); + } + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + if (args.length < 2) { + return baseCommands; + } + switch (args[0].toLowerCase()) { + case "addsong": + if (args.length == 2) { + return soundCategories; + } else if (args.length == 3) { + List exampleSongNames = new ArrayList<>(); + exampleSongNames.add("minecraft:records.custom.medieval_3_g_mixolydian"); + exampleSongNames.add("minecraft:block.amethyst_block.step"); + return exampleSongNames; + } + } + return null; + } + +} diff --git a/src/main/java/net/knarcraft/minstrel/command/RemoveSongCommand.java b/src/main/java/net/knarcraft/minstrel/command/RemoveSongCommand.java new file mode 100644 index 0000000..935dc29 --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/command/RemoveSongCommand.java @@ -0,0 +1,50 @@ +package net.knarcraft.minstrel.command; + +import net.knarcraft.minstrel.music.Playlist; +import net.knarcraft.minstrel.trait.MinstrelTrait; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * The command for removing a song from a minstrel + */ +public class RemoveSongCommand implements CommandExecutor { + + private final MinstrelTrait minstrelTrait; + + /** + * Instantiates a new remove song command + * + * @param minstrelTrait

The minstrel to run this command on

+ */ + public RemoveSongCommand(MinstrelTrait minstrelTrait) { + this.minstrelTrait = minstrelTrait; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + Playlist playlist = minstrelTrait.getPlaylist(); + int index; + try { + index = Integer.parseInt(args[1]); + } catch (NumberFormatException exception) { + sender.sendMessage("The given index is not an integer"); + return false; + } + if (index >= 0 && playlist.getSongs().size() > index) { + playlist.removeSong(index); + //Stop any minstrels from playing the removed song + minstrelTrait.getPlaylist().stop(); + minstrelTrait.getPlaylist().play(minstrelTrait); + sender.sendMessage("Song removed"); + } else { + sender.sendMessage("The specified index is outside the bounds of the playlist"); + return false; + } + return true; + } + +} diff --git a/src/main/java/net/knarcraft/minstrel/PlayerListener.java b/src/main/java/net/knarcraft/minstrel/listener/PlayerListener.java similarity index 67% rename from src/main/java/net/knarcraft/minstrel/PlayerListener.java rename to src/main/java/net/knarcraft/minstrel/listener/PlayerListener.java index cbc7abc..209bb26 100644 --- a/src/main/java/net/knarcraft/minstrel/PlayerListener.java +++ b/src/main/java/net/knarcraft/minstrel/listener/PlayerListener.java @@ -1,7 +1,8 @@ -package net.knarcraft.minstrel; +package net.knarcraft.minstrel.listener; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; +import net.knarcraft.minstrel.trait.MinstrelTrait; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -15,7 +16,8 @@ public class PlayerListener implements Listener { public void playerJoinListener(PlayerJoinEvent event) { for (NPC npc : CitizensAPI.getNPCRegistry()) { if (npc.hasTrait(MinstrelTrait.class)) { - MinstrelPlugin.getTestPlaylist().play(npc.getTraitNullable(MinstrelTrait.class), event.getPlayer()); + MinstrelTrait minstrelTrait = npc.getTraitNullable(MinstrelTrait.class); + minstrelTrait.getPlaylist().play(minstrelTrait, event.getPlayer()); } } } diff --git a/src/main/java/net/knarcraft/minstrel/Playlist.java b/src/main/java/net/knarcraft/minstrel/music/Playlist.java similarity index 74% rename from src/main/java/net/knarcraft/minstrel/Playlist.java rename to src/main/java/net/knarcraft/minstrel/music/Playlist.java index e3786cb..1639749 100644 --- a/src/main/java/net/knarcraft/minstrel/Playlist.java +++ b/src/main/java/net/knarcraft/minstrel/music/Playlist.java @@ -1,5 +1,7 @@ -package net.knarcraft.minstrel; +package net.knarcraft.minstrel.music; +import net.knarcraft.minstrel.MinstrelPlugin; +import net.knarcraft.minstrel.trait.MinstrelTrait; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -14,7 +16,7 @@ public class Playlist { private final List songs; private final boolean loop; private int currentlyPlaying = 0; - private int schedulerId = 0; + private int schedulerId = -1; /** * Instantiates a new playlist @@ -54,6 +56,33 @@ public class Playlist { this.songs.remove(index); } + /** + * Stops all songs in this playlist for the given player + * + * @param player

The player to stop the playlist for

+ */ + public void stop(Player player) { + for (Song song : this.songs) { + if (song.isPlaying()) { + song.stop(player); + } + } + } + + /** + * Stops all songs in this playlist for all players, and aborts scheduling for the next song + */ + public void stop() { + for (Song song : this.songs) { + if (song.isPlaying()) { + for (Player player : Bukkit.getOnlinePlayers()) { + song.stop(player); + } + } + } + Bukkit.getScheduler().cancelTask(schedulerId); + } + /** * Plays the current song for the given player * @@ -69,10 +98,7 @@ public class Playlist { return; } - for (Song song : this.songs) { - song.stop(player); - } - + stop(player); Song currentSong = this.songs.get(this.currentlyPlaying - 1); currentSong.play(trait, player, trait.getVolume(), trait.getPitch()); } @@ -113,4 +139,11 @@ public class Playlist { }, currentSong.getDuration(), 20); } + /** + * Clears this playlist, removing any existing songs + */ + public void clear() { + this.songs.clear(); + } + } diff --git a/src/main/java/net/knarcraft/minstrel/Song.java b/src/main/java/net/knarcraft/minstrel/music/Song.java similarity index 79% rename from src/main/java/net/knarcraft/minstrel/Song.java rename to src/main/java/net/knarcraft/minstrel/music/Song.java index 99d2909..dbbf3a4 100644 --- a/src/main/java/net/knarcraft/minstrel/Song.java +++ b/src/main/java/net/knarcraft/minstrel/music/Song.java @@ -1,5 +1,7 @@ -package net.knarcraft.minstrel; +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; @@ -112,4 +114,35 @@ public class Song { } } + @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.

+ * + * @return

The category of this song

+ */ + public SoundCategory getCategory() { + return category; + } + + /** + * Gets the identifier for this song's sound + * + * @return

The identifier for this song's sound

+ */ + public String getSound() { + return this.sound; + } + } diff --git a/src/main/java/net/knarcraft/minstrel/trait/MinstrelTrait.java b/src/main/java/net/knarcraft/minstrel/trait/MinstrelTrait.java new file mode 100644 index 0000000..1157d43 --- /dev/null +++ b/src/main/java/net/knarcraft/minstrel/trait/MinstrelTrait.java @@ -0,0 +1,146 @@ +package net.knarcraft.minstrel.trait; + +import net.citizensnpcs.api.trait.Trait; +import net.citizensnpcs.api.util.DataKey; +import net.knarcraft.minstrel.MinstrelPlugin; +import net.knarcraft.minstrel.music.Playlist; +import net.knarcraft.minstrel.music.Song; +import org.bukkit.Location; +import org.bukkit.SoundCategory; + +import java.util.ArrayList; +import java.util.List; + +/** + * The minstrel trait itself, which contains all NPC data for this trait + */ +public class MinstrelTrait extends Trait { + + private final Playlist playlist = new Playlist(new ArrayList<>(), true); + private float volume = 1F; + private float pitch = 1F; + + /** + * Instantiates a new minstrel trait + */ + public MinstrelTrait() { + super("minstrel"); + } + + /** + * Gets the location of this minstrel + * + * @return

The location of this minstrel

+ */ + public Location getLocation() { + return this.getNPC().getStoredLocation(); + } + + /** + * Loads all config values stored in citizens' config file for this NPC + * + * @param key

The data key used for the config root

+ */ + @Override + public void load(DataKey key) { + this.playlist.clear(); + for (DataKey songKey : key.getRelative("playlist").getSubKeys()) { + String category = songKey.getString("category"); + SoundCategory soundCategory; + if (category.equalsIgnoreCase("null")) { + soundCategory = null; + } else { + soundCategory = SoundCategory.valueOf(category); + } + String soundIdentifier = songKey.getString("identifier"); + int songDuration = songKey.getInt("duration"); + Song song = new Song(soundCategory, soundIdentifier, songDuration); + this.playlist.addSong(song); + } + this.volume = (float) key.getDouble("volume", 1D); + this.pitch = (float) key.getDouble("pitch", 1D); + this.playlist.play(this); + + //Register the minstrel to allow stopping the playback later + MinstrelPlugin.getInstance().addMinstrel(this); + } + + /** + * Saves all of this NPC's config values to citizens' config file + * + * @param key

The data key used for the config root

+ */ + @Override + public void save(DataKey key) { + //Saves the songs in the playlist, the volume and the pitch + key.setRaw("playlist", null); + List songs = this.playlist.getSongs(); + for (int i = 0; i < songs.size(); i++) { + Song song = songs.get(i); + String songKey = "playlist." + i; + if (song.getCategory() == null) { + key.setString(songKey + ".category", "null"); + } else { + key.setString(songKey + ".category", song.getCategory().name()); + } + key.setString(songKey + ".identifier", song.getSound()); + key.setInt(songKey + ".duration", song.getDuration()); + } + key.setRaw("volume", this.getVolume()); + key.setRaw("pitch", this.getPitch()); + } + + /** + * Gets the volume to use for this minstrel + * + * @return

The volume of this minstrel

+ */ + public float getVolume() { + return this.volume; + } + + /** + * Gets the pitch to use for this minstrel + * + * @return

The pitch of this minstrel

+ */ + public float getPitch() { + return this.pitch; + } + + /** + * Gets this minstrel's playlist + * + * @return

This minstrel's playlist

+ */ + public Playlist getPlaylist() { + return this.playlist; + } + + /** + * Sets the volume for this minstrel + * + * @param newVolume

The volume for this minstrel

+ */ + public void setVolume(float newVolume) { + if (newVolume > 0) { + this.volume = newVolume; + } else { + throw new IllegalArgumentException("Volume cannot be negative!"); + } + } + + /** + * Sets the pitch for this minstrel + * + * @param newPitch

The new pitch for this minstrel

+ */ + public void setPitch(float newPitch) { + if (newPitch > 0) { + this.pitch = newPitch; + } else { + throw new IllegalArgumentException("Pitch cannot be negative!"); + } + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 78326df..19712ad 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,3 +6,13 @@ prefix: Minstrel depend: [ Citizens ] authors: [ EpicKnarvik97 ] description: Adds a minstrel trait to Citizens NPCs + +commands: + minstrel: + permission: minstrel.admin + usage: / [argument] + description: Used to see, or alter, a minstrel's songs +permissions: + minstrel.admin: + description: Allows configuring minstrels + default: op \ No newline at end of file