Keeps track of current song individually
All checks were successful
KnarCraft/Minstrel/pipeline/head This commit looks good

This commit is contained in:
Kristian Knarvik 2023-09-01 05:04:25 +02:00
parent a243b3fc77
commit 44d5639bfc
7 changed files with 43 additions and 39 deletions

View File

@ -65,10 +65,6 @@ public class AddSongCommand implements CommandExecutor {
Song song = new Song(category, songIdString, duration); Song song = new Song(category, songIdString, duration);
playlist.addSong(song); playlist.addSong(song);
//If this is the first song in the playlist, start playing
if (playlist.getSongs().size() == 1) {
playlist.changeSong();
}
sender.sendMessage("New song added"); sender.sendMessage("New song added");
return true; return true;
} }

View File

@ -38,9 +38,6 @@ public class RemoveSongCommand implements CommandExecutor {
//Stop any minstrels from playing the removed song //Stop any minstrels from playing the removed song
playlist.stop(); playlist.stop();
playlist.removeSong(index); playlist.removeSong(index);
if (!playlist.getSongs().isEmpty()) {
playlist.changeSong();
}
sender.sendMessage("Song removed"); sender.sendMessage("Song removed");
} else { } else {
sender.sendMessage("The specified index is outside the bounds of the playlist"); sender.sendMessage("The specified index is outside the bounds of the playlist");

View File

@ -9,6 +9,7 @@ import net.knarcraft.minstrel.trait.MinstrelTrait;
import net.knarcraft.minstrel.util.SoundHelper; import net.knarcraft.minstrel.util.SoundHelper;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
/** /**
@ -16,12 +17,18 @@ import org.bukkit.event.player.PlayerMoveEvent;
*/ */
public class MinstrelListener implements Listener { public class MinstrelListener implements Listener {
@EventHandler
public void enterWorldListener(PlayerChangedWorldEvent event) {
QueueManager.clearQueue(event.getPlayer());
}
@EventHandler @EventHandler
public void playerMoveListener(PlayerMoveEvent event) { public void playerMoveListener(PlayerMoveEvent event) {
if (event.getTo() == null || event.getFrom().getBlock().equals(event.getTo().getBlock())) { if (event.getTo() == null || event.getFrom().getBlock().equals(event.getTo().getBlock())) {
return; return;
} }
// Start playback for any Minstrels that just entered the player's hearable range
for (MinstrelTrait minstrelTrait : MinstrelPlugin.getInstance().getMinstrels()) { for (MinstrelTrait minstrelTrait : MinstrelPlugin.getInstance().getMinstrels()) {
if (!SoundHelper.canHear(event.getPlayer(), minstrelTrait) || if (!SoundHelper.canHear(event.getPlayer(), minstrelTrait) ||
QueueManager.isQueued(event.getPlayer(), minstrelTrait)) { QueueManager.isQueued(event.getPlayer(), minstrelTrait)) {

View File

@ -63,4 +63,14 @@ public class QueueManager {
queuedMinstrels.get(songEndTime.player()).add(songEndTime.minstrelTrait()); queuedMinstrels.get(songEndTime.player()).add(songEndTime.minstrelTrait());
} }
/**
* Clears the song queue for the given player
*
* @param player <p>The player to clear the song queue for</p>
*/
public static void clearQueue(Player player) {
queuedMinstrels.remove(player);
songEndTimes.removeIf((songEndTime -> songEndTime.player().equals(player)));
}
} }

View File

@ -1,6 +1,5 @@
package net.knarcraft.minstrel.music; package net.knarcraft.minstrel.music;
import net.knarcraft.minstrel.MinstrelPlugin;
import net.knarcraft.minstrel.manager.QueueManager; import net.knarcraft.minstrel.manager.QueueManager;
import net.knarcraft.minstrel.trait.MinstrelTrait; import net.knarcraft.minstrel.trait.MinstrelTrait;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -17,8 +16,7 @@ import java.util.Map;
public class Playlist { public class Playlist {
private final List<Song> songs; private final List<Song> songs;
private int currentlyPlaying = 0; private final Map<Player, Integer> playerCurrentSong = new HashMap<>();
private final Map<Player, Song> playerCurrentSong = new HashMap<>();
/** /**
* Instantiates a new playlist * Instantiates a new playlist
@ -62,7 +60,11 @@ public class Playlist {
* @param player <p>The player to stop the playlist for</p> * @param player <p>The player to stop the playlist for</p>
*/ */
public void stop(Player player) { public void stop(Player player) {
Song currentlyPlaying = playerCurrentSong.get(player); Integer currentSong = this.playerCurrentSong.get(player);
if (currentSong == null) {
return;
}
Song currentlyPlaying = this.songs.get(currentSong);
if (currentlyPlaying != null) { if (currentlyPlaying != null) {
currentlyPlaying.stop(player); currentlyPlaying.stop(player);
playerCurrentSong.remove(player); playerCurrentSong.remove(player);
@ -71,6 +73,8 @@ public class Playlist {
/** /**
* Stops all songs in this playlist for all players, and aborts scheduling for the next song * Stops all songs in this playlist for all players, and aborts scheduling for the next song
*
* <p>This should only be triggered if a Minstrel, or a playlist song, is removed.</p>
*/ */
public void stop() { public void stop() {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
@ -78,10 +82,6 @@ public class Playlist {
song.stop(player); song.stop(player);
} }
} }
int schedulerId = -1;
if (Bukkit.getScheduler().isCurrentlyRunning(schedulerId)) {
Bukkit.getScheduler().cancelTask(schedulerId);
}
} }
/** /**
@ -99,9 +99,15 @@ public class Playlist {
return; return;
} }
stop(player); Song currentSong;
Song currentSong = this.songs.get(this.currentlyPlaying); if (this.playerCurrentSong.containsKey(player)) {
playerCurrentSong.put(player, currentSong); int songId = (this.playerCurrentSong.get(player) + 1) % songs.size();
this.playerCurrentSong.put(player, songId);
currentSong = songs.get(songId);
} else {
this.playerCurrentSong.put(player, 0);
currentSong = songs.get(0);
}
currentSong.play(trait, player, trait.getVolume(), trait.getPitch()); currentSong.play(trait, player, trait.getVolume(), trait.getPitch());
QueueManager.queue(new SongEndTime(player, trait, System.currentTimeMillis() + QueueManager.queue(new SongEndTime(player, trait, System.currentTimeMillis() +
(currentSong.getDuration() * 1000L))); (currentSong.getDuration() * 1000L)));
@ -114,29 +120,12 @@ public class Playlist {
this.songs.clear(); this.songs.clear();
} }
/**
* Changes to the next song in the playlist
*/
public void changeSong() {
if (this.songs.isEmpty()) {
return;
}
this.currentlyPlaying++;
this.currentlyPlaying = this.currentlyPlaying % this.songs.size();
Bukkit.getScheduler().scheduleSyncDelayedTask(MinstrelPlugin.getInstance(), this::changeSong,
this.songs.get(this.currentlyPlaying).getDuration() * 20L);
}
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (int i = 0; i < this.songs.size(); i++) { for (Song song : this.songs) {
builder.append("\n"); builder.append("\n");
if (this.currentlyPlaying == i) { builder.append(song);
builder.append(">");
}
builder.append(this.songs.get(i));
} }
return builder.toString(); return builder.toString();
} }

View File

@ -59,7 +59,6 @@ public class MinstrelTrait extends Trait {
} }
this.volume = (float) key.getDouble("volume", 1D); this.volume = (float) key.getDouble("volume", 1D);
this.pitch = (float) key.getDouble("pitch", 1D); this.pitch = (float) key.getDouble("pitch", 1D);
this.playlist.changeSong();
//Register the minstrel to allow stopping the playback later //Register the minstrel to allow stopping the playback later
MinstrelPlugin.getInstance().addMinstrel(this); MinstrelPlugin.getInstance().addMinstrel(this);

View File

@ -13,6 +13,12 @@ public class SoundHelper {
* @return <p>True if the player would hear the minstrel</p> * @return <p>True if the player would hear the minstrel</p>
*/ */
public static boolean canHear(Player player, MinstrelTrait minstrelTrait) { public static boolean canHear(Player player, MinstrelTrait minstrelTrait) {
// Minstrels cannot be heard across worlds!
if (player.getLocation().getWorld() != null && minstrelTrait.getLocation().getWorld() != null &&
!player.getLocation().getWorld().equals(minstrelTrait.getLocation().getWorld())) {
return false;
}
double distance = player.getLocation().distance(minstrelTrait.getNPC().getStoredLocation()); double distance = player.getLocation().distance(minstrelTrait.getNPC().getStoredLocation());
// A player can hear a minstrel 15 blocks away, but the distance increases if volume > 1 // A player can hear a minstrel 15 blocks away, but the distance increases if volume > 1
return distance < 15 * (Math.max(minstrelTrait.getVolume(), 1)); return distance < 15 * (Math.max(minstrelTrait.getVolume(), 1));