Merge branch 'Mario/headshots' into 'master'
authorMario <mario.mario@y7mail.com>
Mon, 27 Jul 2020 03:22:55 +0000 (03:22 +0000)
committerMario <mario.mario@y7mail.com>
Mon, 27 Jul 2020 03:22:55 +0000 (03:22 +0000)
Merge branch Mario/headshots (S merge request)

See merge request xonotic/xonotic-data.pk3dir!839

24 files changed:
bal-wep-mario.cfg
bal-wep-nexuiz25.cfg
bal-wep-samual.cfg
bal-wep-xdf.cfg
bal-wep-xonotic.cfg
notifications.cfg
qcsrc/common/mutators/mutator/overkill/okhmg.qc
qcsrc/common/mutators/mutator/overkill/okmachinegun.qc
qcsrc/common/mutators/mutator/overkill/oknex.qc
qcsrc/common/notifications/all.inc
qcsrc/common/turrets/turret/machinegun_weapon.qc
qcsrc/common/turrets/turret/plasma.qc
qcsrc/common/turrets/turret/plasma_dual.qc
qcsrc/common/turrets/turret/walker_weapon.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/rifle.qh
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/tracing.qh

index 5cfa34882b2710471c8e0a44157dda9feff17eb5..52dfc5f12ca507fcf15c621d2c24514468572dff 100644 (file)
@@ -557,6 +557,7 @@ set g_balance_rifle_primary_bullethail 0
 set g_balance_rifle_primary_burstcost 0
 set g_balance_rifle_primary_damage 80
 set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_headshot_multiplier 0
 set g_balance_rifle_primary_refire 1.2
 set g_balance_rifle_primary_shots 1
 set g_balance_rifle_primary_solidpenetration 62.2
@@ -571,6 +572,7 @@ set g_balance_rifle_secondary_bullethail 0
 set g_balance_rifle_secondary_burstcost 0
 set g_balance_rifle_secondary_damage 20
 set g_balance_rifle_secondary_force 50
+set g_balance_rifle_secondary_headshot_multiplier 0
 set g_balance_rifle_secondary_refire 0.9
 set g_balance_rifle_secondary_reload 0
 set g_balance_rifle_secondary_shots 4
index f9659814b3ea91d425b172095dbc9c264a2e5418..7bc8de485d6c5943c0b4c965cd4406909a246f79 100644 (file)
@@ -557,6 +557,7 @@ set g_balance_rifle_primary_bullethail 0
 set g_balance_rifle_primary_burstcost 0
 set g_balance_rifle_primary_damage 80
 set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_headshot_multiplier 1.25
 set g_balance_rifle_primary_refire 1.2
 set g_balance_rifle_primary_shots 1
 set g_balance_rifle_primary_solidpenetration 62.2
@@ -571,6 +572,7 @@ set g_balance_rifle_secondary_bullethail 0
 set g_balance_rifle_secondary_burstcost 0
 set g_balance_rifle_secondary_damage 20
 set g_balance_rifle_secondary_force 50
+set g_balance_rifle_secondary_headshot_multiplier 0.1875
 set g_balance_rifle_secondary_refire 0.9
 set g_balance_rifle_secondary_reload 0
 set g_balance_rifle_secondary_shots 4
index 6896f5f5e0be99131c379ea538b28a0ff7e3b252..a89f480215ae56c7d4abf98be80d6a7302dd6b08 100644 (file)
@@ -557,6 +557,7 @@ set g_balance_rifle_primary_bullethail 0
 set g_balance_rifle_primary_burstcost 0
 set g_balance_rifle_primary_damage 80
 set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_headshot_multiplier 0
 set g_balance_rifle_primary_refire 1.2
 set g_balance_rifle_primary_shots 1
 set g_balance_rifle_primary_solidpenetration 62.2
@@ -570,6 +571,7 @@ set g_balance_rifle_secondary_animtime 0.3
 set g_balance_rifle_secondary_bullethail 0
 set g_balance_rifle_secondary_burstcost 0
 set g_balance_rifle_secondary_damage 20
