]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_ctf.qc
Merge branch 'master' into divVerent/4team_ctf
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_ctf.qc
index 3ae63436b8bae44536b2bb396033a107ac21d580..0c61e4a94f3fdb48f3698a4f6fa41d06a7644b79 100644 (file)
@@ -25,20 +25,20 @@ void ctf_CaptureRecord(entity flag, entity player)
        float cap_record = ctf_captimerecord;
        float cap_time = (time - flag.ctf_pickuptime);
        string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
-       
+
        // notify about shit
        if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(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_4(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_4(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
-       
+
        // write that shit in the database
        if((!ctf_captimerecord) || (cap_time < cap_record))
        {
                ctf_captimerecord = cap_time;
                db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
                db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
-               write_recordmarker(player, (time - cap_time), cap_time); 
-       } 
+               write_recordmarker(player, (time - cap_time), cap_time);
+       }
 }
 
 void ctf_FlagcarrierWaypoints(entity player)
@@ -92,7 +92,7 @@ float ctf_CheckPassDirection(vector head_center, vector passer_center, vector pa
                float ang; // angle between shotdir and h
                float h; // hypotenuse, which is the distance between attacker to head
                float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
-               
+
                h = vlen(head_center - passer_center);
                ang = acos(dotproduct(normalize(head_center - passer_center), v_forward));
                a = h * cos(ang);
@@ -117,26 +117,26 @@ float ctf_Stalemate_customizeentityforclient()
        entity e, wp_owner;
        e = WaypointSprite_getviewentity(other);
        wp_owner = self.owner;
-       
+
        // team waypoints
        if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner))
                return FALSE;
-               
+
        if(SAME_TEAM(wp_owner, e))
                return FALSE;
-               
-       if not(IS_PLAYER(e))
+
+       if(!IS_PLAYER(e))
                return FALSE;
-               
+
        return TRUE;
 }
 
 
 // =======================
-// CaptureShield Functions 
+// CaptureShield Functions
 // =======================
 
-float ctf_CaptureShield_CheckStatus(entity p) 
+float ctf_CaptureShield_CheckStatus(entity p)
 {
        float s, s2, s3, s4, se, se2, se3, se4, sr, ser;
        entity e;
@@ -144,14 +144,14 @@ float ctf_CaptureShield_CheckStatus(entity p)
 
        if(ctf_captureshield_max_ratio <= 0)
                return FALSE;
-               
+
        s = PlayerScore_Add(p, SP_CTF_CAPS, 0);
        s2 = PlayerScore_Add(p, SP_CTF_PICKUPS, 0);
        s3 = PlayerScore_Add(p, SP_CTF_RETURNS, 0);
        s4 = PlayerScore_Add(p, SP_CTF_FCKILLS, 0);
-       
+
        sr = ((s - s2) + (s3 + s4));
-       
+
        if(sr >= -ctf_captureshield_min_negscore)
                return FALSE;
 
@@ -164,9 +164,9 @@ float ctf_CaptureShield_CheckStatus(entity p)
                se2 = PlayerScore_Add(e, SP_CTF_PICKUPS, 0);
                se3 = PlayerScore_Add(e, SP_CTF_RETURNS, 0);
                se4 = PlayerScore_Add(e, SP_CTF_FCKILLS, 0);
-               
+
                ser = ((se - se2) + (se3 + se4));
-               
+
                if(ser <= sr)
                        ++players_worseeq;
                ++players_total;
@@ -174,7 +174,7 @@ float ctf_CaptureShield_CheckStatus(entity p)
 
        // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse
        // use this rule here
-       
+
        if(players_worseeq >= players_total * ctf_captureshield_max_ratio)
                return FALSE;
 
@@ -195,7 +195,7 @@ float ctf_CaptureShield_Customize()
 {
        if(!other.ctf_captureshielded) { return FALSE; }
        if(CTF_SAMETEAM(self, other)) { return FALSE; }
-       
+
        return TRUE;
 }
 
@@ -203,7 +203,7 @@ void ctf_CaptureShield_Touch()
 {
        if(!other.ctf_captureshielded) { return; }
        if(CTF_SAMETEAM(self, other)) { return; }
-       
+
        vector mymid = (self.absmin + self.absmax) * 0.5;
        vector othermid = (other.absmin + other.absmax) * 0.5;
 
@@ -214,7 +214,7 @@ void ctf_CaptureShield_Touch()
 void ctf_CaptureShield_Spawn(entity flag)
 {
        entity shield = spawn();
-       
+
        shield.enemy = self;
        shield.team = self.team;
        shield.touch = ctf_CaptureShield_Touch;
@@ -225,7 +225,7 @@ void ctf_CaptureShield_Spawn(entity flag)
        shield.solid = SOLID_TRIGGER;
        shield.avelocity = '7 0 11';
        shield.scale = 0.5;
-       
+
        setorigin(shield, self.origin);
        setmodel(shield, "models/ctf/shield.md3");
        setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
@@ -249,16 +249,16 @@ void ctf_Handle_Drop(entity flag, entity player, float droptype)
        flag.ctf_droptime = time;
        flag.ctf_dropper = player;
        flag.ctf_status = FLAG_DROPPED;
-       
+
        // messages and sounds
        Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_LOST_), player.netname);
        sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
        ctf_EventLog("dropped", player.team, player);
 
        // scoring
-       PlayerTeamScore_AddScore(player, -autocvar_g_ctf_score_penalty_drop);   
+       PlayerTeamScore_AddScore(player, -autocvar_g_ctf_score_penalty_drop);
        PlayerScore_Add(player, SP_CTF_DROPS, 1);
-       
+
        // waypoints
        if(autocvar_g_ctf_flag_dropped_waypoint)
                WaypointSprite_Spawn("flagdropped", 0, 0, flag, FLAG_WAYPOINT_OFFSET, world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, TRUE, RADARICON_FLAG, WPCOLOR_DROPPEDFLAG(flag.team));
@@ -268,9 +268,9 @@ void ctf_Handle_Drop(entity flag, entity player, float droptype)
                WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_flag_health);
                WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health);
        }
