]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc
Add a mutator hook to append special item codes to the death log
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / ctf / sv_ctf.qc
index 536e7cd77ca63b19177095f2f1c4e9dd162fbd7b..939c70e29ea858597260439a21ea3db98c19f78c 100644 (file)
@@ -144,8 +144,8 @@ bool ctf_Return_Customize(entity this, entity client)
 void ctf_FlagcarrierWaypoints(entity player)
 {
        WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, NULL, player.team, player, wps_flagcarrier, true, RADARICON_FLAG);
-       WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2);
-       WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(GetResourceAmount(player, RESOURCE_HEALTH), GetResourceAmount(player, RESOURCE_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
+       WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, 2 * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x);
+       WaypointSprite_UpdateHealth(player.wps_flagcarrier, healtharmor_maxdamage(GetResource(player, RES_HEALTH), GetResource(player, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x);
        WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team));
 
        if(player.flagcarried && CTF_SAMETEAM(player, player.flagcarried))
@@ -186,7 +186,7 @@ void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnra
                {
                        //print("normal arc line failed, trying to find new pos...");
                        WarpZone_TraceLine(to, targpos, MOVE_NOMONSTERS, flag);
-                       targpos = (trace_endpos + FLAG_PASS_ARC_OFFSET);
+                       targpos = (trace_endpos + eZ * FLAG_PASS_ARC_OFFSET_Z);
                        WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
                        if(trace_fraction < 1) { targpos = to; /* print(" ^1FAILURE^7, reverting to original direction.\n"); */ }
                        /*else { print(" ^3SUCCESS^7, using new arc line.\n"); } */
@@ -341,7 +341,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype)
        set_movetype(flag, MOVETYPE_TOSS);
        flag.takedamage = DAMAGE_YES;
        flag.angles = '0 0 0';
-       SetResourceAmountExplicit(flag, RESOURCE_HEALTH, flag.max_flag_health);
+       SetResourceExplicit(flag, RES_HEALTH, flag.max_health);
        flag.ctf_droptime = time;
        flag.ctf_dropper = player;
        flag.ctf_status = FLAG_DROPPED;
@@ -363,8 +363,8 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype)
 
        if(autocvar_g_ctf_flag_return_time || (autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health))
        {
-               WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_flag_health);
-               WaypointSprite_UpdateHealth(flag.wps_flagdropped, GetResourceAmount(flag, RESOURCE_HEALTH));
+               WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_health);
+               WaypointSprite_UpdateHealth(flag.wps_flagdropped, GetResource(flag, RES_HEALTH));
        }
 
        player.throw_antispam = time + autocvar_g_ctf_pass_wait;
@@ -679,7 +679,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
        switch(pickuptype)
        {
                case PICKUP_BASE: flag.ctf_pickuptime = time; break; // used for timing runs
-               case PICKUP_DROPPED: SetResourceAmountExplicit(flag, RESOURCE_HEALTH, flag.max_flag_health); break; // reset health/return timelimit
+               case PICKUP_DROPPED: SetResourceExplicit(flag, RES_HEALTH, flag.max_health); break; // reset health/return timelimit
                default: break;
        }
 
@@ -702,10 +702,12 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
        if(flag.team)
                FOREACH_CLIENT(IS_PLAYER(it) && it != player, {
                        if(CTF_SAMETEAM(flag, it))
-                       if(SAME_TEAM(player, it))
-                               Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname);
-                       else
-                               Send_Notification(NOTIF_ONE, it, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
+                       {
+                               if(SAME_TEAM(player, it))
+                                       Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname);
+                               else
+                                       Send_Notification(NOTIF_ONE, it, 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);
@@ -761,9 +763,9 @@ void ctf_CheckFlagReturn(entity flag, int returntype)
 {
        if((flag.ctf_status == FLAG_DROPPED) || (flag.ctf_status == FLAG_PASSING))
        {
-               if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped, GetResourceAmount(flag, RESOURCE_HEALTH)); }
+               if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped, GetResource(flag, RES_HEALTH)); }
 
