]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Separated handicap into give and take variables
authorDr. Jaska <drjaska83@gmail.com>
Thu, 13 Jun 2024 22:50:50 +0000 (22:50 +0000)
committerDr. Jaska <drjaska83@gmail.com>
Thu, 13 Jun 2024 22:50:50 +0000 (22:50 +0000)
qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qc
qcsrc/common/replicate.qh
qcsrc/server/client.qh
qcsrc/server/handicap.qc
qcsrc/server/handicap.qh
qcsrc/server/player.qc
xonotic-client.cfg

index 237d14a6e72a38a328663562645aebfbde9b8493..4796830d4823d6d2a9f1f29522e1105bb4393a14 100644 (file)
@@ -58,7 +58,8 @@ void DynamicHandicap_UpdateHandicap()
                        handicap = 1 / (fabs(handicap) + 1);
                }
                handicap = DynamicHandicap_ClampHandicap(handicap);
-               Handicap_SetForcedHandicap(it, handicap);
+               Handicap_SetForcedHandicap(it, handicap, false);
+               Handicap_SetForcedHandicap(it, handicap, true);
        });
 }
 
index 6115223b486b3e61382fc9fb2f1a709e4d7448d4..6c66771f8aab4a812e50b9030385a3d688c19651 100644 (file)
@@ -1,18 +1,24 @@
 #pragma once
 
+// TODO: Remove cvar_cl_handicap vector after 0.9 release
+
 #ifdef GAMEQC
 REPLICATE_INIT(bool, cvar_cl_autoswitch);
 REPLICATE_INIT(int, cvar_cl_autoscreenshot);
 REPLICATE_INIT(bool, cvar_cl_clippedspectating);
 REPLICATE_INIT(bool, cvar_cl_cts_noautoswitch);
-REPLICATE_INIT(float, cvar_cl_handicap);
+REPLICATE_INIT(vector, cvar_cl_handicap);
+REPLICATE_INIT(float, cvar_cl_handicap_damage_given);
+REPLICATE_INIT(float, cvar_cl_handicap_damage_taken);
 REPLICATE_INIT(bool, cvar_cl_noantilag);
 REPLICATE_INIT(string, cvar_g_xonoticversion);
 REPLICATE(cvar_cl_autoswitch, bool, "cl_autoswitch");
 REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
 REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating");
 REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch");
-REPLICATE(cvar_cl_handicap, float, "cl_handicap");
+REPLICATE(cvar_cl_handicap, vector, "cl_handicap");
+REPLICATE(cvar_cl_handicap_damage_given, float, "cl_handicap_damage_given");
+REPLICATE(cvar_cl_handicap_damage_taken, float, "cl_handicap_damage_taken");
 REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag");
 REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion");
 #endif
index 9611df4e87980f2fb639198e7f94fd1cae7f70ca..5e9f17ff697ef98c50cd285c729f04058e3c262f 100644 (file)
@@ -204,7 +204,8 @@ CLASS(Client, Object)
     ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type);
     ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate);
     ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign);
-    ATTRIB(Client, cvar_cl_handicap, float, this.cvar_cl_handicap);
+    ATTRIB(Client, cvar_cl_handicap_damage_given, float, this.cvar_cl_handicap_damage_given);
+    ATTRIB(Client, cvar_cl_handicap_damage_taken, float, this.cvar_cl_handicap_damage_taken);
     ATTRIB(Client, cvar_cl_clippedspectating, bool, this.cvar_cl_clippedspectating);
     ATTRIB(Client, cvar_cl_autoscreenshot, int, this.cvar_cl_autoscreenshot);
     ATTRIB(Client, cvar_cl_jetpack_jump, bool, this.cvar_cl_jetpack_jump);
index ce0d6cd0a6c10f3fe0653d33da3ed700b0d95fb2..5c03cd11b9965ca52ac644a732d47735f0b4d1d8 100644 (file)
@@ -8,34 +8,83 @@
 #include <common/state.qh>
 #include <server/client.qh>
 
