]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Added Dynamic handicap.
authorLyberta <lyberta@lyberta.net>
Mon, 4 Sep 2017 14:33:31 +0000 (17:33 +0300)
committerLyberta <lyberta@lyberta.net>
Mon, 4 Sep 2017 14:33:31 +0000 (17:33 +0300)
mutators.cfg
qcsrc/common/mutators/mutator/_mod.inc
qcsrc/common/mutators/mutator/_mod.qh
qcsrc/common/mutators/mutator/dynamic_handicap/_mod.inc [new file with mode: 0644]
qcsrc/common/mutators/mutator/dynamic_handicap/_mod.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qh [new file with mode: 0644]

index 5eb8d1b9d6dae7d806a64bc55c8771535fd42efa..31d51f11ae7db2041cfcae1ab07b7bdd00ab72ff 100644 (file)
@@ -464,3 +464,11 @@ set g_bugrigs_steer 1      "steering amount"
 //  running guns
 // ==============
 set g_running_guns 0 "... or wonder, till it drives you mad, what would have followed if you had."
+
+// ==================
+//  dynamic handicap
+// ==================
+set g_dynamic_handicap 0 "Whether to enable dynamic handicap."
+set g_dynamic_handicap_scale 1 "The scale of the handicap. Larget values mean more penalties for strong players and more buffs for weak players."
+set g_dynamic_handicap_min 0 "The minimum value of the handicap."
+set g_dynamic_handicap_max 0 "The maximum value of the handicap."
index 0d6326fef0712b405f0ad88a856c27a61ef646ab..eeb93ba5e83f7cb9252274e397c994bf9e93a73e 100644 (file)
@@ -9,6 +9,7 @@
 #include <common/mutators/mutator/damagetext/_mod.inc>
 #include <common/mutators/mutator/dodging/_mod.inc>
 #include <common/mutators/mutator/doublejump/_mod.inc>
+#include <common/mutators/mutator/dynamic_handicap/_mod.inc>
 #include <common/mutators/mutator/globalforces/_mod.inc>
 #include <common/mutators/mutator/hook/_mod.inc>
 #include <common/mutators/mutator/instagib/_mod.inc>
index 917dc6557ceb02b2415649bc6d9546e6a400c9c6..956c0d97536fbfeaddc4d4b8b1728ce147d09bc5 100644 (file)
@@ -9,6 +9,7 @@
 #include <common/mutators/mutator/damagetext/_mod.qh>
 #include <common/mutators/mutator/dodging/_mod.qh>
 #include <common/mutators/mutator/doublejump/_mod.qh>
+#include <common/mutators/mutator/dynamic_handicap/_mod.qh>
 #include <common/mutators/mutator/globalforces/_mod.qh>
 #include <common/mutators/mutator/hook/_mod.qh>
 #include <common/mutators/mutator/instagib/_mod.qh>
diff --git a/qcsrc/common/mutators/mutator/dynamic_handicap/_mod.inc b/qcsrc/common/mutators/mutator/dynamic_handicap/_mod.inc
new file mode 100644 (file)
index 0000000..f4b0a30
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qc>
+#endif
diff --git a/qcsrc/common/mutators/mutator/dynamic_handicap/_mod.qh b/qcsrc/common/mutators/mutator/dynamic_handicap/_mod.qh
new file mode 100644 (file)
index 0000000..10aeb22
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qh>
+#endif
diff --git a/qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qc b/qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qc
new file mode 100644 (file)
index 0000000..43f10fd
--- /dev/null
@@ -0,0 +1,166 @@
+/// \file
+/// \brief Source file that contains implementation of the Dynamic handicap
+/// mutator.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+//======================= Global variables ====================================
+
+int autocvar_g_dynamic_handicap; ///< Whether to enable dynamic handicap.
+/// \brief The scale of the handicap. Larget values mean more penalties for
+/// strong players and more buffs for weak players.
+float autocvar_g_dynamic_handicap_scale;
+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.
+/// \param[in] player Player to evaluate.
+/// \return Base handicap value.
+float DynamicHandicap_GetBaseValue(entity player);
+
+/// \brief Scales the base value of the handicap.
+/// \param[in] handicap Value to scale.
+/// \return Scaled value.
+float DynamicHandicap_ScaleHandicap(float handicap);
+
+/// \brief Clamps the value of the handicap.
+/// \param[in] handicap Value to clamp.
+/// \return Clamped value.
+float DynamicHandicap_ClampHandicap(float handicap);
+
+//========================= Free functions ====================================
+
+/// \brief Updates the handicap of a given player.
+/// \param[in,out] player Player to update.
+/// \return No return.
+void DynamicHandicap_UpdateHandicap(entity player)
+{
+       float handicap = DynamicHandicap_GetBaseValue(player);
+       //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)));
+}
+
+float DynamicHandicap_GetBaseValue(entity player)
+{
+       int kills = PlayerScore_Get(player, SP_KILLS);
+       int deaths = PlayerScore_Get(player, SP_DEATHS);
+       if (kills == deaths)
+       {
+               return 1;
+       }
+       if (deaths == 0)
+       {
+               return kills;
+       }
+       if (kills == 0)
+       {
+               return 1 / deaths;
+       }
+       return kills / deaths;
+}
+
+float DynamicHandicap_ScaleHandicap(float handicap)
+{
+       if (handicap == 1)
+       {
+               return 1;
+       }
+       if (autocvar_g_dynamic_handicap_scale == 1)
+       {
+               return handicap;
+       }
+       if (handicap > 1)
+       {
+               handicap -= 1;
+               handicap *= autocvar_g_dynamic_handicap_scale;
+               return handicap + 1;
+       }
+       if (handicap < 1)
+       {
+               handicap = 1 / handicap;
+               handicap -= 1;
+               handicap *= autocvar_g_dynamic_handicap_scale;
+               handicap += 1;
+               return 1 / handicap;
+       }
+       return 1;
+}
+
+float DynamicHandicap_ClampHandicap(float handicap)
+{
+       if ((autocvar_g_dynamic_handicap_min >= 0) && (handicap <
+               autocvar_g_dynamic_handicap_min))
+       {
+               handicap = autocvar_g_dynamic_handicap_min;
+       }
+       if ((autocvar_g_dynamic_handicap_max > 0) && (handicap >
+               autocvar_g_dynamic_handicap_max))
+       {
+               handicap = autocvar_g_dynamic_handicap_max;
+       }
+       return handicap;
+}
+
+//============================= Hooks ========================================
+
+REGISTER_MUTATOR(dynamic_handicap, autocvar_g_dynamic_handicap);
+
+MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsString)
+{
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ":handicap");
+}
+
+MUTATOR_HOOKFUNCTION(dynamic_handicap, BuildMutatorsPrettyString)
+{
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Dynamic handicap");
+}
+
+/// \brief Hook that is called when player connects to the server.
+MUTATOR_HOOKFUNCTION(dynamic_handicap, ClientConnect)
+{
+       entity player = M_ARGV(0, entity);
+       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)
+{
+       entity attacker = M_ARGV(1, entity);
+       entity victim = M_ARGV(2, entity);
+       DynamicHandicap_UpdateHandicap(victim);
+       if (!IS_CLIENT(attacker))
+       {
+               return;
+       }
+       DynamicHandicap_UpdateHandicap(attacker);
+}
diff --git a/qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qh b/qcsrc/common/mutators/mutator/dynamic_handicap/sv_dynamic_handicap.qh
new file mode 100644 (file)
index 0000000..e69de29