From 9bb80b00c7075c5ad6c07cd6d35c27c82612ef2c Mon Sep 17 00:00:00 2001 From: "Dr. Jaska" Date: Sun, 28 Jul 2024 03:16:25 +0000 Subject: [PATCH] Implement a fixed spread pattern, for (OK) Shotgun (Crylink and Hagar share the function call also) --- bal-wep-mario.cfg | 4 ++ bal-wep-nexuiz25.cfg | 4 ++ bal-wep-samual.cfg | 4 ++ bal-wep-xdf.cfg | 4 ++ bal-wep-xonotic.cfg | 4 ++ .../mutators/mutator/overkill/okshotgun.qc | 2 + .../mutators/mutator/overkill/okshotgun.qh | 2 + qcsrc/common/weapons/calculations.qc | 46 +++++++++++++++++ qcsrc/common/weapons/weapon/crylink.qc | 21 +------- qcsrc/common/weapons/weapon/hagar.qc | 11 +---- qcsrc/common/weapons/weapon/shockwave.qc | 2 +- qcsrc/common/weapons/weapon/shotgun.qc | 49 ++++++++++++++++--- qcsrc/common/weapons/weapon/shotgun.qh | 18 ++++--- 13 files changed, 126 insertions(+), 45 deletions(-) diff --git a/bal-wep-mario.cfg b/bal-wep-mario.cfg index 66b029fea..2f3ac6ceb 100644 --- a/bal-wep-mario.cfg +++ b/bal-wep-mario.cfg @@ -44,6 +44,8 @@ set g_balance_shotgun_primary_force 15 set g_balance_shotgun_primary_refire 0.75 set g_balance_shotgun_primary_solidpenetration 3.8 set g_balance_shotgun_primary_spread 0.12 +set g_balance_shotgun_primary_spread_pattern 0 +set g_balance_shotgun_primary_spread_pattern_scale 0 set g_balance_shotgun_reload_ammo 0 set g_balance_shotgun_reload_time 2 set g_balance_shotgun_secondary 1 @@ -987,6 +989,8 @@ set g_balance_okshotgun_primary_force 80 set g_balance_okshotgun_primary_refire 0.75 set g_balance_okshotgun_primary_solidpenetration 3.8 set g_balance_okshotgun_primary_spread 0.07 +set g_balance_okshotgun_primary_spread_pattern 0 +set g_balance_okshotgun_primary_spread_pattern_scale 0 set g_balance_okshotgun_reload_ammo 24 set g_balance_okshotgun_reload_time 2 set g_balance_okshotgun_secondary_animtime 0.2 diff --git a/bal-wep-nexuiz25.cfg b/bal-wep-nexuiz25.cfg index ebc0ab772..64f3b3a5d 100644 --- a/bal-wep-nexuiz25.cfg +++ b/bal-wep-nexuiz25.cfg @@ -44,6 +44,8 @@ set g_balance_shotgun_primary_force 60 set g_balance_shotgun_primary_refire 0.5 set g_balance_shotgun_primary_solidpenetration 3.8 set g_balance_shotgun_primary_spread 0.07 +set g_balance_shotgun_primary_spread_pattern 0 +set g_balance_shotgun_primary_spread_pattern_scale 0 set g_balance_shotgun_reload_ammo 0 set g_balance_shotgun_reload_time 2 set g_balance_shotgun_secondary 2 @@ -987,6 +989,8 @@ set g_balance_okshotgun_primary_force 80 set g_balance_okshotgun_primary_refire 0.75 set g_balance_okshotgun_primary_solidpenetration 3.8 set g_balance_okshotgun_primary_spread 0.07 +set g_balance_okshotgun_primary_spread_pattern 0 +set g_balance_okshotgun_primary_spread_pattern_scale 0 set g_balance_okshotgun_reload_ammo 24 set g_balance_okshotgun_reload_time 2 set g_balance_okshotgun_secondary_animtime 0.2 diff --git a/bal-wep-samual.cfg b/bal-wep-samual.cfg index 049e080cb..d202f3af8 100644 --- a/bal-wep-samual.cfg +++ b/bal-wep-samual.cfg @@ -44,6 +44,8 @@ set g_balance_shotgun_primary_force 15 set g_balance_shotgun_primary_refire 0.75 set g_balance_shotgun_primary_solidpenetration 3.8 set g_balance_shotgun_primary_spread 0.12 +set g_balance_shotgun_primary_spread_pattern 0 +set g_balance_shotgun_primary_spread_pattern_scale 0 set g_balance_shotgun_reload_ammo 0 set g_balance_shotgun_reload_time 2 set g_balance_shotgun_secondary 1 @@ -987,6 +989,8 @@ set g_balance_okshotgun_primary_force 80 set g_balance_okshotgun_primary_refire 0.75 set g_balance_okshotgun_primary_solidpenetration 3.8 set g_balance_okshotgun_primary_spread 0.07 +set g_balance_okshotgun_primary_spread_pattern 0 +set g_balance_okshotgun_primary_spread_pattern_scale 0 set g_balance_okshotgun_reload_ammo 24 set g_balance_okshotgun_reload_time 2 set g_balance_okshotgun_secondary_animtime 0.2 diff --git a/bal-wep-xdf.cfg b/bal-wep-xdf.cfg index 70fdb4700..c5c8ca474 100644 --- a/bal-wep-xdf.cfg +++ b/bal-wep-xdf.cfg @@ -44,6 +44,8 @@ set g_balance_shotgun_primary_force 15 set g_balance_shotgun_primary_refire 0.75 set g_balance_shotgun_primary_solidpenetration 3.8 set g_balance_shotgun_primary_spread 0.12 +set g_balance_shotgun_primary_spread_pattern 0 +set g_balance_shotgun_primary_spread_pattern_scale 0 set g_balance_shotgun_reload_ammo 0 set g_balance_shotgun_reload_time 2 set g_balance_shotgun_secondary 1 @@ -987,6 +989,8 @@ set g_balance_okshotgun_primary_force 80 set g_balance_okshotgun_primary_refire 0.75 set g_balance_okshotgun_primary_solidpenetration 3.8 set g_balance_okshotgun_primary_spread 0.07 +set g_balance_okshotgun_primary_spread_pattern 0 +set g_balance_okshotgun_primary_spread_pattern_scale 0 set g_balance_okshotgun_reload_ammo 24 set g_balance_okshotgun_reload_time 2 set g_balance_okshotgun_secondary_animtime 0.2 diff --git a/bal-wep-xonotic.cfg b/bal-wep-xonotic.cfg index 1b2a56176..bb61ad2f2 100644 --- a/bal-wep-xonotic.cfg +++ b/bal-wep-xonotic.cfg @@ -44,6 +44,8 @@ set g_balance_shotgun_primary_force 15 set g_balance_shotgun_primary_refire 0.75 set g_balance_shotgun_primary_solidpenetration 3.8 set g_balance_shotgun_primary_spread 0.12 +set g_balance_shotgun_primary_spread_pattern 0 +set g_balance_shotgun_primary_spread_pattern_scale 0 set g_balance_shotgun_reload_ammo 0 set g_balance_shotgun_reload_time 2 set g_balance_shotgun_secondary 1 @@ -987,6 +989,8 @@ set g_balance_okshotgun_primary_force 80 set g_balance_okshotgun_primary_refire 0.75 set g_balance_okshotgun_primary_solidpenetration 3.8 set g_balance_okshotgun_primary_spread 0.07 +set g_balance_okshotgun_primary_spread_pattern 0 +set g_balance_okshotgun_primary_spread_pattern_scale 0 set g_balance_okshotgun_reload_ammo 24 set g_balance_okshotgun_reload_time 2 set g_balance_okshotgun_secondary_animtime 0.2 diff --git a/qcsrc/common/mutators/mutator/overkill/okshotgun.qc b/qcsrc/common/mutators/mutator/overkill/okshotgun.qc index 7fae9ad30..301ed4d9e 100644 --- a/qcsrc/common/mutators/mutator/overkill/okshotgun.qc +++ b/qcsrc/common/mutators/mutator/overkill/okshotgun.qc @@ -55,6 +55,8 @@ METHOD(OverkillShotgun, wr_think, void(entity thiswep, entity actor, .entity wea WEP_CVAR_PRI(okshotgun, damagefalloff_maxdist), WEP_CVAR_PRI(okshotgun, bullets), WEP_CVAR_PRI(okshotgun, spread), + WEP_CVAR_PRI(okshotgun, spread_pattern), + WEP_CVAR_PRI(okshotgun, spread_pattern_scale), WEP_CVAR_PRI(okshotgun, solidpenetration), WEP_CVAR_PRI(okshotgun, force), WEP_CVAR_PRI(okshotgun, damagefalloff_forcehalflife), diff --git a/qcsrc/common/mutators/mutator/overkill/okshotgun.qh b/qcsrc/common/mutators/mutator/overkill/okshotgun.qh index 094f15688..91412689b 100644 --- a/qcsrc/common/mutators/mutator/overkill/okshotgun.qh +++ b/qcsrc/common/mutators/mutator/overkill/okshotgun.qh @@ -32,6 +32,8 @@ CLASS(OverkillShotgun, Weapon) P(class, prefix, refire, float, PRI) \ P(class, prefix, solidpenetration, float, PRI) \ P(class, prefix, spread, float, PRI) \ + P(class, prefix, spread_pattern, float, PRI) \ + P(class, prefix, spread_pattern_scale, float, PRI) \ P(class, prefix, animtime, float, SEC) \ P(class, prefix, damage, float, SEC) \ P(class, prefix, delay, float, SEC) \ diff --git a/qcsrc/common/weapons/calculations.qc b/qcsrc/common/weapons/calculations.qc index cd2d925bc..4830efb20 100644 --- a/qcsrc/common/weapons/calculations.qc +++ b/qcsrc/common/weapons/calculations.qc @@ -184,6 +184,52 @@ int W_GetGunAlignment(entity player) } #endif +vector W_CalculateSpreadPattern(int pattern, int counter, int total) +{ + vector s = '0 0 0'; + + switch (pattern) + { + default: + case 1: + { + // first is always centered + if (counter == 0) + return '0 0 0'; + + makevectors('0 360 0' * (0.75 + (counter - 0.5) / (total - 1))); + s.y = v_forward.x; + s.z = v_forward.y; + + return s; + } + case 2: + { + // first is always centered + if (counter == 0) + return '0 0 0'; + + // points form a round circle with even distribution + // this could be simplified to '0 360 0' * (counter / total) + // but it would lose ALL the specific placements + // for example with this 2 pellets is center + directly up + // while 3 pellets is a horizontal sweep and and 4 is an upside + // down Y shape, 5 is a star instead of a pentagram, + // 9 is a 3x3 grid and 13 is a circle with center + 3 per quadrant + makevectors('0 360 0' * ((0.25 * ((total + 1) % 2)) + (counter / (total - 1)))); + + // return transform vector + s.y = v_forward.x; + s.z = v_forward.y; + + //else // return original result normal vector + //s = v_forward; + + return s; + } + } +} + vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle) { float sigma; diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 6a69a7c57..60ab1336f 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -347,16 +347,7 @@ void W_Crylink_Attack(Weapon thiswep, entity actor, .entity weaponentity) setorigin(proj, w_shotorg); setsize(proj, '0 0 0', '0 0 0'); - - s = '0 0 0'; - if(counter == 0) - s = '0 0 0'; - else - { - makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1))); - s.y = v_forward.x; - s.z = v_forward.y; - } + s = W_CalculateSpreadPattern(1, counter, shots); s = s * WEP_CVAR_PRI(crylink, spread) * autocvar_g_weaponspreadfactor; W_SetupProjVelocity_Explicit(proj, w_shotdir + right * s.y + up * s.z, v_up, WEP_CVAR_PRI(crylink, speed), 0, 0, 0, false); settouch(proj, W_Crylink_Touch); @@ -462,15 +453,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor, .entity weaponentity) if(WEP_CVAR_SEC(crylink, spreadtype) == 1) { - s = '0 0 0'; - if(counter == 0) - s = '0 0 0'; - else - { - makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1))); - s.y = v_forward.x; - s.z = v_forward.y; - } + s = W_CalculateSpreadPattern(1, counter, shots); s = s * WEP_CVAR_SEC(crylink, spread) * autocvar_g_weaponspreadfactor; s = w_shotdir + right * s.y + up * s.z; } diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index a8c12efcc..d018bb3f6 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -223,16 +223,7 @@ void W_Hagar_Attack2_Load_Release(Weapon thiswep, entity actor, .entity weaponen spread_pershot = (1 - (spread_pershot * WEP_CVAR_SEC(hagar, load_spread_bias))); spread_pershot = (WEP_CVAR_SEC(hagar, spread) * spread_pershot * autocvar_g_weaponspreadfactor); - // pattern spread calculation - s = '0 0 0'; - if(counter == 0) - s = '0 0 0'; - else - { - makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1))); - s.y = v_forward.x; - s.z = v_forward.y; - } + s = W_CalculateSpreadPattern(1, counter, shots); s = s * WEP_CVAR_SEC(hagar, load_spread) * autocvar_g_weaponspreadfactor; W_SetupProjVelocity_Explicit(missile, w_shotdir + right * s.y + up * s.z, v_up, WEP_CVAR_SEC(hagar, speed), 0, 0, spread_pershot, false); diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index b41a14f34..29dbdb279 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -709,7 +709,7 @@ void Draw_Shockwave(entity this) for(counter = 0; counter < divisions; ++counter) { // perfect circle effect lines - makevectors('0 360 0' * (0.75 + (counter - 0.5) / divisions)); + makevectors('0 360 0' * (counter / divisions)); angle.y = v_forward.x; angle.z = v_forward.y; diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 89bdf2a36..b28e3c96a 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -8,8 +8,11 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float isprimary, float ammocount, float damage, float falloff_halflife, float falloff_mindist, float falloff_maxdist, - float bullets, float spread, float solidpenetration, - float force, float falloff_forcehalflife, entity bullet_trail_effect) + float bullets, float spread, + float spread_pattern, float spread_pattern_scale, + float solidpenetration, + float force, float falloff_forcehalflife, + entity bullet_trail_effect) { W_DecreaseAmmo(thiswep, actor, ammocount, weaponentity); @@ -22,10 +25,34 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, if(lag && bullets > 0) antilag_takeback_all(actor, lag); - for(int sc = 0;sc < bullets;sc = sc + 1) - fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir, spread, solidpenetration, - damage, falloff_halflife, falloff_mindist, falloff_maxdist, 0, force, - falloff_forcehalflife, thiswep.m_id, bullet_trail_effect, false); + if (spread_pattern && spread_pattern_scale > 0) + { + vector right, up; + right = v_right; + up = v_up; + + float fixed_spread_factor = (spread * autocvar_g_weaponspreadfactor) / spread_pattern_scale; + + for(int sc = 0; sc < bullets; ++sc) + { + vector s = W_CalculateSpreadPattern(spread_pattern, sc, bullets); + s = s * fixed_spread_factor; + fireBullet_falloff(actor, weaponentity, + w_shotorg, w_shotdir + right * s.y + up * s.z, + 0, solidpenetration, damage, + falloff_halflife, falloff_mindist, falloff_maxdist, + 0, force, falloff_forcehalflife, + thiswep.m_id, bullet_trail_effect, false); + } + } + else + for(int sc = 0; sc < bullets; ++sc) + fireBullet_falloff(actor, weaponentity, + w_shotorg, w_shotdir, + spread, solidpenetration, damage, + falloff_halflife, falloff_mindist, falloff_maxdist, + 0, force, falloff_forcehalflife, + thiswep.m_id, bullet_trail_effect, false); if(lag && bullets > 0) antilag_restore_all(actor); @@ -36,7 +63,7 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, if(autocvar_g_casings >= 1) { makevectors(actor.v_angle); // for some reason, this is lost - //for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, ammo);sc = sc + 1) + //for(int sc = 0; sc < WEP_CVAR_PRI(shotgun, ammo); ++sc) SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), vectoangles(v_forward), 1, actor, weaponentity); } } @@ -176,6 +203,8 @@ void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity WEP_CVAR_PRI(shotgun, damagefalloff_maxdist), WEP_CVAR_PRI(shotgun, bullets), WEP_CVAR_PRI(shotgun, spread), + WEP_CVAR_PRI(shotgun, spread_pattern), + WEP_CVAR_PRI(shotgun, spread_pattern_scale), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, force), WEP_CVAR_PRI(shotgun, damagefalloff_forcehalflife), @@ -200,6 +229,8 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity WEP_CVAR_PRI(shotgun, damagefalloff_maxdist), WEP_CVAR_PRI(shotgun, bullets), WEP_CVAR_PRI(shotgun, spread), + WEP_CVAR_PRI(shotgun, spread_pattern), + WEP_CVAR_PRI(shotgun, spread_pattern_scale), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, force), WEP_CVAR_PRI(shotgun, damagefalloff_forcehalflife), @@ -245,6 +276,8 @@ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentit WEP_CVAR_PRI(shotgun, damagefalloff_maxdist), WEP_CVAR_PRI(shotgun, bullets), WEP_CVAR_PRI(shotgun, spread), + WEP_CVAR_PRI(shotgun, spread_pattern), + WEP_CVAR_PRI(shotgun, spread_pattern_scale), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, force), WEP_CVAR_PRI(shotgun, damagefalloff_forcehalflife), @@ -269,6 +302,8 @@ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentit WEP_CVAR_PRI(shotgun, damagefalloff_maxdist), WEP_CVAR_PRI(shotgun, bullets), WEP_CVAR_PRI(shotgun, spread), + WEP_CVAR_PRI(shotgun, spread_pattern), + WEP_CVAR_PRI(shotgun, spread_pattern_scale), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, force), WEP_CVAR_PRI(shotgun, damagefalloff_forcehalflife), diff --git a/qcsrc/common/weapons/weapon/shotgun.qh b/qcsrc/common/weapons/weapon/shotgun.qh index ca30189fa..8f78e72b6 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qh +++ b/qcsrc/common/weapons/weapon/shotgun.qh @@ -43,18 +43,20 @@ CLASS(Shotgun, Weapon) P(class, prefix, melee_traces, float, SEC) \ P(class, prefix, refire, float, BOTH) \ P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ P(class, prefix, secondary, float, NONE) \ P(class, prefix, solidpenetration, float, PRI) \ P(class, prefix, spread, float, PRI) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string,NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, spread_pattern, float, PRI) \ + P(class, prefix, spread_pattern_scale, float, PRI) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, weaponreplace, string,NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Shotgun, shotgun) + W_PROPS(X, Shotgun, shotgun) #undef X ENDCLASS(Shotgun) -- 2.39.2