+set g_balance_rifle_secondary_headshot_multiplier 0
 set g_balance_rifle_secondary_force 50
 set g_balance_rifle_secondary_refire 0.9
 set g_balance_rifle_secondary_reload 0
index ec8029c74bf28647cae83bf57d806178f6120640..007a36cf56e217c29d8fa749dbcf166f8bcbe29c 100644 (file)
@@ -557,6 +557,7 @@ set g_balance_rifle_primary_bullethail 0
 set g_balance_rifle_primary_burstcost 0
 set g_balance_rifle_primary_damage 80
 set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_headshot_multiplier 0
 set g_balance_rifle_primary_refire 1.2
 set g_balance_rifle_primary_shots 1
 set g_balance_rifle_primary_solidpenetration 62.2
@@ -571,6 +572,7 @@ set g_balance_rifle_secondary_bullethail 0
 set g_balance_rifle_secondary_burstcost 0
 set g_balance_rifle_secondary_damage 20
 set g_balance_rifle_secondary_force 50
+set g_balance_rifle_secondary_headshot_multiplier 0
 set g_balance_rifle_secondary_refire 0.9
 set g_balance_rifle_secondary_reload 0
 set g_balance_rifle_secondary_shots 4
index c38ea832f3e2c53576a9cd2d9c15538d81ca1633..2f7b598b739e6d4664c284c7468fc23d36f11e8a 100644 (file)
@@ -557,6 +557,7 @@ set g_balance_rifle_primary_bullethail 0
 set g_balance_rifle_primary_burstcost 0
 set g_balance_rifle_primary_damage 80
 set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_headshot_multiplier 0
 set g_balance_rifle_primary_refire 1.2
 set g_balance_rifle_primary_shots 1
 set g_balance_rifle_primary_solidpenetration 62.2
@@ -570,6 +571,7 @@ set g_balance_rifle_secondary_animtime 0.3
 set g_balance_rifle_secondary_bullethail 0
 set g_balance_rifle_secondary_burstcost 0
 set g_balance_rifle_secondary_damage 20
+set g_balance_rifle_secondary_headshot_multiplier 0
 set g_balance_rifle_secondary_force 50
 set g_balance_rifle_secondary_refire 0.9
 set g_balance_rifle_secondary_reload 0
index 41f0706ea3d72f95c1d2b4180c3a27d5dd6232ad..10f2f8b03049f4ba921c48f5465322b6eeff41a3 100644 (file)
@@ -20,6 +20,7 @@ seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "0 = disabled, 1 = enabled
 seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 seta notification_ANNCE_ACHIEVEMENT_YODA "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 seta notification_ANNCE_BEGIN "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_HEADSHOT "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 seta notification_ANNCE_INSTAGIB_LASTSECOND "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 seta notification_ANNCE_INSTAGIB_NARROWLY "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 seta notification_ANNCE_INSTAGIB_TERMINATED "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
index 51b3c05d9cf757638a54837e9aa9b6a66a1ecac4..31db0c4db92e2663a54f0b3a9f0069220a8848a8 100644 (file)
@@ -36,7 +36,7 @@ void W_OverkillHeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity
        }
 
        float okhmg_spread = bound(WEP_CVAR_PRI(okhmg, spread_min), WEP_CVAR_PRI(okhmg, spread_min) + (WEP_CVAR_PRI(okhmg, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR_PRI(okhmg, spread_max));
-       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, okhmg_spread, WEP_CVAR_PRI(okhmg, solidpenetration), WEP_CVAR_PRI(okhmg, damage), WEP_CVAR_PRI(okhmg, force), WEP_OVERKILL_HMG.m_id, EFFECT_RIFLE);
+       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, okhmg_spread, WEP_CVAR_PRI(okhmg, solidpenetration), WEP_CVAR_PRI(okhmg, damage), 0, WEP_CVAR_PRI(okhmg, force), WEP_OVERKILL_HMG.m_id, EFFECT_RIFLE);
 
        actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
 
