Browse Source

Added configurable settings

Configurable settings include deciding whether or not the plugin can
play songs during a map (so they can be disabled on maps with very short
rounds), and the number of songs per map.

Plugin has been tested to ensure the plugin can be disabled during Arena
maps, and that the playlist length can be altered between map changes.
nosoop 8 years ago
parent
commit
d84cdddbb4
1 changed files with 83 additions and 38 deletions
  1. 83 38
      scripting/round_end_music.sp

+ 83 - 38
scripting/round_end_music.sp

@@ -12,7 +12,7 @@
 #pragma newdecls required
 #include <round_end_music>
 
-#define PLUGIN_VERSION "0.0.0"
+#define PLUGIN_VERSION "0.1.0"
 public Plugin myinfo = {
     name = "[CSRD] Round End Music",
     author = "nosoop",
@@ -24,9 +24,12 @@ public Plugin myinfo = {
 bool g_bQueueLocked = false;
 ArrayList g_QueuedSongs, g_ActiveSongs, g_PlayedSongs;
 
+ConVar g_ConVarMaxActiveSongs, g_ConVarEnabled;
+
 Handle g_RequestSongForward;
 
 int g_nMaxActiveSongs = 5;
+bool g_bRoundEndMusicActive;
 
 public void OnPluginStart() {
 	g_QueuedSongs = new ArrayList();
@@ -39,6 +42,14 @@ public void OnPluginStart() {
 	
 	RegAdminCmd("sm_playsong", AdminCmd_PlaySong, ADMFLAG_ROOT);
 	RegAdminCmd("sm_peekqueue", AdminCmd_PeekQueue, ADMFLAG_ROOT);
+	
+	g_ConVarMaxActiveSongs = CreateConVar("sm_rem_active_songs", "5",
+			"Maximum number of songs available for playback on a single map.", _,
+			true, 1.0, false);
+	g_ConVarEnabled = CreateConVar("sm_rem_enabled", "1", "Enables Round End Music.", _,
+			true, 0.0, true, 1.0);
+	
+	AutoExecConfig();
 }
 
 public Action AdminCmd_PlaySong(int client, int argc) {
@@ -70,14 +81,22 @@ void PrintSongList(int client, const char[] listName, ArrayList songList) {
 	}
 }
 
-public void OnAutoConfigsBuffered() {
+public void OnConfigsExecuted() {
 	// TODO pull g_nMaxActiveSongs from ConVar -- it can't change during map
+	g_nMaxActiveSongs = g_ConVarMaxActiveSongs.IntValue;
+	g_bRoundEndMusicActive = g_ConVarEnabled.BoolValue;
 	
 	g_bQueueLocked = false;
 	Call_StartForward(g_RequestSongForward);
 	Call_Finish();
 	g_bQueueLocked = true;
 	
+	/**
+	 * It's okay if there are songs in the active list, as it won't be processed if the plugin
+	 * is set as disabled.  However...
+	 * 
+	 * TODO make the active song count implicitly zero when disabled?
+	 */
 	if (g_nMaxActiveSongs < g_ActiveSongs.Length) {
 		// Put excess songs back in the head of the queue
 		// Used if fewer active songs are required for long maps
@@ -86,10 +105,16 @@ public void OnAutoConfigsBuffered() {
 			int pos = g_ActiveSongs.Length - 1;
 			MusicEntry song = g_ActiveSongs.Get(pos);
 			
-			g_QueuedSongs.ShiftUp(0);
+			// Insert songs at the top of the queued songs list.
+			if (g_QueuedSongs.Length == 0) {
+				// Fix attempting to shift contents of an empty queue up.
+				g_QueuedSongs.Resize(1);
+			} else {
+				g_QueuedSongs.ShiftUp(0);
+			}
 			g_QueuedSongs.Set(0, song);
 			
-			g_ActiveSongs.Erase(0);
+			g_ActiveSongs.Erase(pos);
 		}
 	} else {
 		// Take up to g_nMaxActiveSongs songs from queue and move them to g_ActiveSongs
@@ -101,29 +126,38 @@ public void OnAutoConfigsBuffered() {
 		}
 	}
 	
-	// Do the Fisher-Yates.
-	// http://spin.atomicobject.com/2014/08/11/fisher-yates-shuffle-randomization-algorithm/
-	int nActiveSongs = g_ActiveSongs.Length < g_nMaxActiveSongs?
-			g_ActiveSongs.Length : g_nMaxActiveSongs;
-	
-	for (int i = 0; i < nActiveSongs; i+= 1) {
-		int s = GetRandomInt(i, nActiveSongs - 1);
-		SwapArrayItems(g_ActiveSongs, i, s);
-		
-		MusicEntry song = g_ActiveSongs.Get(i);
-		
-		char title[64], source[64], filePath[PLATFORM_MAX_PATH];
-		song.GetTitle(title, sizeof(title));
-		song.GetSource(source, sizeof(source));
-		song.GetFilePath(filePath, sizeof(filePath));
-		
-		char fileDownloadPath[PLATFORM_MAX_PATH];
-		Format(fileDownloadPath, sizeof(fileDownloadPath), "sound/%s", filePath);
-		AddFileToDownloadsTable(fileDownloadPath);
-		
-		PrecacheSound(filePath);
+	/**
+	 * Check to see if we should play music on this map.  If not, then don't process the active
+	 * music list.
+	 */
+	if (g_bRoundEndMusicActive) {
+		// Do the Fisher-Yates.
+		// http://spin.atomicobject.com/2014/08/11/fisher-yates-shuffle-randomization-algorithm/
+		int nActiveSongs = g_ActiveSongs.Length < g_nMaxActiveSongs?
+				g_ActiveSongs.Length : g_nMaxActiveSongs;
 		
-		PrintToServer("[rem] Added song %d: %s", i + 1, filePath);
+		for (int i = 0; i < nActiveSongs; i+= 1) {
+			int s = GetRandomInt(i, nActiveSongs - 1);
+			SwapArrayItems(g_ActiveSongs, i, s);
+			
+			MusicEntry song = g_ActiveSongs.Get(i);
+			
+			char title[64], source[64], filePath[PLATFORM_MAX_PATH];
+			song.GetTitle(title, sizeof(title));
+			song.GetSource(source, sizeof(source));
+			song.GetFilePath(filePath, sizeof(filePath));
+			
+			char fileDownloadPath[PLATFORM_MAX_PATH];
+			Format(fileDownloadPath, sizeof(fileDownloadPath), "sound/%s", filePath);
+			AddFileToDownloadsTable(fileDownloadPath);
+			
+			PrecacheSound(filePath);
+			
+			PrintToServer("[rem] Added song %d: %s", i + 1, filePath);
+		}
+		PrintToServer("[rem] Round End Music plugin enabled.");
+	} else {
+		PrintToServer("[rem] Round End Music plugin disabled.");
 	}
 }
 
@@ -148,7 +182,7 @@ public void OnMapEnd() {
  * Play pending endround music.
  */
 void PlayRoundEndMusic() {
-	if (g_ActiveSongs.Length == 0) {
+	if (g_ActiveSongs.Length == 0 || !g_bRoundEndMusicActive) {
 		PrintToServer("no songs to play :(");
 		return;
 	}
@@ -157,17 +191,7 @@ void PlayRoundEndMusic() {
 	
 	// mock play for testing
 	// TODO move into a function with shiny forwards
-	char filePath[PLATFORM_MAX_PATH];
-	song.GetFilePath(filePath, sizeof(filePath));
-	
-	PrintToServer("mock play song %s", filePath);
-	EmitSoundToAll(filePath);
-	
-	if (g_PlayedSongs.FindValue(song) == -1) {
-		g_PlayedSongs.Push(song);
-	}
-	
-	g_ActiveSongs.Erase(0);
+	EmitRoundEndMusic(song);
 	
 	// if 'active' is empty, copy all back into 'active' without removing from 'played'
 	if (g_ActiveSongs.Length == 0) {
@@ -184,12 +208,33 @@ void PlayRoundEndMusic() {
 	}
 }
 
+void EmitRoundEndMusic(MusicEntry song) {
+	char filePath[PLATFORM_MAX_PATH];
+	song.GetFilePath(filePath, sizeof(filePath));
+	
+	PrintToServer("mock play song %s", filePath);
+	EmitSoundToAll(filePath);
+	
+	// TODO create new forward OnRoundEndMusicPlayed(MusicEntry song) ?
+	// - Plugin_Continue uses default handling
+	// - Plugin_Handled does not
+	// - Plugin_Stop doesn't either, but the implication is that the entire endround is canceled
+	//   (i.e., it shouldn't move it to the played list)
+	
+	if (g_PlayedSongs.FindValue(song) == -1) {
+		g_PlayedSongs.Push(song);
+	}
+	
+	g_ActiveSongs.Erase(0);
+}
+
 public void OnRoundEnd(Event event, const char[] name, bool dontBroadcast) {
 	PlayRoundEndMusic();
 }
 
 // menu: read entries from g_PlayedSongs and then g_ActiveSongs if not empty
 // that *should* maintain initial play order
+// maybe we should just provide a function that provides the entire list and active counts?
 
 /* Native function calls */
 public APLRes AskPluginLoad2(Handle self, bool late, char[] error, int err_max) {