-       
+
        player.throw_antispam = time + autocvar_g_ctf_pass_wait;
-       
+
        if(droptype == DROP_PASS)
        {
                flag.pass_distance = 0;
@@ -283,11 +283,11 @@ void ctf_Handle_Retrieve(entity flag, entity player)
 {
        entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
        entity sender = flag.pass_sender;
-       
+
        // transfer flag to player
        flag.owner = player;
        flag.owner.flagcarried = flag;
-       
+
        // reset flag
        setattachment(flag, player, "");
        setorigin(flag, FLAG_CARRY_OFFSET);
@@ -300,7 +300,7 @@ void ctf_Handle_Retrieve(entity flag, entity player)
        // messages and sounds
        sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
        ctf_EventLog("receive", flag.team, player);
-       
+
        FOR_EACH_REALPLAYER(tmp_player)
        {
                if(tmp_player == sender)
@@ -310,10 +310,10 @@ void ctf_Handle_Retrieve(entity flag, entity player)
                else if(SAME_TEAM(tmp_player, sender))
                        Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
        }
-       
+
        // create new waypoint
        ctf_FlagcarrierWaypoints(player);
-       
+
        sender.throw_antispam = time + autocvar_g_ctf_pass_wait;
        player.throw_antispam = sender.throw_antispam;
 
@@ -326,12 +326,12 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
 {
        entity flag = player.flagcarried;
        vector targ_origin, flag_velocity;
-       
+
        if(!flag) { return; }
        if((droptype == DROP_PASS) && !receiver) { return; }
-       
+
        if(flag.speedrunning) { ctf_RespawnFlag(flag); return; }
-       
+
        // reset the flag
        setattachment(flag, world, "");
        setorigin(flag, player.origin + FLAG_DROP_OFFSET);
@@ -340,9 +340,9 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
        flag.solid = SOLID_TRIGGER;
        flag.ctf_dropper = player;
        flag.ctf_droptime = time;
-       
+
        flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
-       
+
        switch(droptype)
        {
                case DROP_PASS:
@@ -363,30 +363,30 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
                        flag.pass_sender = player;
                        flag.pass_target = receiver;
                        flag.ctf_status = FLAG_PASSING;
-                       
+
                        // other
                        sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
                        WarpZone_TrailParticles(world, particleeffectnum(flag.passeffect), player.origin, targ_origin);
                        ctf_EventLog("pass", flag.team, player);
                        break;
                }
-               
+
                case DROP_THROW:
                {
                        makevectors((player.v_angle_y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle_x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
-                               
+
                        flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & IT_STRENGTH) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
                        flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, FALSE);
                        ctf_Handle_Drop(flag, player, droptype);
                        break;
                }
-               
+
                case DROP_RESET:
                {
                        flag.velocity = '0 0 0'; // do nothing
                        break;
                }
-               
+
                default:
                case DROP_NORMAL:
                {
@@ -399,10 +399,10 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
        // kill old waypointsprite
        WaypointSprite_Ping(player.wps_flagcarrier);
        WaypointSprite_Kill(player.wps_flagcarrier);
-       
+
        if(player.wps_enemyflagcarrier)
                WaypointSprite_Kill(player.wps_enemyflagcarrier);
-       
+
        // captureshield
        ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
 }
@@ -416,23 +416,23 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
 {
        entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher);
        entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper);
-       float old_time, new_time; 
-       
-       if not(player) { return; } // without someone to give the reward to, we can't possibly cap
+       float old_time, new_time;
+
+       if(!player) { return; } // without someone to give the reward to, we can't possibly cap
        if(CTF_DIFFTEAM(player, flag)) { return; }
-       
+
        // messages and sounds
        Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_));
        ctf_CaptureRecord(enemy_flag, player);
        sound(player, CH_TRIGGER, ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture), VOL_BASE, ATTEN_NONE);
-       
+
        switch(capturetype)
        {
                case CAPTURE_NORMAL: ctf_EventLog("capture", enemy_flag.team, player); break;
                case CAPTURE_DROPPED: ctf_EventLog("droppedcapture", enemy_flag.team, player); break;
                default: break;
        }
-       
+
        // scoring
        PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_capture);
        PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
@@ -451,11 +451,11 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
        {
                WaypointSprite_Kill(player.wps_flagcarrier);
                if(flag.speedrunning) { ctf_FakeTimeLimit(player, -1); }
-               
+
                if((enemy_flag.ctf_dropper) && (player != enemy_flag.ctf_dropper))
                        { PlayerTeamScore_AddScore(enemy_flag.ctf_dropper, autocvar_g_ctf_score_capture_assist); }
        }
