From 859524daef3b651f3a26db0f57e65afe659f24f3 Mon Sep 17 00:00:00 2001
From: drjaska <drjaska83@gmail.com>
Date: Thu, 5 Sep 2024 08:50:38 +0300
Subject: [PATCH] Implement damage scaling based on accumulated spread

---
 bal-wep-mario.cfg                         |  2 ++
 bal-wep-nexuiz25.cfg                      |  2 ++
 bal-wep-samual.cfg                        |  2 ++
 bal-wep-xdf.cfg                           |  2 ++
 bal-wep-xonotic.cfg                       |  2 ++
 qcsrc/common/weapons/weapon/machinegun.qc | 33 +++++++++++++++++++++--
 qcsrc/common/weapons/weapon/machinegun.qh |  2 ++
 7 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/bal-wep-mario.cfg b/bal-wep-mario.cfg
index 306fb9a02e..6a2462d335 100644
--- a/bal-wep-mario.cfg
+++ b/bal-wep-mario.cfg
@@ -84,6 +84,8 @@ set g_balance_machinegun_spread_add 0.012
 set g_balance_machinegun_spread_decay 0.048
 set g_balance_machinegun_spread_max 0.05
 set g_balance_machinegun_spread_min 0.02
+set g_balance_machinegun_spread_cold_damagemultiplier 1
+set g_balance_machinegun_spread_heat_damagemultiplier 1
 set g_balance_machinegun_sustained_ammo 1
 set g_balance_machinegun_sustained_damage 10
 set g_balance_machinegun_sustained_force 3
diff --git a/bal-wep-nexuiz25.cfg b/bal-wep-nexuiz25.cfg
index aa241622e8..bfd58cf176 100644
--- a/bal-wep-nexuiz25.cfg
+++ b/bal-wep-nexuiz25.cfg
@@ -84,6 +84,8 @@ set g_balance_machinegun_spread_add 0.02
 set g_balance_machinegun_spread_decay 0
 set g_balance_machinegun_spread_max 0.6
 set g_balance_machinegun_spread_min 0.02
+set g_balance_machinegun_spread_cold_damagemultiplier 1
+set g_balance_machinegun_spread_heat_damagemultiplier 1
 set g_balance_machinegun_sustained_ammo 1
 set g_balance_machinegun_sustained_damage 15
 set g_balance_machinegun_sustained_force 27
diff --git a/bal-wep-samual.cfg b/bal-wep-samual.cfg
index 1320937e73..dd555810a2 100644
--- a/bal-wep-samual.cfg
+++ b/bal-wep-samual.cfg
@@ -84,6 +84,8 @@ set g_balance_machinegun_spread_add 0.012
 set g_balance_machinegun_spread_decay 0.048
 set g_balance_machinegun_spread_max 0.05
 set g_balance_machinegun_spread_min 0.02
+set g_balance_machinegun_spread_cold_damagemultiplier 1
+set g_balance_machinegun_spread_heat_damagemultiplier 1
 set g_balance_machinegun_sustained_ammo 1
 set g_balance_machinegun_sustained_damage 10
 set g_balance_machinegun_sustained_force 5
diff --git a/bal-wep-xdf.cfg b/bal-wep-xdf.cfg
index 36bd4b407e..0c33b8e0c3 100644
--- a/bal-wep-xdf.cfg
+++ b/bal-wep-xdf.cfg
@@ -84,6 +84,8 @@ set g_balance_machinegun_spread_add 0
 set g_balance_machinegun_spread_decay 0
 set g_balance_machinegun_spread_max 0
 set g_balance_machinegun_spread_min 0
+set g_balance_machinegun_spread_cold_damagemultiplier 1
+set g_balance_machinegun_spread_heat_damagemultiplier 1
 set g_balance_machinegun_sustained_ammo 1
 set g_balance_machinegun_sustained_damage 10
 set g_balance_machinegun_sustained_force 3
diff --git a/bal-wep-xonotic.cfg b/bal-wep-xonotic.cfg
index 803ae377d6..e24b172e84 100644
--- a/bal-wep-xonotic.cfg
+++ b/bal-wep-xonotic.cfg
@@ -84,6 +84,8 @@ set g_balance_machinegun_spread_add 0.012
 set g_balance_machinegun_spread_decay 0.048
 set g_balance_machinegun_spread_max 0.05
 set g_balance_machinegun_spread_min 0.02
+set g_balance_machinegun_spread_cold_damagemultiplier 1
+set g_balance_machinegun_spread_heat_damagemultiplier 1
 set g_balance_machinegun_sustained_ammo 1
 set g_balance_machinegun_sustained_damage 10
 set g_balance_machinegun_sustained_force 3
diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc
index 103d50b5be..89d3692a1d 100644
--- a/qcsrc/common/weapons/weapon/machinegun.qc
+++ b/qcsrc/common/weapons/weapon/machinegun.qc
@@ -30,6 +30,31 @@ void MachineGun_Update_Spread(entity actor, .entity weaponentity)
 	actor.(weaponentity).spreadUpdateTime = time;
 }
 
+ERASEABLE
+float MachineGun_Heat(float spread_accum)
+{
+	// function for reducing mg's damage with no spread and adding damage with
+	// heated up barrel or vice versa depending on the values of exposed cvars
+	float heatMultiplierApplicationPercent = 0.5;
+	float coldMultiplierApplicationPercent = 0.5;
+
+	float spreadSpectrumDistance = fabs(WEP_CVAR(WEP_MACHINEGUN, spread_max) - WEP_CVAR(WEP_MACHINEGUN, spread_min));
+
+	if (spreadSpectrumDistance > 0) // avoid division by 0, can never be < 0 either due to how it is set when defined
+	{
+		heatMultiplierApplicationPercent = spread_accum / spreadSpectrumDistance;
+		coldMultiplierApplicationPercent = 1 - heatMultiplierApplicationPercent;
+	}
+
+	// example where low end has halved damage and high end has tripled damage:
+	// with 50% spread accumulation: heat = (0.5 * 0.5) + (0.5 * 3) = 0.25 + 1.5 = 1.75 damage multiplier
+	// with 90% spread accumulation: heat = (0.1 * 0.5) + (0.9 * 3) = 0.05 + 2.7 = 2.75 damage multiplier
+	float heat = (coldMultiplierApplicationPercent * WEP_CVAR(WEP_MACHINEGUN, spread_cold_damagemultiplier))
+	           + (heatMultiplierApplicationPercent * WEP_CVAR(WEP_MACHINEGUN, spread_heat_damagemultiplier));
+
+	return heat;
+}
+
 void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity weaponentity)
 {
 	W_SetupShot(actor, weaponentity, true, 0, SND_UZI_FIRE, CH_WEAPON_A, ((actor.(weaponentity).misc_bulletcounter == 1) ? WEP_CVAR(WEP_MACHINEGUN, first_damage) : WEP_CVAR(WEP_MACHINEGUN, sustained_damage)), deathtype);
@@ -138,6 +163,8 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
 
 	float spread_accum = actor.(weaponentity).machinegun_spread_accumulation;
 
+	float heat = MachineGun_Heat(spread_accum);
+
 	float spread_accuracy;
 	if (WEP_CVAR(WEP_MACHINEGUN, spread_min) < WEP_CVAR(WEP_MACHINEGUN, spread_max))
 		spread_accuracy = WEP_CVAR(WEP_MACHINEGUN, spread_min) + spread_accum;
@@ -147,7 +174,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
 	fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir,
 	                   spread_accuracy,
 	                   WEP_CVAR(WEP_MACHINEGUN, solidpenetration),
-	                   WEP_CVAR(WEP_MACHINEGUN, sustained_damage),
+	                   WEP_CVAR(WEP_MACHINEGUN, sustained_damage) * heat,
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_halflife),
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist),
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist),
@@ -187,10 +214,12 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit
 
 	float spread_accum = actor.(weaponentity).machinegun_spread_accumulation;
 
+	float heat = MachineGun_Heat(spread_accum);
+
 	fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir,
 	                   WEP_CVAR(WEP_MACHINEGUN, burst_spread),
 	                   WEP_CVAR(WEP_MACHINEGUN, solidpenetration),
-	                   WEP_CVAR(WEP_MACHINEGUN, sustained_damage),
+	                   WEP_CVAR(WEP_MACHINEGUN, sustained_damage) * heat,
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_halflife),
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist),
 	                   WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist),
diff --git a/qcsrc/common/weapons/weapon/machinegun.qh b/qcsrc/common/weapons/weapon/machinegun.qh
index 10bfc08f0b..824ecc3d47 100644
--- a/qcsrc/common/weapons/weapon/machinegun.qh
+++ b/qcsrc/common/weapons/weapon/machinegun.qh
@@ -46,6 +46,8 @@ CLASS(MachineGun, Weapon)
 		P(class, prefix, spread_decay, float, NONE) \
 		P(class, prefix, spread_max, float, NONE) \
 		P(class, prefix, spread_min, float, NONE) \
+		P(class, prefix, spread_cold_damagemultiplier, float, NONE) \
+		P(class, prefix, spread_heat_damagemultiplier, float, NONE) \
 		P(class, prefix, sustained_ammo, float, NONE) \
 		P(class, prefix, sustained_damage, float, NONE) \
 		P(class, prefix, sustained_force, float, NONE) \
-- 
GitLab