index b64af05f766a719632fd7411decc38170662c22f..9ce9a2901856e313dd6d2c07f06f3412fb6a7e7d 100644 (file)
@@ -30,7 +30,7 @@ void W_OverkillMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weap
        }
 
        okmachinegun_spread = bound(WEP_CVAR_PRI(okmachinegun, spread_min), WEP_CVAR_PRI(okmachinegun, spread_min) + (WEP_CVAR_PRI(okmachinegun, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR_PRI(okmachinegun, spread_max));
-       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, okmachinegun_spread, WEP_CVAR_PRI(okmachinegun, solidpenetration), WEP_CVAR_PRI(okmachinegun, damage), WEP_CVAR_PRI(okmachinegun, force), WEP_OVERKILL_MACHINEGUN.m_id, EFFECT_RIFLE);
+       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, okmachinegun_spread, WEP_CVAR_PRI(okmachinegun, solidpenetration), WEP_CVAR_PRI(okmachinegun, damage), 0, WEP_CVAR_PRI(okmachinegun, force), WEP_OVERKILL_MACHINEGUN.m_id, EFFECT_RIFLE);
 
        actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
 
index ca44a070a0cf99c2db176642d49cd07efaa34bfc..55afbe45c1112e4f2fdf04632f62dd71becdbbb5 100644 (file)
@@ -95,7 +95,7 @@ void W_OverkillNex_Attack(Weapon thiswep, entity actor, .entity weaponentity, fl
 
        yoda = 0;
        damage_goodhits = 0;
-       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, thiswep.m_id);
+       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, true, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, thiswep.m_id);
 
        if(yoda && flying)
                Send_Notification(NOTIF_ONE, actor, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
index a9a2ee655139555dfc70bb72ae875d9fc2061a28..2c6a16d88f81b90d4b984c43effc5f663f70dcfd 100644 (file)
 
     MSG_ANNCE_NOTIF(BEGIN,                      N__ALWAYS, "begin",             CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
 
+    MSG_ANNCE_NOTIF(HEADSHOT,                   N__ALWAYS, "headshot",          CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+
     MSG_ANNCE_NOTIF(KILLSTREAK_03,              N_GNTLOFF, "03kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(KILLSTREAK_05,              N_GNTLOFF, "05kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(KILLSTREAK_10,              N_GNTLOFF, "10kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
index 38a74c8e9481f0e84e70f5dff0575703367f371a..9d4ff22946a860be5b45d35e8ed09564510553f3 100644 (file)
@@ -17,7 +17,7 @@ METHOD(MachineGunTurretAttack, wr_think, void(entity thiswep, entity actor, .ent
             actor.tur_head = actor;
             weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
         }
-        fireBullet(actor, weaponentity, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_MACHINEGUN.m_id, EFFECT_BULLET);
+        fireBullet(actor, weaponentity, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, 0, actor.shot_force, DEATH_TURRET_MACHINEGUN.m_id, EFFECT_BULLET);
         W_MuzzleFlash_Model(actor.(weaponentity), MDL_MACHINEGUN_MUZZLEFLASH);
         setattachment(actor.(weaponentity).muzzle_flash, actor.tur_head, "tag_fire");
     }
index 89ddfbd4f1ca6a28df7f9d45339b016d01923144..98426c9c33ef7b3bf43850099bc29a98101513dd 100644 (file)
@@ -9,7 +9,7 @@ METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this, entity it))
     if(MUTATOR_IS_ENABLED(mutator_instagib))
     {
         .entity weaponentity = weaponentities[0]; // TODO: unhardcode
-        FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000,
+        FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000, false,
                            800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id);
 
         Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, it.tur_shotorg, it.tur_shotdir_updated * 1000, 1);
index 9fa10eefff01e8a2c7cf0a9cbd305014f7be13e4..1aee6f5c4a501e53cdc9eebf331678568a9a3a37 100644 (file)
@@ -8,7 +8,7 @@ METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur, entity it))
 {
     if (MUTATOR_IS_ENABLED(mutator_instagib)) {
         .entity weaponentity = weaponentities[0]; // TODO: unhardcode
-        FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000,
+        FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000, false,
                            800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id);
 
 
index bbe59aeac90aeca4980be687fb8257eb60ae545e..c16d130142056cf0da5e8ec9cec6c8b0d2cc6435 100644 (file)
@@ -16,7 +16,7 @@ METHOD(WalkerTurretAttack, wr_think, void(entity thiswep, entity actor, .entity
             weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
         }
         sound (actor, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
-        fireBullet(actor, weaponentity, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_WALK_GUN.m_id, EFFECT_BULLET);
+        fireBullet(actor, weaponentity, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, 0, actor.shot_force, DEATH_TURRET_WALK_GUN.m_id, EFFECT_BULLET);
         Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, actor.tur_shotorg, actor.tur_shotdir_updated * 1000, 1);
     }
 }