-       
+
        // reset the flag
        player.next_take_time = time + autocvar_g_ctf_flag_collect_delay;
        ctf_RespawnFlag(enemy_flag);
@@ -474,14 +474,18 @@ void ctf_Handle_Return(entity flag, entity player)
        PlayerScore_Add(player, SP_CTF_RETURNS, 1); // add to count of returns
 
        TeamScore_AddToTeam(flag.team, ST_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the team who was last carrying it
-       
-       if(flag.ctf_dropper) 
+
+       if(flag.ctf_dropper)
        {
                PlayerScore_Add(flag.ctf_dropper, SP_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the player who dropped the flag
-               ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag 
+               ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag
                flag.ctf_dropper.next_take_time = time + autocvar_g_ctf_flag_collect_delay; // set next take time
        }
        
+       // other
+       if(player.flagcarried == flag)
+               WaypointSprite_Kill(player.wps_flagcarrier);
+
        // reset the flag
        ctf_RespawnFlag(flag);
 }
@@ -491,20 +495,20 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        // declarations
        float pickup_dropped_score; // used to calculate dropped pickup score
        entity tmp_entity; // temporary entity
-       
+
        // attach the flag to the player
        flag.owner = player;
        player.flagcarried = flag;
        setattachment(flag, player, "");
        setorigin(flag, FLAG_CARRY_OFFSET);
-       
+
        // flag setup
        flag.movetype = MOVETYPE_NONE;
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
        flag.angles = '0 0 0';
        flag.ctf_status = FLAG_CARRY;
-       
+
        switch(pickuptype)
        {
                case PICKUP_BASE: flag.ctf_pickuptime = time; break; // used for timing runs
@@ -513,29 +517,34 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        }
 
        // messages and sounds
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_), player.netname);  
-       Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_));
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_), player.netname);
        if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
-       
+       if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); }
+       else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); }
+
        Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
-       
+
        FOR_EACH_PLAYER(tmp_entity)
+       if(tmp_entity != player)
        if(CTF_SAMETEAM(flag, tmp_entity))
+       if(SAME_TEAM(player, tmp_entity))
+               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
+       else
                Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
-       
+
        sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
-       
+
        // scoring
        PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
        switch(pickuptype)
-       {               
+       {
                case PICKUP_BASE:
                {
                        PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_pickup_base);
                        ctf_EventLog("steal", flag.team, player);
                        break;
                }
-               
+
                case PICKUP_DROPPED:
                {
                        pickup_dropped_score = (autocvar_g_ctf_flag_return_time ? bound(0, ((flag.ctf_droptime + autocvar_g_ctf_flag_return_time) - time) / autocvar_g_ctf_flag_return_time, 1) : 1);
@@ -545,10 +554,10 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
                        ctf_EventLog("pickup", flag.team, player);
                        break;
                }
-               
+
                default: break;
        }
-       
+
        // speedrunning
        if(pickuptype == PICKUP_BASE)
        {
@@ -556,11 +565,11 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
                if((player.speedrunning) && (ctf_captimerecord))
                        ctf_FakeTimeLimit(player, time + ctf_captimerecord);
        }
-               
+
        // effects
        pointparticles(particleeffectnum(flag.toucheffect), player.origin, '0 0 0', 1);
-       
-       // waypoints 
+
+       // waypoints
        if(pickuptype == PICKUP_DROPPED) { WaypointSprite_Kill(flag.wps_flagdropped); }
        ctf_FlagcarrierWaypoints(player);
        WaypointSprite_Ping(player.wps_flagcarrier);
@@ -576,7 +585,7 @@ void ctf_CheckFlagReturn(entity flag, float returntype)
        if((flag.ctf_status == FLAG_DROPPED) || (flag.ctf_status == FLAG_PASSING))
        {
                if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health); }
-               
+
                if((flag.health <= 0) || (time >= flag.ctf_droptime + autocvar_g_ctf_flag_return_time))
                {
                        switch(returntype)
@@ -585,7 +594,7 @@ void ctf_CheckFlagReturn(entity flag, float returntype)
                                case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_)); break;
                                case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), ctf_captimerecord); break;
                                case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_)); break;
-                               
+
                                default:
                                case RETURN_TIMEOUT:
                                        { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
@@ -614,7 +623,7 @@ void ctf_CheckStalemate(void)
                {
                        tmp_entity.ctf_staleflagnext = ctf_staleflaglist; // link flag into staleflaglist
                        ctf_staleflaglist = tmp_entity;
-                       
+
                        switch(tmp_entity.team)
                        {
                                case NUM_TEAM_1: ++stale_red_flags; break;
@@ -624,16 +633,16 @@ void ctf_CheckStalemate(void)
                        }
                }
        }
-       
+
        stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
-       
+
        if(stale_flags == ctf_teams)
                ctf_stalemate = TRUE;
        else if(stale_flags == 0 && autocvar_g_ctf_stalemate_endcondition == 2)
                { ctf_stalemate = FALSE; wpforenemy_announced = FALSE; }
        else if(stale_flags < ctf_teams && autocvar_g_ctf_stalemate_endcondition == 1)
                { ctf_stalemate = FALSE; wpforenemy_announced = FALSE; }
