From ed345eed29e9ffe3bd08ecf64643520519ea9145 Mon Sep 17 00:00:00 2001
From: terencehill <piuntn@gmail.com>
Date: Sun, 26 Apr 2020 17:30:40 +0200
Subject: [PATCH] LMS: attackers receive a fraction of health removed from
 enemies based on the number of lives less than the enemy

---
 gamemodes-server.cfg                          |  5 +++
 qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc | 33 +++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg
index a466211a32..21f84e8899 100644
--- a/gamemodes-server.cfg
+++ b/gamemodes-server.cfg
@@ -448,6 +448,11 @@ set g_lms_leader_wp_time_repeat 30 "periodically show again waypoints for leader
 set g_lms_dynamic_respawn_delay 1 "increase player respawn delay based on the number of lives less than the leader (NOTE: delay doesn't increase when only 2 players are left alive)"
 set g_lms_dynamic_respawn_delay_base 2 "base player respawn delay"
 set g_lms_dynamic_respawn_delay_increase 3 "increase base player respawn delay by this amount of time for each life less than the leader"
+set g_lms_dynamic_vampire 1 "attackers receive a fraction of health removed from enemies based on the number of lives less than the enemy"
+set g_lms_dynamic_vampire_factor_base 0.1 "base vampire factor"
+set g_lms_dynamic_vampire_factor_increase 0.1 "increase vampire factor by this fraction for each life less than the enemy"
+set g_lms_dynamic_vampire_factor_max 0.5 "max vampire factor"
+set g_lms_dynamic_vampire_min_lives_diff 2 "number of lives the attacker must have less than the enemy to receive the base fraction of health"
 
 
 // =========
diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
index d31938591d..ae9af3e7dc 100644
--- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
+++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
@@ -15,6 +15,11 @@ float autocvar_g_lms_leader_wp_time_repeat;
 float autocvar_g_lms_dynamic_respawn_delay;
 float autocvar_g_lms_dynamic_respawn_delay_base;
 float autocvar_g_lms_dynamic_respawn_delay_increase;
+bool autocvar_g_lms_dynamic_vampire;
+float autocvar_g_lms_dynamic_vampire_factor_base;
+float autocvar_g_lms_dynamic_vampire_factor_increase;
+float autocvar_g_lms_dynamic_vampire_factor_max;
+int autocvar_g_lms_dynamic_vampire_min_lives_diff;
 
 .float lms_wp_time;
 
@@ -322,6 +327,34 @@ MUTATOR_HOOKFUNCTION(lms, ForbidThrowCurrentWeapon)
 	return true;
 }
 
+MUTATOR_HOOKFUNCTION(lms, Damage_Calculate)
+{
+	if (!autocvar_g_lms_dynamic_vampire)
+		return;
+
+	entity frag_attacker = M_ARGV(1, entity);
+	entity frag_target = M_ARGV(2, entity);
+	float frag_damage = M_ARGV(4, float);
+
+	if (IS_PLAYER(frag_attacker) && !IS_DEAD(frag_target) && frag_attacker != frag_target)
+	{
+		float vampire_factor = 0;
+
+		int frag_attacker_lives = GameRules_scoring_add(frag_attacker, LMS_LIVES, 0);
+		int frag_target_lives = GameRules_scoring_add(frag_target, LMS_LIVES, 0);
+		int diff = frag_target_lives - frag_attacker_lives - autocvar_g_lms_dynamic_vampire_min_lives_diff;
+
+		if (diff >= 0)
+			vampire_factor = autocvar_g_lms_dynamic_vampire_factor_base + diff * autocvar_g_lms_dynamic_vampire_factor_increase;
+		if (vampire_factor > 0)
+		{
+			vampire_factor = min(vampire_factor, autocvar_g_lms_dynamic_vampire_factor_max);
+			SetResourceExplicit(frag_attacker, RES_HEALTH,
+				min(GetResource(frag_attacker, RES_HEALTH) + frag_damage * vampire_factor, start_health));
+		}
+	}
+}
+
 bool lms_waypointsprite_visible_for_player(entity this, entity player, entity view) // runs on waypoints which are attached to ballcarriers, updates once per frame
 {
 	if(view.lms_wp_time)
-- 
2.39.5