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

@ -64,11 +64,7 @@ public class AddSongCommand implements CommandExecutor {
}
Song song = new Song(category, songIdString, duration);
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");
return true;
}

View File

@ -38,9 +38,6 @@ public class RemoveSongCommand implements CommandExecutor {
//Stop any minstrels from playing the removed song
playlist.stop();
playlist.removeSong(index);
if (!playlist.getSongs().isEmpty()) {
playlist.changeSong();
}
sender.sendMessage("Song removed");
} else {
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 org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerMoveEvent;
/**
@ -16,12 +17,18 @@ import org.bukkit.event.player.PlayerMoveEvent;
*/
public class MinstrelListener implements Listener {
@EventHandler
public void enterWorldListener(PlayerChangedWorldEvent event) {
QueueManager.clearQueue(event.getPlayer());
}
@EventHandler
public void playerMoveListener(PlayerMoveEvent event) {
if (event.getTo() == null || event.getFrom().getBlock().equals(event.getTo().getBlock())) {
return;
}
// Start playback for any Minstrels that just entered the player's hearable range
for (MinstrelTrait minstrelTrait : MinstrelPlugin.getInstance().getMinstrels()) {
if (!SoundHelper.canHear(event.getPlayer(), minstrelTrait) ||
QueueManager.isQueued(event.getPlayer(), minstrelTrait)) {

View File

@ -63,4 +63,14 @@ public class QueueManager {
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;
import net.knarcraft.minstrel.MinstrelPlugin;
import net.knarcraft.minstrel.manager.QueueManager;
import net.knarcraft.minstrel.trait.MinstrelTrait;
import org.bukkit.Bukkit;
@ -17,8 +16,7 @@ import java.util.Map;
public class Playlist {
private final List<Song> songs;
private int currentlyPlaying = 0;
private final Map<Player, Song> playerCurrentSong = new HashMap<>();
private final Map<Player, Integer> playerCurrentSong = new HashMap<>();
/**
* Instantiates a new playlist
@ -62,7 +60,11 @@ public class Playlist {
* @param player <p>The player to stop the playlist for</p>
*/
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) {
currentlyPlaying.stop(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
*
* <p>This should only be triggered if a Minstrel, or a playlist song, is removed.</p>
*/
public void stop() {
for (Player player : Bukkit.getOnlinePlayers()) {
@ -78,10 +82,6 @@ public class Playlist {
song.stop(player);
}
}
int schedulerId = -1;
if (Bukkit.getScheduler().isCurrentlyRunning(schedulerId)) {
Bukkit.getScheduler().cancelTask(schedulerId);
}
}
/**
@ -99,9 +99,15 @@ public class Playlist {
return;
}
stop(player);
Song currentSong = this.songs.get(this.currentlyPlaying);
playerCurrentSong.put(player, currentSong);
Song currentSong;
if (this.playerCurrentSong.containsKey(player)) {
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());
QueueManager.queue(new SongEndTime(player, trait, System.currentTimeMillis() +
(currentSong.getDuration() * 1000L)));
@ -114,29 +120,12 @@ public class Playlist {
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
public String toString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < this.songs.size(); i++) {
for (Song song : this.songs) {
builder.append("\n");
if (this.currentlyPlaying == i) {
builder.append(">");
}
builder.append(this.songs.get(i));
builder.append(song);
}
return builder.toString();
}

View File

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

View File

@ -13,6 +13,12 @@ public class SoundHelper {
* @return <p>True if the player would hear the minstrel</p>
*/
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());
// A player can hear a minstrel 15 blocks away, but the distance increases if volume > 1
return distance < 15 * (Math.max(minstrelTrait.getVolume(), 1));