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
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
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
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
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
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
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
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
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
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
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),
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) \
}
#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;
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);
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;
}
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);
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;
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);
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);
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);
}
}
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),
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),
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),
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),
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)