]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_ctf.qc
Move flag capture verbosity to MSG_CHOICE, plus fix some various things
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_ctf.qc
index e8fa4639b888ef90c53ba6ca5b4a3061e1a7e69e..e4b3a04e35da6fc90578092009b4c8f4391b378a 100644 (file)
@@ -22,31 +22,17 @@ void ctf_EventLog(string mode, float flagteam, entity actor) // use an alias for
 
 void ctf_CaptureRecord(entity flag, entity player)
 {
-       entity tmp_entity;
-       float notification, success;
        float cap_record = ctf_captimerecord;
        float cap_time = (time - flag.ctf_pickuptime);
-       float f1, f2 = NO_FL_ARG;
-       string s1, s2 = NO_STR_ARG;
        string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
        
-       // figure shit out
-       if(!ctf_captimerecord) 
-               { notification = APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_TIME_); s1 = player.netname; f1 = (cap_time * 100); success = TRUE; }
-       else if(cap_time < cap_record) 
-               { notification = APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_BROKEN_); s1 = player.netname; s2 = refername; f1 = (cap_time * 100); f2 = (cap_record * 100); success = TRUE; }
-       else
-               { notification = APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_UNBROKEN_); s1 = player.netname; s2 = refername; f1 = (cap_time * 100); f2 = (cap_record * 100); success = FALSE; }
-
        // notify about shit
-       FOR_EACH_REALCLIENT(tmp_entity)
-       {
-               if not(tmp_entity.CAPTURE_VERBOSE) { notification = APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_); s2 = NO_STR_ARG; f1 = f2 = NO_FL_ARG; }
-               Send_Notification(tmp_entity, MSG_ONE, MSG_INFO, notification, s1, s2, f1, f2, NO_FL_ARG);
-       }
-
+       if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
+       else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+       else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+       
        // write that shit in the database
-       if(success) 
+       if((!ctf_captimerecord) || (cap_time < cap_record))
        {
                ctf_captimerecord = cap_time;
                db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
@@ -168,11 +154,7 @@ void ctf_CaptureShield_Update(entity player, float wanted_status)
        float updated_status = ctf_CaptureShield_CheckStatus(player);
        if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status)) // 0: shield only, 1: unshield only
        {
-               if(updated_status) // TODO csqc notifier for this // Samual: How?
-                       Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-               else
-                       Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_FREE, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-                       
+               Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE));
                player.ctf_captureshielded = updated_status;
        }
 }
@@ -194,7 +176,7 @@ void ctf_CaptureShield_Touch()
        vector othermid = (other.absmin + other.absmax) * 0.5;
 
        Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
-       Send_Notification(other, MSG_ONE, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED);
 }
 
 void ctf_CaptureShield_Spawn(entity flag)
@@ -237,7 +219,7 @@ void ctf_Handle_Drop(entity flag, entity player, float droptype)
        flag.ctf_status = FLAG_DROPPED;
        
        // messages and sounds
-       Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_LOST_), player.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_LOST_), player.netname);
        sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTN_NONE);
        ctf_EventLog("dropped", player.team, player);
 
@@ -290,11 +272,11 @@ void ctf_Handle_Retrieve(entity flag, entity player)
        FOR_EACH_REALPLAYER(tmp_player)
        {
                if(tmp_player == sender)
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_SENT_), player.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_SENT_), player.netname);
                else if(tmp_player == player)
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname);
                else if(!IsDifferentTeam(tmp_player, sender))
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
        }
        
        // create new waypoint
@@ -407,6 +389,7 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
        if not(player) { return; } // without someone to give the reward to, we can't possibly cap
        
        // messages and sounds
+       Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
        ctf_CaptureRecord(enemy_flag, player);
        sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE);
        
@@ -448,8 +431,8 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
 void ctf_Handle_Return(entity flag, entity player)
 {
        // messages and sounds
-       Send_Notification(player, MSG_ONE, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_RETURN_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-       Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_RETURN_), player.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+       Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_RETURN_));
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_RETURN_), player.netname);
        sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTN_NONE);
        ctf_EventLog("return", flag.team, player);
 