-               
+
        // if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary
        if(ctf_stalemate)
        {
@@ -645,12 +654,12 @@ void ctf_CheckStalemate(void)
                                tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_customizeentityforclient;
                        }
                }
-               
-               if not(wpforenemy_announced)
+
+               if (!wpforenemy_announced)
                {
                        FOR_EACH_REALPLAYER(tmp_entity)
                                Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
-                       
+
                        wpforenemy_announced = TRUE;
                }
        }
@@ -665,7 +674,7 @@ void ctf_FlagDamage(entity inflictor, entity attacker, float damage, float death
                ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
                return;
        }
-       if(autocvar_g_ctf_flag_return_damage) 
+       if(autocvar_g_ctf_flag_return_damage)
        {
                // reduce health and check if it should be returned
                self.health = self.health - damage;
@@ -692,7 +701,7 @@ void ctf_FlagThink()
                tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
                if(!trace_startsolid) // can we resize it without getting stuck?
                        setsize(self, FLAG_MIN, FLAG_MAX); }
-                       
+
        switch(self.ctf_status) // reset flag angles in case warpzones adjust it
        {
                case FLAG_DROPPED:
@@ -700,13 +709,13 @@ void ctf_FlagThink()
                        self.angles = '0 0 0';
                        break;
                }
-               
+
                default: break;
        }
 
        // main think method
        switch(self.ctf_status)
-       {       
+       {
                case FLAG_BASE:
                {
                        if(autocvar_g_ctf_dropped_capture_radius)
@@ -719,7 +728,7 @@ void ctf_FlagThink()
                        }
                        return;
                }
-               
+
                case FLAG_DROPPED:
                {
                        if(autocvar_g_ctf_flag_dropped_floatinwater)
@@ -728,7 +737,7 @@ void ctf_FlagThink()
                                if(pointcontents(midpoint) == CONTENT_WATER)
                                {
                                        self.velocity = self.velocity * 0.5;
-                                       
+
                                        if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
                                                { self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
                                        else
@@ -750,13 +759,13 @@ void ctf_FlagThink()
                                self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE);
                                ctf_CheckFlagReturn(self, RETURN_TIMEOUT);
                                return;
-                       } 
+                       }
                        return;
                }
