]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator/gamemode_ctf.qc
While passing the flag to a team mate, don't return it immediately if an enemy interc...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator / gamemode_ctf.qc
index 8120e1cb348a77e35e545eaa2c78733f41a2ea02..4db911362ecfe0b6b31cbb73dee668b339c492d5 100644 (file)
@@ -155,6 +155,16 @@ void ctf_CaptureRecord(entity flag, entity player)
        }
 }
 
+bool ctf_Immediate_Return_Allowed(entity flag, entity toucher)
+{
+       int num_perteam = 0;
+       FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(toucher, it), { ++num_perteam; });
+
+       // automatically return if there's only 1 player on the team
+       return ((autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried))
+               && flag.team);
+}
+
 bool ctf_Return_Customize(entity this, entity client)
 {
        // only to the carrier
@@ -871,9 +881,7 @@ void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage
        if(ITEM_DAMAGE_NEEDKILL(deathtype))
        {
                if(autocvar_g_ctf_flag_return_damage_delay)
-               {
-                       this.ctf_flagdamaged = true;
-               }
+                       this.ctf_flagdamaged_byworld = true;
                else
                {
                        this.health = 0;
@@ -906,17 +914,7 @@ void ctf_FlagThink(entity this)
                LOG_TRACE("wtf the flag got squashed?");
                tracebox(this.origin, CTF_FLAG.m_mins, CTF_FLAG.m_maxs, this.origin, MOVE_NOMONSTERS, this);
                if(!trace_startsolid || this.noalign) // can we resize it without getting stuck?
-                       setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs); }
-
-       switch(this.ctf_status) // reset flag angles in case warpzones adjust it
-       {
-               case FLAG_DROPPED:
-               {
-                       this.angles = '0 0 0';
-                       break;
-               }
-
-               default: break;
+                       setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs);
        }
 
        // main think method
@@ -937,6 +935,8 @@ void ctf_FlagThink(entity this)
 
                case FLAG_DROPPED:
                {
+                       this.angles = '0 0 0'; // reset flag angles in case warpzones adjust it
+
                        if(autocvar_g_ctf_flag_dropped_floatinwater)
                        {
                                vector midpoint = ((this.absmin + this.absmax) * 0.5);
@@ -960,7 +960,7 @@ void ctf_FlagThink(entity this)
                                        return;
                                }
                        }
-                       if(this.ctf_flagdamaged)
+                       if(this.ctf_flagdamaged_byworld)
                        {
                                this.health -= ((this.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
                                ctf_CheckFlagReturn(this, RETURN_NEEDKILL);
@@ -1051,12 +1051,9 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        flag.health = 0;
                        ctf_CheckFlagReturn(flag, RETURN_NEEDKILL);
                }
-               if(!flag.ctf_flagdamaged) { return; }
+               if(!flag.ctf_flagdamaged_byworld) { return; }
        }
 
-       int num_perteam = 0;
-       FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(toucher, it), LAMBDA(++num_perteam));
-
        // special touch behaviors
        if(STAT(FROZEN, toucher)) { return; }
        else if(IS_VEHICLE(toucher))
@@ -1108,7 +1105,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
 
                case FLAG_DROPPED:
                {
-                       if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried)) && flag.team) // automatically return if there's only 1 player on the team
+                       if(CTF_SAMETEAM(toucher, flag) && ctf_Immediate_Return_Allowed(flag, toucher))
                                ctf_Handle_Return(flag, toucher); // toucher just returned his own flag
                        else if(is_not_monster && (!toucher.flagcarried) && ((toucher != flag.ctf_dropper) || (time > flag.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
                                ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
@@ -1126,7 +1123,12 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        if((IS_PLAYER(toucher)) && !IS_DEAD(toucher) && (toucher != flag.pass_sender))
                        {
                                if(DIFF_TEAM(toucher, flag.pass_sender))
-                                       ctf_Handle_Return(flag, toucher);
+                               {
+                                       if(ctf_Immediate_Return_Allowed(flag, toucher))
+                                               ctf_Handle_Return(flag, toucher);
+                                       else if(is_not_monster && (!toucher.flagcarried))
+                                               ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED);
+                               }
                                else
                                        ctf_Handle_Retrieve(flag, toucher);
                        }
@@ -1183,7 +1185,7 @@ void ctf_RespawnFlag(entity flag)
        flag.ctf_dropper = NULL;
        flag.ctf_pickuptime = 0;
        flag.ctf_droptime = 0;
-       flag.ctf_flagdamaged = 0;
+       flag.ctf_flagdamaged_byworld = false;
 
        ctf_CheckStalemate();
 }