-.float m_handicap; ///< Holds the handicap value.
+.float m_handicap_give; ///< Holds the forced handicap value.
+.float m_handicap_take; ///< Holds the forced handicap value.
 
 void Handicap_Initialize(entity player)
 {
-       CS(player).m_handicap = 1;
+       // forced handicap defaults
+       CS(player).m_handicap_give = 1;
+       CS(player).m_handicap_take = 1;
 }
 
-float Handicap_GetVoluntaryHandicap(entity player)
+float Handicap_GetVoluntaryHandicap(entity player, bool receiving)
 {
-       return bound(1.0, CS_CVAR(player).cvar_cl_handicap, 10.0);
+#if 0
+       if (receiving)
+               return bound(1.0, CS_CVAR(player).cvar_cl_handicap_damage_taken, 10.0);
+       else
+               return bound(1.0, CS_CVAR(player).cvar_cl_handicap_damage_given, 10.0);
+#else
+       // TODO: remove the else vector branch after 0.9 release
+       // Forwards compatibility for old clients on new servers. `cl_handicap 2`
+       // ( '2 0 0' ) is treated the same as `cl_handicap_damage_{given,taken} 2`.
+       // The x is give and y is take.
+       // '2 0 0' gives and takes x2
+       // '2 2 0' gives and takes x2
+       // '2 1 0' only gives x2
+       // '1 2 0' only takes x2
+       // z is wasted
+
+       int handicap_value;
+
+       // First read if the new cvars have a valid value,
+       // if they don't then read old cvar, checking if the old cvar has
+       // separate give and take values or we should use the first value for both
+       if (receiving)
+       {
+               if (CS_CVAR(player).cvar_cl_handicap_damage_taken > 1)
+                       handicap_value = CS_CVAR(player).cvar_cl_handicap_damage_taken;
+               else if (CS_CVAR(player).cvar_cl_handicap.y > 0)
+                       handicap_value = CS_CVAR(player).cvar_cl_handicap.y;
+               else
+                       handicap_value = CS_CVAR(player).cvar_cl_handicap.x;
+       }
+       else
+       {
+               if (CS_CVAR(player).cvar_cl_handicap_damage_given > 1)
+                       handicap_value = CS_CVAR(player).cvar_cl_handicap_damage_given;
+               else
+                       handicap_value = CS_CVAR(player).cvar_cl_handicap.x;
+       }
+
+       return bound(1.0, handicap_value, 10.0);
+#endif
+
 }
 
-float Handicap_GetForcedHandicap(entity player)
+float Handicap_GetForcedHandicap(entity player, bool receiving)
 {
-       return (CS(player)) ? CS(player).m_handicap : 1;
+       if (receiving)
+               return (CS(player)) ? CS(player).m_handicap_take : 1;
+       else
+               return (CS(player)) ? CS(player).m_handicap_give : 1;
+
 }
 
-void Handicap_SetForcedHandicap(entity player, float value)
+void Handicap_SetForcedHandicap(entity player, float value, bool receiving)
 {
        if (value <= 0)
-       {
                error("Handicap_SetForcedHandicap: Invalid handicap value.");
-       }
-       CS(player).m_handicap = value;
+
+       if (receiving)
+               CS(player).m_handicap_take = value;
+       else
+               CS(player).m_handicap_give = value;
 }
 
-float Handicap_GetTotalHandicap(entity player)
+float Handicap_GetTotalHandicap(entity player, bool receiving)
 {
-       return Handicap_GetForcedHandicap(player) * Handicap_GetVoluntaryHandicap(
-               player);
+       return Handicap_GetForcedHandicap(player, receiving) *
+               Handicap_GetVoluntaryHandicap(player, receiving);
 }