-                       
+
                case FLAG_CARRY:
                {
-                       if(self.speedrunning && ctf_captimerecord && (time >= self.ctf_pickuptime + ctf_captimerecord)) 
+                       if(self.speedrunning && ctf_captimerecord && (time >= self.ctf_pickuptime + ctf_captimerecord))
                        {
                                self.health = 0;
                                ctf_CheckFlagReturn(self, RETURN_SPEEDRUN);
@@ -777,18 +786,20 @@ void ctf_FlagThink()
                        }
                        if(CTF_SAMETEAM(self, self.owner))
                        {
-                               // drop the flag if reverse status has changed
-                               ctf_Handle_Throw(self.owner, world, DROP_THROW);
+                               if(autocvar_g_ctf_flag_return) // drop the flag if reverse status has changed
+                                       ctf_Handle_Throw(self.owner, world, DROP_THROW);
+                               else if(vlen(self.owner.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_carried_radius)
+                                       ctf_Handle_Return(self, self.owner);
                        }
                        return;
                }
-               
+
                case FLAG_PASSING:
                {
                        vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
                        targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin); // origin of target as seen by the flag (us)
                        WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
-                       
+
                        if((self.pass_target == world)
                                || (self.pass_target.deadflag != DEAD_NO)
                                || (self.pass_target.flagcarried)
@@ -818,9 +829,9 @@ void ctf_FlagThink()
 void ctf_FlagTouch()
 {
        if(gameover) { return; }
-       
+
        entity toucher = other;
-       
+
        // automatically kill the flag and return it if it touched lava/slime/nodrop surfaces
        if(ITEM_TOUCH_NEEDKILL())
        {
@@ -828,7 +839,7 @@ void ctf_FlagTouch()
                ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
                return;
        }
-       
+
        // special touch behaviors
        if(toucher.vehicle_flags & VHF_ISVEHICLE)
        {
@@ -837,7 +848,7 @@ void ctf_FlagTouch()
                else
                        return; // do nothing
        }
-       else if not(IS_PLAYER(toucher)) // The flag just touched an object, most likely the world
+       else if (!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
                {
@@ -849,8 +860,8 @@ void ctf_FlagTouch()
        }
        else if(toucher.deadflag != DEAD_NO) { return; }
 
-       switch(self.ctf_status) 
-       {       
+       switch(self.ctf_status)
+       {
                case FLAG_BASE:
                {
                        if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self))
@@ -859,22 +870,22 @@ void ctf_FlagTouch()
                                ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
                        break;
                }
-               
+
                case FLAG_DROPPED:
                {
-                       if(CTF_SAMETEAM(toucher, self))
+                       if(CTF_SAMETEAM(toucher, self) && autocvar_g_ctf_flag_return)
                                ctf_Handle_Return(self, toucher); // toucher just returned his own flag
                        else if((!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
                                ctf_Handle_Pickup(self, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
                        break;
                }
-                       
+
                case FLAG_CARRY:
                {
                        dprint("Someone touched a flag even though it was being carried?\n");
                        break;
                }
-               
+
                case FLAG_PASSING:
                {
                        if((IS_PLAYER(toucher)) && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
@@ -897,13 +908,13 @@ void ctf_RespawnFlag(entity flag)
                { backtrace("flag respawn called twice quickly! please notify Samual about this..."); }
 
        flag.last_respawn = time;
-       
+
        // reset the player (if there is one)
        if((flag.owner) && (flag.owner.flagcarried == flag))
        {
                WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
                WaypointSprite_Kill(flag.wps_flagcarrier);
-               
+
                flag.owner.flagcarried = world;
 
                if(flag.speedrunning)
@@ -916,7 +927,7 @@ void ctf_RespawnFlag(entity flag)
        // reset the flag
        setattachment(flag, world, "");
        setorigin(flag, flag.ctf_spawnorigin);
-       
+
        flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
        flag.takedamage = DAMAGE_NO;
        flag.health = flag.max_flag_health;
@@ -924,7 +935,7 @@ void ctf_RespawnFlag(entity flag)
        flag.velocity = '0 0 0';
        flag.angles = flag.mangle;
        flag.flags = FL_ITEM | FL_NOTARGET;
-       
+
        flag.ctf_status = FLAG_BASE;
        flag.owner = world;
        flag.pass_distance = 0;
@@ -940,7 +951,7 @@ void ctf_Reset()
        if(self.owner)
                if(IS_PLAYER(self.owner))
                        ctf_Handle_Throw(self.owner, world, DROP_RESET);
-                       
+
        ctf_RespawnFlag(self);
 }
 
@@ -953,7 +964,7 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
 
        // waypointsprites
        string basename = "base";
-       
+
        switch(self.team)
        {
                case NUM_TEAM_1: basename = "redbase"; break;
@@ -961,7 +972,7 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
                case NUM_TEAM_3: basename = "yellowbase"; break;
                case NUM_TEAM_4: basename = "pinkbase"; break;
        }
-       
+
        WaypointSprite_SpawnFixed(basename, 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));
 
@@ -973,13 +984,13 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
 {
        // declarations
        self = flag; // for later usage with droptofloor()
-       
+
        // main setup
        flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
        ctf_worldflaglist = flag;
 
        setattachment(flag, world, "");
-       
+
        flag.netname = ((teamnumber == NUM_TEAM_1) ? "^1RED^7 flag" : ((teamnumber == NUM_TEAM_2) ? "^2BLUE^7 flag" : ((teamnumber == NUM_TEAM_3) ? "^3YELLOW^7 flag" : "^6PINK^7 flag")));
        flag.team = teamnumber;
        flag.classname = "item_flag_team";
@@ -987,7 +998,7 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        flag.flags = FL_ITEM | FL_NOTARGET;
        flag.solid = SOLID_TRIGGER;
        flag.takedamage = DAMAGE_NO;
-       flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;   
+       flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
        flag.max_flag_health = ((autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health) ? autocvar_g_ctf_flag_health : 100);
        flag.health = flag.max_flag_health;
        flag.event_damage = ctf_FlagDamage;
@@ -1005,12 +1016,12 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
 
        // appearence
        if(flag.model == "")       { flag.model = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_model : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_model : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_model : autocvar_g_ctf_flag_pink_model))); }
+       if(!flag.scale)            { flag.scale = FLAG_SCALE; }
        if(!flag.skin)             { flag.skin = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_skin : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_skin : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_skin : autocvar_g_ctf_flag_pink_skin))); }
        if(flag.toucheffect == "") { flag.toucheffect = ((teamnumber == NUM_TEAM_1) ? "redflag_touch" : ((teamnumber == NUM_TEAM_2) ? "blueflag_touch" : ((teamnumber == NUM_TEAM_3) ? "yellowflag_touch" : "pinkflag_touch"))); }
        if(flag.passeffect == "")  { flag.passeffect = ((teamnumber == NUM_TEAM_1) ? "red_pass" : ((teamnumber == NUM_TEAM_2) ? "blue_pass" : ((teamnumber == NUM_TEAM_3) ? "yellow_pass" : "pink_pass"))); }
        if(flag.capeffect == "")   { flag.capeffect = ((teamnumber == NUM_TEAM_1) ? "red_cap" : ((teamnumber == NUM_TEAM_2) ? "blue_cap" : ((teamnumber == NUM_TEAM_3) ? "yellow_cap" : "pink_cap"))); }
-       if(!flag.scale) { flag.scale = FLAG_SCALE; }
-       
+
        // sound
        if(flag.snd_flag_taken == "")    { flag.snd_flag_taken = ((teamnumber == NUM_TEAM_1) ? "ctf/red_taken.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_taken.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_taken.wav" : "ctf/pink_taken.wav"))); }
        if(flag.snd_flag_returned == "") { flag.snd_flag_returned = ((teamnumber == NUM_TEAM_1) ? "ctf/red_returned.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_returned.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_returned.wav" : "ctf/pink_returned.wav"))); }
@@ -1019,7 +1030,7 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a 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_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);
        precache_sound(flag.snd_flag_returned);
@@ -1036,14 +1047,14 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        setmodel(flag, flag.model); // precision set below
        setsize(flag, FLAG_MIN, FLAG_MAX);
        setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
