]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_ctf.qc
Fix balancing with drop penalties; add assist points for previous carriers
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_ctf.qc
index f705621712d01c4cdf93e380e8a366e1b3694f94..15e62c5b7e9f51a845859ecbd8d361ffa424116b 100644 (file)
@@ -3,14 +3,6 @@
 //  Last updated: March 30th, 2012
 // ================================================================
 
-float ctf_ReadScore(string parameter) // make this obsolete
-{
-       //if(g_ctf_win_mode != 2)
-               return cvar(strcat("g_ctf_personal", parameter));
-       //else
-       //      return cvar(strcat("g_ctf_flag", parameter));
-}
-
 void ctf_FakeTimeLimit(entity e, float t)
 {
        msg_entity = e;
@@ -184,7 +176,7 @@ void ctf_Handle_Drop(entity flag, entity player, float droptype)
        ctf_EventLog("dropped", player.team, player);
 
        // scoring
-       PlayerTeamScore_AddScore(player, -ctf_ReadScore("penalty_drop"));       
+       PlayerTeamScore_AddScore(player, -autocvar_g_ctf_score_penalty_drop);   
        PlayerScore_Add(player, SP_CTF_DROPS, 1);
        
        // waypoints
@@ -212,7 +204,6 @@ void ctf_Handle_Retrieve(entity flag, entity player)
        entity sender = flag.pass_sender;
        
        // transfer flag to player
-       flag.ctf_carrier = player;
        flag.owner = player;
        flag.owner.flagcarried = flag;
        
@@ -273,7 +264,8 @@ void ctf_Handle_Throw(entity player, entity reciever, float droptype)
        {
                case DROP_PASS:
                {
-                       targ_origin = WarpZone_UnTransformOrigin(reciever, (0.5 * (reciever.absmin + reciever.absmax)));
+                       WarpZone_RefSys_MakeSameRefSys(flag, player);
+                       targ_origin = WarpZone_RefSys_TransformOrigin(reciever, flag, (0.5 * (reciever.absmin + reciever.absmax)));
                        flag.velocity = (normalize(targ_origin - player.origin) * autocvar_g_ctf_pass_velocity);
                        break;
                }
@@ -352,6 +344,7 @@ 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
        
@@ -367,9 +360,14 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
        }
        
        // scoring
-       PlayerTeamScore_AddScore(player, ctf_ReadScore("score_capture"));
+       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_capture);
        PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
 
+       old_time = PlayerScore_Add(player, SP_CTF_CAPTIME, 0);
+       new_time = TIME_ENCODE(time - enemy_flag.ctf_pickuptime);
+       if(!old_time || new_time < old_time)
+               PlayerScore_Add(player, SP_CTF_CAPTIME, new_time - old_time);
+
        // effects
        if(autocvar_g_ctf_flag_capture_effects) 
        {
@@ -382,6 +380,7 @@ 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) { PlayerTeamScore_AddScore(enemy_flag.ctf_dropper, autocvar_g_ctf_score_capture_assist); }
        }
        
        // reset the flag
@@ -398,14 +397,14 @@ void ctf_Handle_Return(entity flag, entity player)
        ctf_EventLog("return", flag.team, player);
 
        // scoring
-       PlayerTeamScore_AddScore(player, ctf_ReadScore("score_return")); // reward for return
+       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_return); // reward for return
        PlayerScore_Add(player, SP_CTF_RETURNS, 1); // add to count of returns
 
-       TeamScore_AddToTeam(flag.team, ST_SCORE, -ctf_ReadScore("penalty_returned")); // punish the team who was last carrying it
+       TeamScore_AddToTeam(flag.team, ST_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the team who was last carrying it
        
        if(flag.ctf_dropper) 
        {
-               PlayerScore_Add(flag.ctf_dropper, SP_SCORE, -ctf_ReadScore("penalty_returned")); // punish the player who dropped the flag
+               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 
                flag.ctf_dropper.next_take_time = time + autocvar_g_ctf_flag_collect_delay; // set next take time
        }
@@ -470,14 +469,14 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        {               
                case PICKUP_BASE:
                {
-                       PlayerTeamScore_AddScore(player, ctf_ReadScore("score_pickup_base"));
+                       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_pickup_base);
                        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);
-                       pickup_dropped_score = floor((ctf_ReadScore("score_pickup_dropped_late") * (1 - pickup_dropped_score) + ctf_ReadScore("score_pickup_dropped_early") * pickup_dropped_score) + 0.5);
+                       pickup_dropped_score = floor((autocvar_g_ctf_score_pickup_dropped_late * (1 - pickup_dropped_score) + autocvar_g_ctf_score_pickup_dropped_early * pickup_dropped_score) + 0.5);
                        print("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n");
                        PlayerTeamScore_AddScore(player, pickup_dropped_score);
                        break;
@@ -711,7 +710,7 @@ void ctf_FlagThink()
                {
                        vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
                        vector old_targ_origin = targ_origin;
-                       targ_origin = WarpZone_UnTransformOrigin(self.pass_target, targ_origin);
+                       targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin);
                        WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
 
                        print(strcat("self: ", vtos(self.origin), ", old: ", vtos(old_targ_origin), " (", ftos(vlen(self.origin - old_targ_origin)), "qu)"), ", transformed: ", vtos(targ_origin), " (", ftos(vlen(self.origin - targ_origin)), "qu)", ".\n");
@@ -997,9 +996,10 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
        {
                switch(flag.ctf_status)
                {
+                       case FLAG_PASSING:
                        case FLAG_CARRY:
                        {
-                               if(flag.owner == self)
+                               if((flag.owner == self) || (flag.pass_sender == self))
                                        self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_CARRYING : IT_BLUE_FLAG_CARRYING); // carrying: self is currently carrying the flag
                                else 
                                        self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_TAKEN : IT_BLUE_FLAG_TAKEN); // taken: someone on self's team is carrying the flag
@@ -1041,8 +1041,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerDamage) // for changing damage and force values t
        }
        else if(frag_target.flagcarried && (frag_target.deadflag == DEAD_NO) && IsDifferentTeam(frag_target, frag_attacker)) // if the target is a flagcarrier
        {
-               // healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent)
-               if(autocvar_g_ctf_flagcarrier_auto_helpme_when_damaged > frag_target.health)
+               if(autocvar_g_ctf_flagcarrier_auto_helpme_when_damaged > ('1 0 0' * healtharmor_maxdamage(frag_target.health, frag_target.armorvalue, autocvar_g_balance_armor_blockpercent)))
                        WaypointSprite_HelpMePing(frag_target.wps_flagcarrier); // TODO: only do this if there is a significant loss of health?
        }
        return 0;
@@ -1052,7 +1051,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerDies)
 {
        if((frag_attacker != frag_target) && (frag_attacker.classname == "player") && (frag_target.flagcarried))
        {
-               PlayerTeamScore_AddScore(frag_attacker, ctf_ReadScore("score_kill"));
+               PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
                PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
        }