index fa45a0ed01edb61227d913cbb49822fee25bf2bf..48129ed5cfddefd2d1d8fa19dd8a341383d00ea9 100644 (file)
@@ -9,9 +9,12 @@
 // weak players. Values greater than 1 make the game harder and values less than
 // 1 make the game easier. Right now handicap only affects damage. There are 2
 // types of handicap: voluntary and forced. Voluntary handicap can be set via
-// cl_handicap cvar. For obvious reasons, it can't be less than 1. Forced
+// cl_handicap cvars. For obvious reasons, it can't be less than 1. Forced
 // handicap can be set by server mutators. The total handicap is the product of
 // voluntary and forced handicap.
+// Both handicaps are separated into _take and _give so that mutators and
+// players are able to nerf their damage output or increase intake
+// without changing the other.
 
 /// \brief Initializes handicap to its default value.
 /// \param[in,out] player Player to initialize.
@@ -20,21 +23,25 @@ void Handicap_Initialize(entity player);
 
 /// \brief Returns the voluntary handicap of the player.
 /// \param[in] player Player to check.
+/// \param[in] receiving Whether handicap is for receiving or dealing.
 /// \return Voluntary handicap of the player.
-float Handicap_GetVoluntaryHandicap(entity player);
+float Handicap_GetVoluntaryHandicap(entity player, bool receiving);
 
 /// \brief Returns the forced handicap of the player.
 /// \param[in] player Player to check.
+/// \param[in] receiving Whether handicap is for receiving or dealing.
 /// \return Forced handicap of the player.
-float Handicap_GetForcedHandicap(entity player);
+float Handicap_GetForcedHandicap(entity player, bool receiving);
 
 /// \brief Sets the forced handicap of the player.
 /// \param[in] player Player to alter.
 /// \param[in] value Handicap value to set.
+/// \param[in] receiving Whether handicap is for receiving or dealing.
 /// \return No return.
-void Handicap_SetForcedHandicap(entity player, float value);
+void Handicap_SetForcedHandicap(entity player, float value, bool receiving);
 
 /// \brief Returns the total handicap of the player.
 /// \param[in] player Player to check.
+/// \param[in] receiving Whether handicap is for receiving or dealing.
 /// \return Total handicap of the player.
-float Handicap_GetTotalHandicap(entity player);
+float Handicap_GetTotalHandicap(entity player, bool receiving);
index 3ca1bbc1b1116c73c224f211d88f51074b720467..a9ae47eb1e6ddaddeca3dfcf83aaa7022ce4197f 100644 (file)
@@ -238,10 +238,10 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
        {
                if(!DEATH_ISSPECIAL(deathtype))
                {
-                       damage *= Handicap_GetTotalHandicap(this);
+                       damage *= Handicap_GetTotalHandicap(this, true);
                        if (this != attacker && IS_PLAYER(attacker))
                        {
-                               damage /= Handicap_GetTotalHandicap(attacker);
+                               damage /= Handicap_GetTotalHandicap(attacker, false);
                        }
                }
 
index 666a065385e84a3c3cc7101728c09c8f0923c832..cfd3e0747ae45e8bf2505289d0e33f6abfa55e82 100644 (file)
@@ -689,7 +689,11 @@ alias _gl_flashblend_update_01 "gl_flashblend 0"
 alias _gl_flashblend_update_11 "gl_flashblend 0"
 alias gl_flashblend_update "_gl_flashblend_update_$r_shadow_realtime_dlight$r_showsurfaces"
 
-set cl_handicap 1      "multiplies damage received and divides damage dealt"
+// TODO: remove cl_handicap cvar after 0.9 release
+set cl_handicap 1 "multiplies damage received and divides damage dealt"
+alias cl_handicap "cl_handicap_damage_given ${* ?} ; cl_handicap_damage_taken ${* ?} ; set cl_handicap ${* ?}"
+set cl_handicap_damage_given 1 "damage given is divided by this factor if > 1"
+set cl_handicap_damage_taken 1 "damage taken is multiplied by this factor if > 1"
 
 seta cl_clippedspectating 1 "movement collision for spectators so that you can't pass through walls and such"