-       
+
        if(autocvar_g_ctf_flag_glowtrails)
        {
                flag.glow_color = ((teamnumber == NUM_TEAM_1) ? 251 : ((teamnumber == NUM_TEAM_2) ? 210 : ((teamnumber == NUM_TEAM_3) ? 110 : 145)));
                flag.glow_size = 25;
                flag.glow_trail = 1;
        }
-       
+
        flag.effects |= EF_LOWPRECISION;
        if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; }
        if(autocvar_g_ctf_dynamiclights)
@@ -1056,22 +1067,22 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
                        case NUM_TEAM_4: flag.effects |= EF_RED; break;
                }
        }
-       
+
        // flag placement
        if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
-       {       
-               flag.dropped_origin = flag.origin; 
+       {
+               flag.dropped_origin = flag.origin;
                flag.noalign = TRUE;
                flag.movetype = MOVETYPE_NONE;
        }
        else // drop to floor, automatically find a platform and set that as spawn origin
-       { 
+       {
                flag.noalign = FALSE;
                self = flag;
                droptofloor();
-               flag.movetype = MOVETYPE_TOSS; 
-       }       
-       
+               flag.movetype = MOVETYPE_TOSS;
+       }
+
        InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION);
 }
 
@@ -1131,7 +1142,7 @@ entity havocbot_ctf_find_enemy_flag(entity bot)
 
 float havocbot_ctf_teamcount(entity bot, vector org, float tc_radius)
 {
-       if not(teamplay)
+       if (!teamplay)
                return 0;
 
        float c = 0;
@@ -1173,7 +1184,7 @@ void havocbot_goalrating_ctf_ourbase(float ratingscale)
                        break;
                head = head.ctf_worldflagnext;
        }
-       if not(head)
+       if (!head)
                return;
 
        navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
@@ -1195,7 +1206,7 @@ void havocbot_goalrating_ctf_enemyflag(float ratingscale)
 
 void havocbot_goalrating_ctf_enemybase(float ratingscale)
 {
-       if not(bot_waypoints_for_items)
+       if (!bot_waypoints_for_items)
        {
                havocbot_goalrating_ctf_enemyflag(ratingscale);
                return;
@@ -1205,7 +1216,7 @@ void havocbot_goalrating_ctf_enemybase(float ratingscale)
 
        head = havocbot_ctf_find_enemy_flag(self);
 
-       if not(head)
+       if (!head)
                return;
 
        navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
@@ -1740,9 +1751,8 @@ void havocbot_role_ctf_setrole(entity bot, float role)
 MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
 {
        entity flag;
-       
        float t = 0, t2 = 0, t3 = 0;
-       
+
        // initially clear items so they can be set as necessary later.
        self.items &= ~(IT_RED_FLAG_CARRYING    | IT_RED_FLAG_TAKEN     | IT_RED_FLAG_LOST 
                                  | IT_BLUE_FLAG_CARRYING       | IT_BLUE_FLAG_TAKEN    | IT_BLUE_FLAG_LOST
@@ -1750,14 +1760,14 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
                                  | IT_PINK_FLAG_CARRYING       | IT_PINK_FLAG_TAKEN    | IT_PINK_FLAG_LOST
                                  | IT_CTF_SHIELDED);
 
-       // scan through all the flags and notify the client about them 
+       // scan through all the flags and notify the client about them
        for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
        {
                if(flag.team == NUM_TEAM_1) { t = IT_RED_FLAG_CARRYING;         t2 = IT_RED_FLAG_TAKEN;         t3 = IT_RED_FLAG_LOST; }
                if(flag.team == NUM_TEAM_2) { t = IT_BLUE_FLAG_CARRYING;        t2 = IT_BLUE_FLAG_TAKEN;        t3 = IT_BLUE_FLAG_LOST; }
                if(flag.team == NUM_TEAM_3) { t = IT_YELLOW_FLAG_CARRYING;      t2 = IT_YELLOW_FLAG_TAKEN;      t3 = IT_YELLOW_FLAG_LOST; }
                if(flag.team == NUM_TEAM_4) { t = IT_PINK_FLAG_CARRYING;        t2 = IT_PINK_FLAG_TAKEN;        t3 = IT_PINK_FLAG_LOST; }
-       
+
                switch(flag.ctf_status)
                {
                        case FLAG_PASSING:
@@ -1765,7 +1775,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
                        {
                                if((flag.owner == self) || (flag.pass_sender == self))
                                        self.items |= t; // carrying: self is currently carrying the flag
-                               else 
+                               else
                                        self.items |= t2; // taken: someone else is carrying the flag
                                break;
                        }
@@ -1776,15 +1786,15 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
                        }
                }
        }
-       
+
        // item for stopping players from capturing the flag too often
        if(self.ctf_captureshielded)
                self.items |= IT_CTF_SHIELDED;
-       
+
        // update the health of the flag carrier waypointsprite
-       if(self.wps_flagcarrier) 
+       if(self.wps_flagcarrier)
                WaypointSprite_UpdateHealth(self.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON));
-       
+
        return FALSE;
 }
 
@@ -1823,10 +1833,10 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerDies)
                PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
                PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
        }
-                               
+
        if(frag_target.flagcarried)
                { ctf_Handle_Throw(frag_target, world, DROP_NORMAL); }
