From: Mario Date: Mon, 27 Jul 2020 03:22:55 +0000 (+0000) Subject: Merge branch 'Mario/headshots' into 'master' X-Git-Tag: xonotic-v0.8.5~829 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=59d3684c3ce95d95c6d3f14e6fc5567a2e6ff2ba;hp=bd21a4132197b9f76d00278cc629771725047ad6 Merge branch 'Mario/headshots' into 'master' Merge branch Mario/headshots (S merge request) See merge request xonotic/xonotic-data.pk3dir!839 --- diff --git a/bal-wep-mario.cfg b/bal-wep-mario.cfg index 5cfa34882b..52dfc5f12c 100644 --- a/bal-wep-mario.cfg +++ b/bal-wep-mario.cfg @@ -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 diff --git a/bal-wep-nexuiz25.cfg b/bal-wep-nexuiz25.cfg index f9659814b3..7bc8de485d 100644 --- a/bal-wep-nexuiz25.cfg +++ b/bal-wep-nexuiz25.cfg @@ -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 diff --git a/bal-wep-samual.cfg b/bal-wep-samual.cfg index 6896f5f5e0..a89f480215 100644 --- a/bal-wep-samual.cfg +++ b/bal-wep-samual.cfg @@ -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 diff --git a/bal-wep-xdf.cfg b/bal-wep-xdf.cfg index ec8029c74b..007a36cf56 100644 --- a/bal-wep-xdf.cfg +++ b/bal-wep-xdf.cfg @@ -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 diff --git a/bal-wep-xonotic.cfg b/bal-wep-xonotic.cfg index c38ea832f3..2f7b598b73 100644 --- a/bal-wep-xonotic.cfg +++ b/bal-wep-xonotic.cfg @@ -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 diff --git a/notifications.cfg b/notifications.cfg index 41f0706ea3..10f2f8b030 100644 --- a/notifications.cfg +++ b/notifications.cfg @@ -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" diff --git a/qcsrc/common/mutators/mutator/overkill/okhmg.qc b/qcsrc/common/mutators/mutator/overkill/okhmg.qc index 51b3c05d9c..31db0c4db9 100644 --- a/qcsrc/common/mutators/mutator/overkill/okhmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/okhmg.qc @@ -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; diff --git a/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc b/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc index b64af05f76..9ce9a29018 100644 --- a/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc +++ b/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc @@ -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; diff --git a/qcsrc/common/mutators/mutator/overkill/oknex.qc b/qcsrc/common/mutators/mutator/overkill/oknex.qc index ca44a070a0..55afbe45c1 100644 --- a/qcsrc/common/mutators/mutator/overkill/oknex.qc +++ b/qcsrc/common/mutators/mutator/overkill/oknex.qc @@ -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); diff --git a/qcsrc/common/notifications/all.inc b/qcsrc/common/notifications/all.inc index a9a2ee6551..2c6a16d88f 100644 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@ -111,6 +111,8 @@ 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) diff --git a/qcsrc/common/turrets/turret/machinegun_weapon.qc b/qcsrc/common/turrets/turret/machinegun_weapon.qc index 38a74c8e94..9d4ff22946 100644 --- a/qcsrc/common/turrets/turret/machinegun_weapon.qc +++ b/qcsrc/common/turrets/turret/machinegun_weapon.qc @@ -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"); } diff --git a/qcsrc/common/turrets/turret/plasma.qc b/qcsrc/common/turrets/turret/plasma.qc index 89ddfbd4f1..98426c9c33 100644 --- a/qcsrc/common/turrets/turret/plasma.qc +++ b/qcsrc/common/turrets/turret/plasma.qc @@ -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); diff --git a/qcsrc/common/turrets/turret/plasma_dual.qc b/qcsrc/common/turrets/turret/plasma_dual.qc index 9fa10eefff..1aee6f5c4a 100644 --- a/qcsrc/common/turrets/turret/plasma_dual.qc +++ b/qcsrc/common/turrets/turret/plasma_dual.qc @@ -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); diff --git a/qcsrc/common/turrets/turret/walker_weapon.qc b/qcsrc/common/turrets/turret/walker_weapon.qc index bbe59aeac9..c16d130142 100644 --- a/qcsrc/common/turrets/turret/walker_weapon.qc +++ b/qcsrc/common/turrets/turret/walker_weapon.qc @@ -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); } } diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index ca72ec1b23..e031222714 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 77c99d16dd..684ae22bc7 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 456e79c031..9f4bdc15e6 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -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; diff --git a/qcsrc/common/weapons/weapon/rifle.qh b/qcsrc/common/weapons/weapon/rifle.qh index 679a3fb0cd..7a2348af74 100644 --- a/qcsrc/common/weapons/weapon/rifle.qh +++ b/qcsrc/common/weapons/weapon/rifle.qh @@ -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) \ diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 8928ec21c1..3e25800cce 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index 918eeb84c9..57668782f1 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index bf179e374d..5a1cd1a920 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -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); diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh index c61dc1e716..1ec27a7818 100644 --- a/qcsrc/server/miscfunctions.qh +++ b/qcsrc/server/miscfunctions.qh @@ -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); diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index 3259523f07..ef1b6bd68d 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -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); } diff --git a/qcsrc/server/weapons/tracing.qh b/qcsrc/server/weapons/tracing.qh index 94bd5b503c..e2f43fb7c1 100644 --- a/qcsrc/server/weapons/tracing.qh +++ b/qcsrc/server/weapons/tracing.qh @@ -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);