index ca72ec1b23b034658bcb8617a9e60a2f9a4c9a21..e031222714e7b758496115675dbf3ed23b2c6846 100644 (file)
@@ -266,7 +266,7 @@ bool spiderbot_frame(entity this, float dt)
 
                        .entity weaponentity = weaponentities[0]; // TODO: unhardcode
                        fireBullet(this, weaponentity, v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_solidpenetration,
-                               autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN.m_id, EFFECT_BULLET);
+                               autocvar_g_vehicle_spiderbot_minigun_damage, 0, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN.m_id, EFFECT_BULLET);
 
                        sound (gun, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
                        //trailparticles(this, _particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
index 77c99d16dd620de81cb3b7fc40ada87fca572b14..684ae22bc740858542996ce53647b45491b23ab8 100644 (file)
@@ -14,9 +14,9 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity we
        ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(actor);
 
        if(actor.(weaponentity).misc_bulletcounter == 1)
-               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, first_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, first_damage), WEP_CVAR(machinegun, first_force), deathtype, EFFECT_BULLET);
+               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, first_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, first_damage), 0, WEP_CVAR(machinegun, first_force), deathtype, EFFECT_BULLET);
        else
-               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, sustained_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), deathtype, EFFECT_BULLET);
+               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, sustained_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), 0, WEP_CVAR(machinegun, sustained_force), deathtype, EFFECT_BULLET);
 
        W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
 
@@ -87,7 +87,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
        }
 
        machinegun_spread = bound(WEP_CVAR(machinegun, spread_min), WEP_CVAR(machinegun, spread_min) + (WEP_CVAR(machinegun, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR(machinegun, spread_max));
-       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), thiswep.m_id, EFFECT_BULLET);
+       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), 0, WEP_CVAR(machinegun, sustained_force), thiswep.m_id, EFFECT_BULLET);
 
        actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
 
@@ -112,7 +112,7 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit
                actor.punchangle_y = random() - 0.5;
        }
 
-       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), thiswep.m_id, EFFECT_BULLET);
+       fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), 0, WEP_CVAR(machinegun, sustained_force), thiswep.m_id, EFFECT_BULLET);
 
        W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
 
index 456e79c0319320f34da47fecfb0c4ebd5c2aca77..9f4bdc15e63d1ba3c6ef9e14177ce084952f97d7 100644 (file)
@@ -2,7 +2,7 @@
 
 #ifdef SVQC
 
-void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, Sound pSound, entity actor)
+void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, float pDamage, float pHeadshotDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, Sound pSound, entity actor)
 {
        float i;
 
@@ -19,7 +19,7 @@ void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, flo
        }
 
        for(i = 0; i < pShots; ++i)
