float autocvar_g_dynamic_handicap_min; ///< The minimum value of the handicap.
float autocvar_g_dynamic_handicap_max; ///< The maximum value of the handicap.
-.float dynamic_handicap; ///< Holds the dynamic handicap value.
-
//====================== Forward declarations =================================
/// \brief Returns the base value of the handicap.
//PrintToChat(player, strcat("Base handicap = ", ftos(handicap)));
handicap = DynamicHandicap_ScaleHandicap(handicap);
//PrintToChat(player, strcat("Scaled handicap = ", ftos(handicap)));
- player.dynamic_handicap = DynamicHandicap_ClampHandicap(handicap);
- //PrintToChat(player, strcat("Clamped handicap = ",
- // ftos(player.dynamic_handicap)));
+ handicap = DynamicHandicap_ClampHandicap(handicap);
+ //PrintToChat(player, strcat("Clamped handicap = ", ftos(handicap)));
+ Handicap_SetForcedHandicap(player, handicap);
}
float DynamicHandicap_GetBaseValue(entity player)
DynamicHandicap_UpdateHandicap(player);
}
-/// \brief Hook which is called when the damage amount must be determined.
-MUTATOR_HOOKFUNCTION(dynamic_handicap, Damage_Calculate)
-{
- entity frag_attacker = M_ARGV(1, entity);
- entity frag_target = M_ARGV(2, entity);
- float deathtype = M_ARGV(3, float);
- float damage = M_ARGV(4, float);
- if (DEATH_ISSPECIAL(deathtype))
- {
- return;
- }
- if (IS_CLIENT(frag_attacker))
- {
- damage /= frag_attacker.dynamic_handicap;
- }
- if (IS_CLIENT(frag_target))
- {
- damage *= frag_target.dynamic_handicap;
- }
- M_ARGV(4, float) = damage;
-}
-
/// \brief Hook that is called when player dies.
MUTATOR_HOOKFUNCTION(dynamic_handicap, PlayerDies)
{
#include <server/g_models.qc>
#include <server/g_subs.qc>
#include <server/g_world.qc>
+#include <server/handicap.qc>
#include <server/impulse.qc>
#include <server/ipban.qc>
#include <server/item_key.qc>
#include <server/g_models.qh>
#include <server/g_subs.qh>
#include <server/g_world.qh>
+#include <server/handicap.qh>
#include <server/impulse.qh>
#include <server/ipban.qh>
#include <server/item_key.qh>
#include "spawnpoints.qh"
#include "resources.qh"
#include "g_damage.qh"
+#include "handicap.qh"
#include "g_hook.qh"
#include "command/common.qh"
#include "cheats.qh"
it.init_for_player(it, this);
});
+ Handicap_Initialize(this);
+
MUTATOR_CALLHOOK(ClientConnect, this);
if (IS_REAL_CLIENT(this))
--- /dev/null
+#include "handicap.qh"
+
+/// \file
+/// \brief Source file that contains implementation of the handicap system.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+.float m_handicap; ///< Holds the handicap value.
+
+void Handicap_Initialize(entity player)
+{
+ player.m_handicap = 1;
+}
+
+float Handicap_GetVoluntaryHandicap(entity player)
+{
+ return bound(1.0, CS(player).cvar_cl_handicap, 10.0);
+}
+
+float Handicap_GetForcedHandicap(entity player)
+{
+ return player.m_handicap;
+}
+
+void Handicap_SetForcedHandicap(entity player, float value)
+{
+ if (value <= 0)
+ {
+ error("Handicap_SetForcedHandicap: Invalid handicap value.");
+ }
+ player.m_handicap = value;
+}
+
+float Handicap_GetTotalHandicap(entity player)
+{
+ return Handicap_GetForcedHandicap(player) * Handicap_GetVoluntaryHandicap(
+ player);
+}
--- /dev/null
+#pragma once
+
+/// \file
+/// \brief Header file that describes the handicap system.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+// Handicap is used to make the game harder for strong players and easier for
+// 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
+// handicap can be set by server mutators. The total handicap is the product of
+// voluntary and forced handicap.
+
+/// \brief Initializes handicap to its default value.
+/// \param[in,out] player Player to initialize.
+/// \return No return.
+void Handicap_Initialize(entity player);
+
+/// \brief Returns the voluntary handicap of the player.
+/// \param[in] player Player to check.
+/// \return Voluntary handicap of the player.
+float Handicap_GetVoluntaryHandicap(entity player);
+
+/// \brief Returns the forced handicap of the player.
+/// \param[in] player Player to check.
+/// \return Forced handicap of the player.
+float Handicap_GetForcedHandicap(entity player);
+
+/// \brief Sets the forced handicap of the player.
+/// \param[in] player Player to alter.
+/// \param[in] value Handicap value to set.
+/// \return No return.
+void Handicap_SetForcedHandicap(entity player, float value);
+
+/// \brief Returns the total handicap of the player.
+/// \param[in] player Player to check.
+/// \return Total handicap of the player.
+float Handicap_GetTotalHandicap(entity player);
if(!DEATH_ISSPECIAL(deathtype))
{
- damage *= bound(1.0, CS(this).cvar_cl_handicap, 10.0);
- if(this != attacker && IS_PLAYER(attacker))
- damage /= bound(1.0, CS(attacker).cvar_cl_handicap, 10.0);
+ damage *= Handicap_GetTotalHandicap(this);
+ if (this != attacker && IS_PLAYER(attacker))
+ {
+ damage /= Handicap_GetTotalHandicap(attacker);
+ }
}
if (time < this.spawnshieldtime && autocvar_g_spawnshield_blockdamage < 1)