@@ -473,7 +456,6 @@ void ctf_Handle_Return(entity flag, entity player)
 void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
 {
        // declarations
-       entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
        float pickup_dropped_score; // used to calculate dropped pickup score
        
        // attach the flag to the player
@@ -497,21 +479,15 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        }
 
        // messages and sounds
-       Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_PICKUP_), player.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_PICKUP_), player.netname);
+       
+       Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PICKUP_));
+       if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
+       
+       Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, CHOICE_CTF_PICKUP_TEAM, Team_ColorCode(player.team), player.netname);
+       Send_Notification(NOTIF_TEAM, flag, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY, Team_ColorCode(player.team), player.netname);
+       
        sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTN_NONE);
-
-       FOR_EACH_REALPLAYER(tmp_player)
-       {
-               if(tmp_player == player)
-               {
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PICKUP_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-                       if(ctf_stalemate) { Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG); }
-               }
-               else if(!IsDifferentTeam(tmp_player, player) && tmp_player != player)
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, (tmp_player.PICKUP_TEAM_VERBOSE ? CENTER_CTF_PICKUP_TEAM_VERBOSE : CENTER_CTF_PICKUP_TEAM), Team_ColorCode(player.team), (tmp_player.PICKUP_TEAM_VERBOSE ? player.netname : NO_STR_ARG), NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-               else if(IsDifferentTeam(tmp_player, player))
-                       Send_Notification(tmp_player, MSG_ONE, MSG_CENTER, (tmp_player.PICKUP_ENEMY_VERBOSE ? CENTER_CTF_PICKUP_ENEMY_VERBOSE : CENTER_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), (tmp_player.PICKUP_ENEMY_VERBOSE ? player.netname : NO_STR_ARG), NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-       }
        
        // scoring
        PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
@@ -569,14 +545,14 @@ void ctf_CheckFlagReturn(entity flag, float returntype)
                {
                        switch(returntype)
                        {
-                               case RETURN_DROPPED: Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DROPPED_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG); break;
-                               case RETURN_DAMAGE: Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DAMAGED_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG); break;
-                               case RETURN_SPEEDRUN: Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), NO_STR_ARG, NO_STR_ARG, ctf_captimerecord, NO_FL_ARG, NO_FL_ARG); break;
-                               case RETURN_NEEDKILL: Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_NEEDKILL_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG); break;
+                               case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DROPPED_)); break;
+                               case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DAMAGED_)); break;
+                               case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), ctf_captimerecord); break;
+                               case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_NEEDKILL_)); break;
                                
                                default:
                                case RETURN_TIMEOUT:
-                                       { Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_TIMEOUT_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG); break; }
+                                       { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
                        }
                        sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTN_NONE);
                        ctf_EventLog("returned", flag.team, world);
@@ -605,8 +581,8 @@ void ctf_CheckStalemate(void)
                        
                        switch(tmp_entity.team)
                        {
-                               case FL_TEAM_1: ++stale_red_flags; break;
-                               case FL_TEAM_2: ++stale_blue_flags; break;
+                               case NUM_TEAM_1: ++stale_red_flags; break;
+                               case NUM_TEAM_2: ++stale_blue_flags; break;
                        }
                }
        }