-               if((GetResourceAmount(flag, RESOURCE_HEALTH) <= 0) || (time >= flag.ctf_droptime + autocvar_g_ctf_flag_return_time))
+               if((GetResource(flag, RES_HEALTH) <= 0) || (time >= flag.ctf_droptime + autocvar_g_ctf_flag_return_time))
                {
                        switch(returntype)
                        {
@@ -874,7 +876,7 @@ void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage
                        this.ctf_flagdamaged_byworld = true;
                else
                {
-                       SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0);
+                       SetResourceExplicit(this, RES_HEALTH, 0);
                        ctf_CheckFlagReturn(this, RETURN_NEEDKILL);
                }
                return;
@@ -882,7 +884,7 @@ void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage
        if(autocvar_g_ctf_flag_return_damage)
        {
                // reduce health and check if it should be returned
-               TakeResource(this, RESOURCE_HEALTH, damage);
+               TakeResource(this, RES_HEALTH, damage);
                ctf_CheckFlagReturn(this, RETURN_DAMAGE);
                return;
        }
@@ -934,7 +936,7 @@ void ctf_FlagThink(entity this)
                                {
                                        this.velocity = this.velocity * 0.5;
 
-                                       if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
+                                       if (pointcontents(midpoint + eZ * FLAG_FLOAT_OFFSET_Z) == CONTENT_WATER)
                                                { this.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
                                        else
                                                { set_movetype(this, MOVETYPE_FLY); }
@@ -945,20 +947,20 @@ void ctf_FlagThink(entity this)
                        {
                                if((vdist(this.origin - this.ctf_spawnorigin, <=, autocvar_g_ctf_flag_return_dropped)) || (autocvar_g_ctf_flag_return_dropped == -1))
                                {
-                                       SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0);
+                                       SetResourceExplicit(this, RES_HEALTH, 0);
                                        ctf_CheckFlagReturn(this, RETURN_DROPPED);
                                        return;
                                }
                        }
                        if(this.ctf_flagdamaged_byworld)
                        {
-                               TakeResource(this, RESOURCE_HEALTH, ((this.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE));
+                               TakeResource(this, RES_HEALTH, (this.max_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
                                ctf_CheckFlagReturn(this, RETURN_NEEDKILL);
                                return;
                        }
                        else if(autocvar_g_ctf_flag_return_time)
                        {
-                               TakeResource(this, RESOURCE_HEALTH, ((this.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE));
+                               TakeResource(this, RES_HEALTH, (this.max_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE);
                                ctf_CheckFlagReturn(this, RETURN_TIMEOUT);
                                return;
                        }
@@ -969,7 +971,7 @@ void ctf_FlagThink(entity this)
                {
                        if(this.speedrunning && ctf_captimerecord && (time >= this.ctf_pickuptime + ctf_captimerecord))
                        {
-                               SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0);
+                               SetResourceExplicit(this, RES_HEALTH, 0);
                                ctf_CheckFlagReturn(this, RETURN_SPEEDRUN);
 
                                CS(this.owner).impulse = CHIMPULSE_SPEEDRUN.impulse; // move the player back to the waypoint they set
@@ -1038,7 +1040,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
        {
                if(!autocvar_g_ctf_flag_return_damage_delay)
                {
-                       SetResourceAmountExplicit(flag, RESOURCE_HEALTH, 0);
+                       SetResourceExplicit(flag, RES_HEALTH, 0);
                        ctf_CheckFlagReturn(flag, RETURN_NEEDKILL);
                }
                if(!flag.ctf_flagdamaged_byworld) { return; }
@@ -1160,9 +1162,10 @@ void ctf_RespawnFlag(entity flag)
        setattachment(flag, NULL, "");
        setorigin(flag, flag.ctf_spawnorigin);
 
-       set_movetype(flag, ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS));
+       //set_movetype(flag, ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS)); // would be desired, except maps that want floating flags have it set to fall!
+       set_movetype(flag, MOVETYPE_NONE); // match the initial setup handling (flag doesn't move when spawned)
        flag.takedamage = DAMAGE_NO;
-       SetResourceAmountExplicit(flag, RESOURCE_HEALTH, flag.max_flag_health);
+       SetResourceExplicit(flag, RES_HEALTH, flag.max_health);
        flag.solid = SOLID_TRIGGER;
        flag.velocity = '0 0 0';
        flag.angles = flag.mangle;
@@ -1248,8 +1251,8 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        flag.solid = SOLID_TRIGGER;
        flag.takedamage = DAMAGE_NO;
        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);
-       SetResourceAmountExplicit(flag, RESOURCE_HEALTH, flag.max_flag_health);
+       flag.max_health = ((autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health) ? autocvar_g_ctf_flag_health : 100);
+       SetResourceExplicit(flag, RES_HEALTH, flag.max_health);
        flag.event_damage = ctf_FlagDamage;
        flag.pushable = true;
        flag.teleportable = TELEPORT_NORMAL;
@@ -1519,7 +1522,7 @@ void havocbot_goalrating_ctf_enemyflag(entity this, float ratingscale)
                {
                        // adjust rating of our flag carrier depending on his health
                        head = head.tag_entity;
-                       float f = bound(0, (head.health + head.armorvalue) / 100, 2) - 1;
+                       float f = bound(0, (GetResource(head, RES_HEALTH) + GetResource(head, RES_ARMOR)) / 100, 2) - 1;
                        ratingscale += ratingscale * f * 0.1;
                }
                navigation_routerating(this, head, ratingscale, 10000);
@@ -2166,7 +2169,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
 
        // update the health of the flag carrier waypointsprite
        if(player.wps_flagcarrier)
-               WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(GetResourceAmount(player, RESOURCE_HEALTH), GetResourceAmount(player, RESOURCE_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
+               WaypointSprite_UpdateHealth(player.wps_flagcarrier, healtharmor_maxdamage(GetResource(player, RES_HEALTH), GetResource(player, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x);
 }
 
 MUTATOR_HOOKFUNCTION(ctf, Damage_Calculate) // for changing damage and force values that are applied to players in g_damage.qc
@@ -2194,8 +2197,8 @@ MUTATOR_HOOKFUNCTION(ctf, Damage_Calculate) // for changing damage and force val
        }
        else if(frag_target.flagcarried && !IS_DEAD(frag_target) && CTF_DIFFTEAM(frag_target, frag_attacker)) // if the target is a flagcarrier
        {
-               if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > ('1 0 0' * healtharmor_maxdamage(GetResourceAmount(frag_target, RESOURCE_HEALTH), GetResourceAmount(frag_target, RESOURCE_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)))
-               if(time > frag_target.wps_helpme_time + autocvar_g_ctf_flagcarrier_auto_helpme_time)
+               if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > healtharmor_maxdamage(GetResource(frag_target, RES_HEALTH), GetResource(frag_target, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x
+                       && time > frag_target.wps_helpme_time + autocvar_g_ctf_flagcarrier_auto_helpme_time)
                {
                        frag_target.wps_helpme_time = time;
                        WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
@@ -2590,6 +2593,13 @@ MUTATOR_HOOKFUNCTION(ctf, DropSpecialItems)
                ctf_Handle_Throw(frag_target, NULL, DROP_THROW);
 }
 
+MUTATOR_HOOKFUNCTION(ctf, LogDeath_AppendItemCodes)
+{
+       entity player = M_ARGV(0, entity);
+       if(player.flagcarried)
+               M_ARGV(1, string) = strcat(M_ARGV(1, string), "F"); // item codes
+}
+
 
 // ==========
 // Spawnfuncs