-               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, pSpread, pSolidPenetration, pDamage, pForce, deathtype, (pTracer ? EFFECT_RIFLE : EFFECT_RIFLE_WEAK));
+               fireBullet(actor, weaponentity, w_shotorg, w_shotdir, pSpread, pSolidPenetration, pDamage, pHeadshotDamage, pForce, deathtype, (pTracer ? EFFECT_RIFLE : EFFECT_RIFLE_WEAK));
 
        if(autocvar_g_casings >= 2)
     {
@@ -30,12 +30,12 @@ void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, flo
 
 void W_Rifle_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 {
-       W_Rifle_FireBullet(thiswep, weaponentity, WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), thiswep.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND_CAMPINGRIFLE_FIRE, actor);
+       W_Rifle_FireBullet(thiswep, weaponentity, WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, headshot_multiplier), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), thiswep.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND_CAMPINGRIFLE_FIRE, actor);
 }
 
 void W_Rifle_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
 {
-       W_Rifle_FireBullet(thiswep, weaponentity, WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), thiswep.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND_CAMPINGRIFLE_FIRE2, actor);
+       W_Rifle_FireBullet(thiswep, weaponentity, WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, headshot_multiplier), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), thiswep.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND_CAMPINGRIFLE_FIRE2, actor);
 }
 
 .void(Weapon thiswep, entity actor, .entity weaponentity) rifle_bullethail_attackfunc;
index 679a3fb0cdb271b85210be2ad6c8c25a6725a8ab..7a2348af740d78954bd6ae86e09af5f1ef1ae4a3 100644 (file)
@@ -29,6 +29,7 @@ CLASS(Rifle, Weapon)
                P(class, prefix, bursttime, float, NONE) \
                P(class, prefix, damage, float, BOTH) \
                P(class, prefix, force, float, BOTH) \
+               P(class, prefix, headshot_multiplier, float, BOTH) \
                P(class, prefix, refire, float, BOTH) \
                P(class, prefix, reload, float, SEC) \
                P(class, prefix, reload_ammo, float, NONE) \
index 8928ec21c165a0ef981ebe10d7453decc36d37e5..3e25800cce5a69119e3073358f1822ac87d4c04c 100644 (file)
@@ -26,7 +26,7 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float
                antilag_takeback_all(actor, lag);
 
        for(int sc = 0;sc < bullets;sc = sc + 1)
-               fireBullet_antilag(actor, weaponentity, w_shotorg, w_shotdir, spread, solidpenetration, damage, force, thiswep.m_id, bullet_trail_effect, false);
+               fireBullet_antilag(actor, weaponentity, w_shotorg, w_shotdir, spread, solidpenetration, damage, 0, force, thiswep.m_id, bullet_trail_effect, false);
        
        if(lag && bullets > 0)
                antilag_restore_all(actor);
index 918eeb84c9bedfbfb5c50f1ed64b3a24ab00cd36..57668782f1da5ce889aa31dc733e6e3b0ba077b8 100644 (file)
@@ -124,7 +124,7 @@ void W_Vaporizer_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 
        yoda = 0;
        damage_goodhits = 0;
-       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, vaporizer_damage, WEP_CVAR_PRI(vaporizer, force), 0, 0, 0, 0, thiswep.m_id);
+       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, vaporizer_damage, true, WEP_CVAR_PRI(vaporizer, force), 0, 0, 0, 0, thiswep.m_id);
 
        // do this now, as goodhits is disabled below
        vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
index bf179e374d3d24df2ddae085a84b33e124104765..5a1cd1a9200469c801d85576596ec7bf43117761 100644 (file)
@@ -139,7 +139,7 @@ void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float i
 
        yoda = 0;
        damage_goodhits = 0;