-               
+
        return FALSE;
 }
 
@@ -1839,23 +1849,23 @@ MUTATOR_HOOKFUNCTION(ctf_GiveFragsForKill)
 MUTATOR_HOOKFUNCTION(ctf_RemovePlayer)
 {
        entity flag; // temporary entity for the search method
-       
+
        if(self.flagcarried)
                { ctf_Handle_Throw(self, world, DROP_NORMAL); }
-       
+
        for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
        {
                if(flag.pass_sender == self) { flag.pass_sender = world; }
                if(flag.pass_target == self) { flag.pass_target = world; }
                if(flag.ctf_dropper == self) { flag.ctf_dropper = world; }
        }
-               
+
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(ctf_PortalTeleport)
 {
-       if(self.flagcarried) 
+       if(self.flagcarried)
        if(!autocvar_g_ctf_portalteleport)
                { ctf_Handle_Throw(self, world, DROP_NORMAL); }
 
@@ -1865,7 +1875,7 @@ MUTATOR_HOOKFUNCTION(ctf_PortalTeleport)
 MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
 {
        if(MUTATOR_RETURNVALUE || gameover) { return FALSE; }
-       
+
        entity player = self;
 
        if((time > player.throw_antispam) && (player.deadflag == DEAD_NO) && !player.speedrunning && (!player.vehicle || autocvar_g_ctf_allow_vehicle_touch))
@@ -1875,21 +1885,21 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                {
                        entity head, closest_target = world;
                        head = WarpZone_FindRadius(player.origin, autocvar_g_ctf_pass_radius, TRUE);
-                       
+
                        while(head) // find the closest acceptable target to pass to
                        {
                                if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
                                if(head != player && SAME_TEAM(head, player))
                                if(!head.speedrunning && !head.vehicle)
                                {
-                                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc) 
+                                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
                                        vector head_center = WarpZone_UnTransformOrigin(head, CENTER_OR_VIEWOFS(head));
                                        vector passer_center = CENTER_OR_VIEWOFS(player);
-                                       
+
                                        if(ctf_CheckPassDirection(head_center, passer_center, player.v_angle, head.WarpZone_findradius_nearest))
                                        {
-                                               if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried) 
-                                               { 
+                                               if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried)
+                                               {
                                                        if(IS_BOT_CLIENT(head))
                                                        {
                                                                Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
@@ -1900,8 +1910,8 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                                                                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; 
+                                                       player.throw_antispam = time + autocvar_g_ctf_pass_wait;
+                                                       return TRUE;
                                                }
                                                else if(player.flagcarried)
                                                {
@@ -1917,10 +1927,10 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                                }
                                head = head.chain;
                        }
-                       
+
                        if(closest_target) { ctf_Handle_Throw(player, closest_target, DROP_PASS); return TRUE; }
                }
-               
+
                // throw the flag in front of you
                if(autocvar_g_ctf_throw && player.flagcarried)
                {
@@ -1944,14 +1954,14 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
                                if(time > player.throw_prevtime + autocvar_g_ctf_throw_punish_time) { player.throw_count = 1; }
                                else { player.throw_count += 1; }
                                if(player.throw_count >= autocvar_g_ctf_throw_punish_count) { player.throw_count = -1; }
-                                       
+
                                player.throw_prevtime = time;
                                ctf_Handle_Throw(player, world, DROP_THROW);
                                return TRUE;
                        }
                }
        }
-               
+
        return FALSE;
 }
 
@@ -1961,7 +1971,7 @@ MUTATOR_HOOKFUNCTION(ctf_HelpMePing)
        {
                self.wps_helpme_time = time;
                WaypointSprite_HelpMePing(self.wps_flagcarrier);
-       } 
+       }
        else // create a normal help me waypointsprite
        {
                WaypointSprite_Spawn("helpme", waypointsprite_deployed_lifetime, waypointsprite_limitedrange, self, FLAG_WAYPOINT_OFFSET, world, self.team, self, wps_helpme, FALSE, RADARICON_HELPME, '1 0.5 0');
@@ -1980,15 +1990,15 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleEnter)
                        ctf_Handle_Throw(vh_player, world, DROP_NORMAL);
                }
                else
-               {            
-                       setattachment(vh_player.flagcarried, vh_vehicle, ""); 
+               {
+                       setattachment(vh_player.flagcarried, vh_vehicle, "");
                        setorigin(vh_player.flagcarried, VEHICLE_FLAG_OFFSET);
                        vh_player.flagcarried.scale = VEHICLE_FLAG_SCALE;
-                       //vh_player.flagcarried.angles = '0 0 0';       
+                       //vh_player.flagcarried.angles = '0 0 0';
                }
                return TRUE;
        }
-               
+
        return FALSE;
 }
 
