2 /// \brief Source file that contains implementation of the Dynamic handicap
5 /// \copyright GNU GPLv2 or any later version.
7 //======================= Global variables ====================================
9 int autocvar_g_dynamic_handicap; ///< Whether to enable dynamic handicap.
10 /// \brief The scale of the handicap. Larget values mean more penalties for
11 /// strong players and more buffs for weak players.
12 float autocvar_g_dynamic_handicap_scale;
13 float autocvar_g_dynamic_handicap_min; ///< The minimum value of the handicap.
14 float autocvar_g_dynamic_handicap_max; ///< The maximum value of the handicap.
16 //====================== Forward declarations =================================
18 /// \brief Returns the base value of the handicap.
19 /// \param[in] player Player to evaluate.
20 /// \return Base handicap value.
21 float DynamicHandicap_GetBaseValue(entity player);
23 /// \brief Scales the base value of the handicap.
24 /// \param[in] handicap Value to scale.
25 /// \return Scaled value.
26 float DynamicHandicap_ScaleHandicap(float handicap);
28 /// \brief Clamps the value of the handicap.
29 /// \param[in] handicap Value to clamp.
30 /// \return Clamped value.
31 float DynamicHandicap_ClampHandicap(float handicap);
33 //========================= Free functions ====================================
35 /// \brief Updates the handicap of a given player.
36 /// \param[in,out] player Player to update.
37 /// \return No return.
38 void DynamicHandicap_UpdateHandicap(entity player)
40 float handicap = DynamicHandicap_GetBaseValue(player);
41 handicap = DynamicHandicap_ScaleHandicap(handicap);
42 handicap = DynamicHandicap_ClampHandicap(handicap);
43 Handicap_SetForcedHandicap(player, handicap);
46 float DynamicHandicap_GetBaseValue(entity player)
48 int kills = PlayerScore_Get(player, SP_KILLS);
49 int deaths = PlayerScore_Get(player, SP_DEATHS);
62 return kills / deaths;
65 float DynamicHandicap_ScaleHandicap(float handicap)
71 if (autocvar_g_dynamic_handicap_scale == 1)
78 handicap *= autocvar_g_dynamic_handicap_scale;
83 handicap = 1 / handicap;
85 handicap *= autocvar_g_dynamic_handicap_scale;
92 float DynamicHandicap_ClampHandicap(float handicap)
94 if ((autocvar_g_dynamic_handicap_min >= 0) && (handicap <
95 autocvar_g_dynamic_handicap_min))
97 handicap = autocvar_g_dynamic_handicap_min;
99 if ((autocvar_g_dynamic_handicap_max > 0) && (handicap >
100 autocvar_g_dynamic_handicap_max))
102 handicap = autocvar_g_dynamic_handicap_max;
107 //============================= Hooks ========================================
109 REGISTER_MUTATOR(dynamic_handicap, autocvar_g_dynamic_handicap);
111 MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsString)
113 M_ARGV(0, string) = strcat(M_ARGV(0, string), ":handicap");
116 MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsPrettyString)
118 M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Dynamic handicap");
121 /// \brief Hook that is called when player connects to the server.
122 MUTATOR_HOOKFUNCTION(dynamic_handicap, ClientConnect)
124 entity player = M_ARGV(0, entity);
125 DynamicHandicap_UpdateHandicap(player);
128 /// \brief Hook that is called when player dies.
129 MUTATOR_HOOKFUNCTION(dynamic_handicap, PlayerDies)
131 entity attacker = M_ARGV(1, entity);
132 entity victim = M_ARGV(2, entity);
133 DynamicHandicap_UpdateHandicap(victim);
134 if (!IS_CLIENT(attacker))
138 DynamicHandicap_UpdateHandicap(attacker);