@@ -630,10 +606,7 @@ void ctf_CheckStalemate(void)
                if not(wpforenemy_announced)
                {
                        FOR_EACH_REALPLAYER(tmp_entity)
-                               if(tmp_entity.flagcarried)
-                                       Send_Notification(tmp_entity, MSG_ONE, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-                               else
-                                       Send_Notification(tmp_entity, MSG_ONE, MSG_CENTER, CENTER_CTF_STALEMATE_OTHER, NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
                        
                        wpforenemy_announced = TRUE;
                }
@@ -815,7 +788,7 @@ void ctf_FlagTouch()
                else
                        return; // do nothing
        }
-       else if(toucher.classname != "player") // The flag just touched an object, most likely the world
+       else if not(IS_PLAYER(toucher)) // The flag just touched an object, most likely the world
        {
                if(time > self.wait) // if we haven't in a while, play a sound/effect
                {
@@ -855,7 +828,7 @@ void ctf_FlagTouch()
                
                case FLAG_PASSING:
                {
-                       if((toucher.classname == "player") && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
+                       if((IS_PLAYER(toucher)) && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
                        {
                                if(IsDifferentTeam(toucher, self.pass_sender))
                                        ctf_Handle_Return(self, toucher);
@@ -918,7 +891,7 @@ void ctf_RespawnFlag(entity flag)
 void ctf_Reset()
 {
        if(self.owner)
-               if(self.owner.classname == "player")
+               if(IS_PLAYER(self.owner))
                        ctf_Handle_Throw(self.owner, world, DROP_RESET);
                        
        ctf_RespawnFlag(self);
@@ -932,7 +905,7 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
        self.bot_basewaypoint = self.nearestwaypoint;
 
        // waypointsprites
-       WaypointSprite_SpawnFixed(((self.team == FL_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
+       WaypointSprite_SpawnFixed(((self.team == NUM_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
        WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
 
        // captureshield setup
@@ -951,8 +924,8 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
 
        setattachment(flag, world, "");
 
-       flag.netname = ((teamnumber) ? "^1REPLACETHIS^7" : "^4REPLACETHIS^7"); // ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag");
-       flag.team = ((teamnumber) ? FL_TEAM_1 : FL_TEAM_2); // FL_TEAM_1: color 4 team (red) - FL_TEAM_2: color 13 team (blue)
+       flag.netname = ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag"); // Primarily only used for debugging or when showing nearby item name
+       flag.team = ((teamnumber) ? NUM_TEAM_1 : NUM_TEAM_2); // NUM_TEAM_1: color 4 team (red) - NUM_TEAM_2: color 13 team (blue)
        flag.items = ((teamnumber) ? IT_KEY2 : IT_KEY1); // IT_KEY2: gold key (redish enough) - IT_KEY1: silver key (bluish enough)
        flag.classname = "item_flag_team";
        flag.target = "###item###"; // wut?
@@ -974,22 +947,23 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        flag.think = ctf_FlagThink;
        flag.nextthink = time + FLAG_THINKRATE;
        flag.ctf_status = FLAG_BASE;
-       
-       if(!flag.model) { flag.model = ((teamnumber) ? autocvar_g_ctf_flag_red_model : autocvar_g_ctf_flag_blue_model); }
-       if(!flag.scale) { flag.scale = FLAG_SCALE; }
-       if(!flag.skin) { flag.skin = ((teamnumber) ? autocvar_g_ctf_flag_red_skin : autocvar_g_ctf_flag_blue_skin); }
-       if(!flag.toucheffect) { flag.toucheffect = ((teamnumber) ? "redflag_touch" : "blueflag_touch"); }
-       if(!flag.passeffect) { flag.passeffect = ((teamnumber) ? "red_pass" : "blue_pass"); }
-       if(!flag.capeffect) { flag.capeffect = ((teamnumber) ? "red_cap" : "blue_cap"); }
+
+       // appearence
+       if(flag.model == "")       { flag.model = ((teamnumber) ? autocvar_g_ctf_flag_red_model : autocvar_g_ctf_flag_blue_model); }
+       if(!flag.scale)            { flag.scale = FLAG_SCALE; }
+       if(!flag.skin)             { flag.skin = ((teamnumber) ? autocvar_g_ctf_flag_red_skin : autocvar_g_ctf_flag_blue_skin); }
+       if(flag.toucheffect == "") { flag.toucheffect = ((teamnumber) ? "redflag_touch" : "blueflag_touch"); }
+       if(flag.passeffect == "")  { flag.passeffect = ((teamnumber) ? "red_pass" : "blue_pass"); }
+       if(flag.capeffect == "")   { flag.capeffect = ((teamnumber) ? "red_cap" : "blue_cap"); }
        
        // sound 
-       if(!flag.snd_flag_taken) { flag.snd_flag_taken  = ((teamnumber) ? "ctf/red_taken.wav" : "ctf/blue_taken.wav"); }
-       if(!flag.snd_flag_returned) { flag.snd_flag_returned = ((teamnumber) ? "ctf/red_returned.wav" : "ctf/blue_returned.wav"); }
-       if(!flag.snd_flag_capture) { flag.snd_flag_capture = ((teamnumber) ? "ctf/red_capture.wav" : "ctf/blue_capture.wav"); } // blue team scores by capturing the red flag
-       if(!flag.snd_flag_respawn) { flag.snd_flag_respawn = "ctf/flag_respawn.wav"; } // if there is ever a team-based sound for this, update the code to match.
-       if(!flag.snd_flag_dropped) { flag.snd_flag_dropped = ((teamnumber) ? "ctf/red_dropped.wav" : "ctf/blue_dropped.wav"); }
-       if(!flag.snd_flag_touch) { flag.snd_flag_touch = "ctf/touch.wav"; } // again has no team-based sound
-       if(!flag.snd_flag_pass) { flag.snd_flag_pass = "ctf/pass.wav"; } // same story here
+       if(flag.snd_flag_taken == "")    { flag.snd_flag_taken  = ((teamnumber) ? "ctf/red_taken.wav" : "ctf/blue_taken.wav"); }
+       if(flag.snd_flag_returned == "") { flag.snd_flag_returned = ((teamnumber) ? "ctf/red_returned.wav" : "ctf/blue_returned.wav"); }
+       if(flag.snd_flag_capture == "")  { flag.snd_flag_capture = ((teamnumber) ? "ctf/red_capture.wav" : "ctf/blue_capture.wav"); } // blue team scores by capturing the red flag
+       if(flag.snd_flag_respawn == "")  { flag.snd_flag_respawn = "ctf/flag_respawn.wav"; } // if there is ever a team-based sound for this, update the code to match.
+       if(flag.snd_flag_dropped == "")  { flag.snd_flag_dropped = ((teamnumber) ? "ctf/red_dropped.wav" : "ctf/blue_dropped.wav"); }
+       if(flag.snd_flag_touch == "")    { flag.snd_flag_touch = "ctf/touch.wav"; } // again has no team-based sound
+       if(flag.snd_flag_pass == "")     { flag.snd_flag_pass = "ctf/pass.wav"; } // same story here
        
        // precache
        precache_sound(flag.snd_flag_taken);
@@ -1763,13 +1737,14 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerDamage) // for changing damage and force values t
                        frag_target.wps_helpme_time = time;
                        WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
                }
+               // todo: add notification for when flag carrier needs help?
        }
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(ctf_PlayerDies)
 {
-       if((frag_attacker != frag_target) && (frag_attacker.classname == "player") && (frag_target.flagcarried))
+       if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)) && (frag_target.flagcarried))
        {
                PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
                PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
@@ -1829,7 +1804,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                        
                        while(head) // find the closest acceptable target to pass to
                        {
-                               if(head.classname == "player" && head.deadflag == DEAD_NO)
+                               if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
                                if(head != player && !IsDifferentTeam(head, player))
                                if(!head.speedrunning && !head.vehicle)
                                {
@@ -1841,15 +1816,15 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                                        {
                                                if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried) 
                                                { 
-                                                       if(clienttype(head) == CLIENTTYPE_BOT)
+                                                       if(IS_BOT_CLIENT(head))
                                                        {
-                                                               Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
                                                                ctf_Handle_Throw(head, player, DROP_PASS);
                                                        }
                                                        else
                                                        {
-                                                               Send_Notification(head, MSG_ONE, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
-                                                               Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+                                                               Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname);
+                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
                                                        }
                                                        player.throw_antispam = time + autocvar_g_ctf_pass_wait; 
                                                        return TRUE; 
@@ -1886,7 +1861,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                                }
                                else
                                {
-                                       Send_Notification(player, MSG_ONE, MSG_CENTER, CENTER_CTF_FLAG_THROW_PUNISH, NO_STR_ARG, NO_STR_ARG, rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time), NO_FL_ARG, NO_FL_ARG);
+                                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_FLAG_THROW_PUNISH, rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time));
                                        return FALSE;
                                }
                        }
@@ -1961,7 +1936,7 @@ MUTATOR_HOOKFUNCTION(ctf_AbortSpeedrun)
 {
        if(self.flagcarried)
        {
-               Send_Notification(world, MSG_BROADCAST, MSG_INFO, APP_TEAM_ENT_2(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_), NO_STR_ARG, NO_STR_ARG, NO_FL_ARG, NO_FL_ARG, NO_FL_ARG);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_));
                ctf_RespawnFlag(self.flagcarried);
                return TRUE;
        }
@@ -2009,14 +1984,6 @@ MUTATOR_HOOKFUNCTION(ctf_BotRoles)
        return TRUE;
 }
 
-MUTATOR_HOOKFUNCTION(ctf_GetCvars)
-{
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, CAPTURE_VERBOSE, "notification_ctf_capture_verbose");
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, PICKUP_TEAM_VERBOSE, "notification_ctf_pickup_team_verbose");
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, PICKUP_ENEMY_VERBOSE, "notification_ctf_pickup_enemy_verbose");
-       return TRUE;
-}
-
 
 // ==========
 // Spawnfuncs
@@ -2029,7 +1996,7 @@ void spawnfunc_info_player_team1()
 {
        if(g_assault) { remove(self); return; }
        
-       self.team = FL_TEAM_1; // red
+       self.team = NUM_TEAM_1; // red
        spawnfunc_info_player_deathmatch();
 }
 
@@ -2041,7 +2008,7 @@ void spawnfunc_info_player_team2()
 {
        if(g_assault) { remove(self); return; }
        
-       self.team = FL_TEAM_2; // blue
+       self.team = NUM_TEAM_2; // blue
        spawnfunc_info_player_deathmatch();
 }
 
@@ -2052,7 +2019,7 @@ void spawnfunc_info_player_team3()
 {
        if(g_assault) { remove(self); return; }
        
-       self.team = FL_TEAM_3; // yellow
+       self.team = NUM_TEAM_3; // yellow
        spawnfunc_info_player_deathmatch();
 }
 
@@ -2064,7 +2031,7 @@ void spawnfunc_info_player_team4()
 {
        if(g_assault) { remove(self); return; }
        
-       self.team = FL_TEAM_4; // purple
+       self.team = NUM_TEAM_4; // purple
        spawnfunc_info_player_deathmatch();
 }
 
@@ -2166,8 +2133,8 @@ void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to
        if(find(world, classname, "ctf_team") == world)
        {
                print("No ""ctf_team"" entities found on this map, creating them anyway.\n");
-               ctf_SpawnTeam("Red", FL_TEAM_1 - 1);
-               ctf_SpawnTeam("Blue", FL_TEAM_2 - 1);
+               ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
+               ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
        }
        
        ctf_ScoreRules();
@@ -2201,7 +2168,6 @@ MUTATOR_DEFINITION(gamemode_ctf)
        MUTATOR_HOOK(VehicleExit, ctf_VehicleExit, CBC_ORDER_ANY);
        MUTATOR_HOOK(AbortSpeedrun, ctf_AbortSpeedrun, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRule, ctf_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetCvars, ctf_GetCvars, CBC_ORDER_ANY);
        
        MUTATOR_ONADD
        {
@@ -2210,9 +2176,17 @@ MUTATOR_DEFINITION(gamemode_ctf)
                ctf_Initialize();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ctf_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This is a game type and it cannot be removed at runtime.");
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;