@@ -1996,7 +2006,7 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleExit)
 {
        if(vh_player.flagcarried)
        {
-               setattachment(vh_player.flagcarried, vh_player, ""); 
+               setattachment(vh_player.flagcarried, vh_player, "");
                setorigin(vh_player.flagcarried, FLAG_CARRY_OFFSET);
                vh_player.flagcarried.scale = FLAG_SCALE;
                vh_player.flagcarried.angles = '0 0 0';
@@ -2014,14 +2024,14 @@ MUTATOR_HOOKFUNCTION(ctf_AbortSpeedrun)
                ctf_RespawnFlag(self.flagcarried);
                return TRUE;
        }
-       
+
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(ctf_MatchEnd)
 {
        entity flag; // temporary entity for the search method
-       
+
        for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
        {
                switch(flag.ctf_status)
@@ -2034,11 +2044,11 @@ MUTATOR_HOOKFUNCTION(ctf_MatchEnd)
                                flag.takedamage = DAMAGE_NO;
                                flag.solid = SOLID_NOT;
                                flag.nextthink = FALSE; // stop thinking
-                               
+
                                //dprint("stopping the ", flag.netname, " from moving.\n");
                                break;
                        }
-                       
+
                        default:
                        case FLAG_BASE:
                        case FLAG_CARRY:
@@ -2048,7 +2058,7 @@ MUTATOR_HOOKFUNCTION(ctf_MatchEnd)
                        }
                }
        }
-       
+
        return FALSE;
 }
 
@@ -2074,7 +2084,7 @@ Keys: "angle" viewing angle when spawning. */
 void spawnfunc_info_player_team1()
 {
        if(g_assault) { remove(self); return; }
-       
+
        self.team = NUM_TEAM_1; // red
        spawnfunc_info_player_deathmatch();
 }
@@ -2086,7 +2096,7 @@ Keys: "angle" viewing angle when spawning. */
 void spawnfunc_info_player_team2()
 {
        if(g_assault) { remove(self); return; }
-       
+
        self.team = NUM_TEAM_2; // blue
        spawnfunc_info_player_deathmatch();
 }
@@ -2097,7 +2107,7 @@ Keys: "angle" viewing angle when spawning. */
 void spawnfunc_info_player_team3()
 {
        if(g_assault) { remove(self); return; }
-       
+
        self.team = NUM_TEAM_3; // yellow
        spawnfunc_info_player_deathmatch();
 }
@@ -2109,20 +2119,20 @@ Keys: "angle" viewing angle when spawning. */
 void spawnfunc_info_player_team4()
 {
        if(g_assault) { remove(self); return; }
-       
+
        self.team = NUM_TEAM_4; // purple
        spawnfunc_info_player_deathmatch();
 }
 
 /*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
 CTF flag for team one (Red).
-Keys: 
-"angle" Angle the flag will point (minus 90 degrees)... 
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
 "model" model to use, note this needs red and blue as skins 0 and 1...
 "noise" sound played when flag is picked up...
 "noise1" sound played when flag is returned by a teammate...
 "noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself... 
+"noise3" sound played when flag is lost in the field and respawns itself...
 "noise4" sound played when flag is dropped by a player...
 "noise5" sound played when flag touches the ground... */
 void spawnfunc_item_flag_team1()
@@ -2134,13 +2144,13 @@ void spawnfunc_item_flag_team1()
 
 /*QUAKED spawnfunc_item_flag_team2 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
 CTF flag for team two (Blue).
-Keys: 
-"angle" Angle the flag will point (minus 90 degrees)... 
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
 "model" model to use, note this needs red and blue as skins 0 and 1...
 "noise" sound played when flag is picked up...
 "noise1" sound played when flag is returned by a teammate...
 "noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself... 
+"noise3" sound played when flag is lost in the field and respawns itself...
 "noise4" sound played when flag is dropped by a player...
 "noise5" sound played when flag touches the ground... */
 void spawnfunc_item_flag_team2()
@@ -2195,7 +2205,7 @@ Keys:
 void spawnfunc_ctf_team()
 {
        if(!g_ctf) { remove(self); return; }
-       
+
        self.classname = "ctf_team";
        self.team = self.cnt + 1;
 }
@@ -2246,14 +2256,14 @@ void ctf_SpawnTeam (string teamname, float teamcolor)
 void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
 {
        ctf_teams = 2;
-       
+
        entity tmp_entity;
        for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
        {
                if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
                if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
        }
-       
+
        ctf_teams = bound(2, ctf_teams, 4);
 
        // if no teams are found, spawn defaults
@@ -2267,7 +2277,7 @@ void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to
                if(ctf_teams >= 4)
                        ctf_SpawnTeam("Pink", NUM_TEAM_4 - 1);
        }
-       
+
        ctf_ScoreRules(ctf_teams);
 }
 
@@ -2278,7 +2288,7 @@ void ctf_Initialize()
        ctf_captureshield_min_negscore = autocvar_g_ctf_shield_min_negscore;
        ctf_captureshield_max_ratio = autocvar_g_ctf_shield_max_ratio;
        ctf_captureshield_force = autocvar_g_ctf_shield_force;
-       
+
        InitializeEntity(world, ctf_DelayedInit, INITPRIO_GAMETYPE);
 }
 
@@ -2300,7 +2310,7 @@ MUTATOR_DEFINITION(gamemode_ctf)
        MUTATOR_HOOK(AbortSpeedrun, ctf_AbortSpeedrun, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRule, ctf_BotRoles, CBC_ORDER_ANY);
        MUTATOR_HOOK(GetTeamCount, ctf_GetTeamCount, CBC_ORDER_ANY);
-       
+
        MUTATOR_ONADD
        {
                if(time > 1) // game loads at time 1