-       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, dtype);
+       FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, false, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, dtype);
 
        if(yoda && flying)
                Send_Notification(NOTIF_ONE, actor, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
index c61dc1e7167397925c986e13266af9adc5ea5e36..1ec27a7818a1cd900aa05f51368968051d358887 100644 (file)
@@ -39,6 +39,12 @@ void soundtoat(float _dest, entity e, vector o, float chan, string samp, float v
 
 void droptofloor(entity this);
 
+float trace_hits_box_1d(float end, float thmi, float thma);
+
+float trace_hits_box(vector start, vector end, vector thmi, vector thma);
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
+
 void attach_sameorigin(entity e, entity to, string tag);
 
 void crosshair_trace(entity pl);
index 3259523f071474ed95374282594ee255825910d5..ef1b6bd68d81880e15f018ec4217e4f3fe81b7d4 100644 (file)
@@ -211,7 +211,18 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 //  Ballistics Tracing
 // ====================
 
-void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
+bool Headshot(entity targ, entity ent, vector start, vector end)
+{
+       if(!IS_PLAYER(targ) || IS_DEAD(targ) || STAT(FROZEN, targ) || !targ.takedamage)
+               return false;
+       vector org = targ.origin; // antilag is already taken into consideration //antilag_takebackorigin(targ, CS(targ), time - ANTILAG_LATENCY(ent));
+       vector headmins = org + '0.6 0 0' * targ.mins_x + '0 0.6 0' * targ.mins_y + '0 0 1' * (1.3 * targ.view_ofs_z - 0.3 * targ.maxs_z);
+       vector headmaxs = org + '0.6 0 0' * targ.maxs_x + '0 0.6 0' * targ.maxs_y + '0 0 1' * targ.maxs_z;
+
+       return trace_hits_box(start, end, headmins, headmaxs);
+}
+
+void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
 {
        vector dir = normalize(end - start);
        vector force = dir * bforce;
@@ -220,6 +231,7 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
        end = end + dir;
 
        float totaldmg = 0;
+       bool headshot = false; // indicates that one of the targets hit was a headshot
 
        // trace multiple times until we hit a wall, each obstacle will be made
        // non-solid so we can hit the next, while doing this we spawn effects and
@@ -244,6 +256,9 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
                if (trace_ent == NULL || trace_fraction == 1)
                        break;
 
+               if(headshot_notify && !headshot && Headshot(trace_ent, this, start, end))
+                       headshot = true;
+
                // make the entity non-solid so we can hit the next one
                IL_PUSH(g_railgunhit, trace_ent);
                trace_ent.railgunhit = true;
@@ -313,6 +328,9 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
 
        IL_CLEAR(g_railgunhit);
 
+       if(headshot)
+               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
+
        // calculate hits and fired shots for hitscan
        if(this.(weaponentity))
                accuracy_add(this, this.(weaponentity).m_weapon, 0, min(bdamage, totaldmg));
@@ -330,7 +348,7 @@ void fireBullet_trace_callback(vector start, vector hit, vector end)
        fireBullet_last_hit = NULL;
 }
 
-void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect, bool do_antilag)
+void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag)
 {
        dir = normalize(dir + randomvec() * spread);
        vector end = start + dir * max_shot_distance;
@@ -353,6 +371,7 @@ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector
 
        WarpZone_trace_forent = this;
 
+       bool headshot = false; // indicates that one of the hit targets was a headshot
        for (;;)
        {
                WarpZone_TraceBox_ThroughZone(start, '0 0 0', '0 0 0', end, false, WarpZone_trace_forent, NULL, fireBullet_trace_callback);
@@ -400,6 +419,11 @@ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector
                        yoda = 0;
                        MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity));
                        damage = M_ARGV(4, float);
+                       if(headshot_multiplier && Headshot(hit, this, start, end))
+                       {
+                               damage *= headshot_multiplier;
+                               headshot = true;
+                       }
                        bool gooddamage = accuracy_isgooddamage(this, hit);
                        Damage(hit, this, this, damage * damage_fraction, dtype, weaponentity, start, force * dir * damage_fraction);
                        // calculate hits for ballistic weapons
@@ -459,6 +483,9 @@ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector
                        Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
        }
 
+       if(headshot)
+               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
+
        if(lag)
                antilag_restore_all(this);
 
@@ -467,7 +494,7 @@ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector
                this.dphitcontentsmask = oldsolid;
 }
 
-void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect)
+void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect)
 {
-       fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, force, dtype, tracer_effect, true);
+       fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
 }
index 94bd5b503ce015d2e5559fc53aae5035ed8356b8..e2f43fb7c13dfb9c2c521432318fd2a2c6210fc6 100644 (file)
@@ -64,10 +64,10 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 
 .float railgundistance;
 .vector railgunforce;
-void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype);
+void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype);
 
 entity fireBullet_trace_callback_eff;
 entity fireBullet_last_hit;
 void fireBullet_trace_callback(vector start, vector hit, vector end);
-void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect, bool do_antilag);
-void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect);
+void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag);
+void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect);