]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Rework Machinegun's spread to be time-based
authordrjaska <drjaska83@gmail.com>
Wed, 4 Sep 2024 18:03:25 +0000 (21:03 +0300)
committerdrjaska <drjaska83@gmail.com>
Fri, 4 Oct 2024 21:17:12 +0000 (00:17 +0300)
.gitlab-ci.yml
bal-wep-mario.cfg
bal-wep-nexuiz25.cfg
bal-wep-samual.cfg
bal-wep-xdf.cfg
bal-wep-xonotic.cfg
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/machinegun.qh

index 3d2d310a028d30ddfd0dc7722d5af104bc25c70f..d23e39d873554809286876f37a42cb5ba104d263 100644 (file)
@@ -36,7 +36,7 @@ test_compilation_units:
 test_sv_game:
   stage: test
   script:
-    - export EXPECT=82b429be1301d38fbe0af0c60511ceed
+    - export EXPECT=7183280c0932824d5cda66d4dc803f76
     - qcsrc/tools/sv_game-hashtest.sh
     - exit $?
 
index 957ee37689c7c0358f2aa02df80a93eedab37bb7..306fb9a02e1719bcc4a617f137779d8cf96bafea 100644 (file)
@@ -81,6 +81,7 @@ set g_balance_machinegun_reload_ammo 0
 set g_balance_machinegun_reload_time 2
 set g_balance_machinegun_solidpenetration 13.1
 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_sustained_ammo 1
index ac49e46179a18335f7fac70d58a2bd4ed20f4215..aa241622e8aebf47d1d993524dcfba1e4eddd689 100644 (file)
@@ -81,6 +81,7 @@ set g_balance_machinegun_reload_ammo 0
 set g_balance_machinegun_reload_time 2
 set g_balance_machinegun_solidpenetration 13.1
 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_sustained_ammo 1
index 53d2c7dbb5efbdc071a105bf7ff1694e6bb5ef6d..1320937e735cef7d8bf775208c314ad35eb02204 100644 (file)
@@ -81,6 +81,7 @@ set g_balance_machinegun_reload_ammo 60
 set g_balance_machinegun_reload_time 2
 set g_balance_machinegun_solidpenetration 13.1
 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_sustained_ammo 1
index 8e22f7b5b073d7acb36b4d92f96ed217693e47ad..36bd4b407e6bec4f78eb47ed07f3bce64411b4f1 100644 (file)
@@ -81,6 +81,7 @@ set g_balance_machinegun_reload_ammo 0
 set g_balance_machinegun_reload_time 2
 set g_balance_machinegun_solidpenetration 13.1
 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_sustained_ammo 1
index 07a6fc0d0337d3c5234226472b7c3bb9366fdb36..803ae377d692a90a28400422c225a99d8dc8fae2 100644 (file)
@@ -81,6 +81,7 @@ set g_balance_machinegun_reload_ammo 0
 set g_balance_machinegun_reload_time 2
 set g_balance_machinegun_solidpenetration 13.1
 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_sustained_ammo 1
index b0517597f4f6553b2e30d36e68657dcbe4ecb533..cee025caf4c7a07ed73a5267840849a4836418e4 100644 (file)
@@ -2,6 +2,35 @@
 
 #ifdef SVQC
 
+.float machinegun_spread_accumulation;
+.float spreadUpdateTime;
+
+
+ERASEABLE
+void MachineGun_Update_Spread(entity actor, .entity weaponentity, float spreadSpectrumMin, float spreadSpectrumMax)
+{
+       float spread_accum = actor.(weaponentity).machinegun_spread_accumulation;
+
+       // time based spread decay
+       if (WEP_CVAR(WEP_MACHINEGUN, spread_decay))
+       {
+               float spreadSpectrumDistance = spreadSpectrumMax - spreadSpectrumMin;
+               float timediff = time - actor.(weaponentity).spreadUpdateTime;
+               spread_accum = bound(0,
+                       spread_accum - (timediff * WEP_CVAR(WEP_MACHINEGUN, spread_decay)),
+                       spreadSpectrumDistance);
+       }
+       else // legacy behavior for Nexuiz weapon balance
+       {
+               spread_accum = bound(WEP_CVAR(WEP_MACHINEGUN, spread_min),
+                       (WEP_CVAR(WEP_MACHINEGUN, spread_add) * actor.(weaponentity).misc_bulletcounter),
+                       WEP_CVAR(WEP_MACHINEGUN, spread_max));
+       }
+
+       actor.(weaponentity).machinegun_spread_accumulation = spread_accum;
+       actor.(weaponentity).spreadUpdateTime = time;
+}
+
 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);
@@ -72,7 +101,7 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit
                        w_ready(thiswep, actor, weaponentity, fire);
                        return;
                }
-               actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
+               ++actor.(weaponentity).misc_bulletcounter;
                W_MachineGun_Attack(thiswep, thiswep.m_id, actor, weaponentity);
                weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_MACHINEGUN, sustained_refire), W_MachineGun_Attack_Frame);
        }
@@ -83,8 +112,6 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit
 
 void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
-       float machinegun_spread;
-
        if(!(fire & 1) || !weapon_prepareattack_check(thiswep, actor, weaponentity, false, -1))
        {
                w_ready(thiswep, actor, weaponentity, fire);
@@ -108,12 +135,29 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
                actor.punchangle_y = random() - 0.5;
        }
 
-       machinegun_spread = bound(WEP_CVAR(WEP_MACHINEGUN, spread_min), WEP_CVAR(WEP_MACHINEGUN, spread_min) + (WEP_CVAR(WEP_MACHINEGUN, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR(WEP_MACHINEGUN, spread_max));
-       fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(WEP_MACHINEGUN, solidpenetration), WEP_CVAR(WEP_MACHINEGUN, sustained_damage),
-               WEP_CVAR(WEP_MACHINEGUN, damagefalloff_halflife), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist), 0,
-               WEP_CVAR(WEP_MACHINEGUN, sustained_force), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_forcehalflife), thiswep.m_id, EFFECT_BULLET, true);
+       MachineGun_Update_Spread(actor, weaponentity, WEP_CVAR(WEP_MACHINEGUN, spread_min), WEP_CVAR(WEP_MACHINEGUN, spread_max));
+
+       float spread_accum = actor.(weaponentity).machinegun_spread_accumulation;
+
+       float spread_accuracy = WEP_CVAR(WEP_MACHINEGUN, spread_min) + spread_accum;
+
+       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, damagefalloff_halflife),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist),
+                          0,
+                          WEP_CVAR(WEP_MACHINEGUN, sustained_force),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_forcehalflife),
+                          thiswep.m_id, EFFECT_BULLET, true);
+
+       ++actor.(weaponentity).misc_bulletcounter;
 
-       actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
+       spread_accum += WEP_CVAR(WEP_MACHINEGUN, spread_add);
+
+       actor.(weaponentity).machinegun_spread_accumulation = spread_accum;
 
        W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
 
@@ -136,9 +180,21 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit
                actor.punchangle_y = random() - 0.5;
        }
 
-       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, damagefalloff_halflife), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist), 0,
-               WEP_CVAR(WEP_MACHINEGUN, sustained_force), WEP_CVAR(WEP_MACHINEGUN, damagefalloff_forcehalflife), thiswep.m_id, EFFECT_BULLET, true);
+       MachineGun_Update_Spread(actor, weaponentity, WEP_CVAR(WEP_MACHINEGUN, spread_min), WEP_CVAR(WEP_MACHINEGUN, spread_max));
+
+       float spread_accum = actor.(weaponentity).machinegun_spread_accumulation;
+
+       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, damagefalloff_halflife),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_mindist),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_maxdist),
+                          0,
+                          WEP_CVAR(WEP_MACHINEGUN, sustained_force),
+                          WEP_CVAR(WEP_MACHINEGUN, damagefalloff_forcehalflife),
+                          thiswep.m_id, EFFECT_BULLET, true);
 
        W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
 
@@ -148,7 +204,11 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit
                SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
        }
 
-       actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
+       spread_accum += WEP_CVAR(WEP_MACHINEGUN, spread_add);
+
+       actor.(weaponentity).machinegun_spread_accumulation = spread_accum;
+
+       ++actor.(weaponentity).misc_bulletcounter;
        if(actor.(weaponentity).misc_bulletcounter == 0)
        {
                ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(WEP_MACHINEGUN, burst_refire2) * W_WeaponRateFactor(actor);
index cf6a17434d37a96d26944379299337233a246d90..10bfc08f0b477b25b566efcceacc94821f582c45 100644 (file)
@@ -43,6 +43,7 @@ CLASS(MachineGun, Weapon)
                P(class, prefix, reload_time, float, NONE) \
                P(class, prefix, solidpenetration, float, NONE) \
                P(class, prefix, spread_add, float, NONE) \
+               P(class, prefix, spread_decay, float, NONE) \
                P(class, prefix, spread_max, float, NONE) \
                P(class, prefix, spread_min, float, NONE) \
                P(class, prefix, sustained_ammo, float, NONE) \