1 #include "sv_dynamic_handicap.qh"
3 /// \brief Source file that contains implementation of the Dynamic handicap
6 /// \copyright GNU GPLv2 or any later version.
8 //======================= Global variables ====================================
10 int autocvar_g_dynamic_handicap; ///< Whether to enable dynamic handicap.
11 /// \brief The scale of the handicap. Larget values mean more penalties for
12 /// strong players and more buffs for weak players.
13 float autocvar_g_dynamic_handicap_scale;
14 float autocvar_g_dynamic_handicap_min; ///< The minimum value of the handicap.
15 float autocvar_g_dynamic_handicap_max; ///< The maximum value of the handicap.
17 //====================== Forward declarations =================================
19 /// \brief Returns the base value of the handicap.
20 /// \param[in] player Player to evaluate.
21 /// \return Base handicap value.
22 float DynamicHandicap_GetBaseValue(entity player);
24 /// \brief Scales the base value of the handicap.
25 /// \param[in] handicap Value to scale.
26 /// \return Scaled value.
27 float DynamicHandicap_ScaleHandicap(float handicap);
29 /// \brief Clamps the value of the handicap.
30 /// \param[in] handicap Value to clamp.
31 /// \return Clamped value.
32 float DynamicHandicap_ClampHandicap(float handicap);
34 //========================= Free functions ====================================
36 /// \brief Updates the handicap of a given player.
37 /// \param[in,out] player Player to update.
38 /// \return No return.
39 void DynamicHandicap_UpdateHandicap(entity player)
41 float handicap = DynamicHandicap_GetBaseValue(player);
42 handicap = DynamicHandicap_ScaleHandicap(handicap);
43 handicap = DynamicHandicap_ClampHandicap(handicap);
44 Handicap_SetForcedHandicap(player, handicap);
47 float DynamicHandicap_GetBaseValue(entity player)
49 int kills = PlayerScore_Get(player, SP_KILLS);
50 int deaths = PlayerScore_Get(player, SP_DEATHS);
63 return kills / deaths;
66 float DynamicHandicap_ScaleHandicap(float handicap)
72 if (autocvar_g_dynamic_handicap_scale == 1)
79 handicap *= autocvar_g_dynamic_handicap_scale;
84 handicap = 1 / handicap;
86 handicap *= autocvar_g_dynamic_handicap_scale;
93 float DynamicHandicap_ClampHandicap(float handicap)
95 if ((autocvar_g_dynamic_handicap_min >= 0) && (handicap <
96 autocvar_g_dynamic_handicap_min))
98 handicap = autocvar_g_dynamic_handicap_min;
100 if ((autocvar_g_dynamic_handicap_max > 0) && (handicap >
101 autocvar_g_dynamic_handicap_max))
103 handicap = autocvar_g_dynamic_handicap_max;
108 //============================= Hooks ========================================
110 REGISTER_MUTATOR(dynamic_handicap, autocvar_g_dynamic_handicap);
112 MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsString)
114 M_ARGV(0, string) = strcat(M_ARGV(0, string), ":handicap");
117 MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsPrettyString)
119 M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Dynamic handicap");
122 /// \brief Hook that is called when player connects to the server.
123 MUTATOR_HOOKFUNCTION(dynamic_handicap, ClientConnect)
125 entity player = M_ARGV(0, entity);
126 DynamicHandicap_UpdateHandicap(player);
129 /// \brief Hook that is called when player dies.
130 MUTATOR_HOOKFUNCTION(dynamic_handicap, PlayerDies)
132 entity attacker = M_ARGV(1, entity);
133 entity victim = M_ARGV(2, entity);
134 DynamicHandicap_UpdateHandicap(victim);
135 if (!IS_CLIENT(attacker))
139 DynamicHandicap_UpdateHandicap(attacker);