From b7fed872ffc25b178eaaeeffc02b5988f20cebc7 Mon Sep 17 00:00:00 2001 From: sajt Date: Wed, 15 Mar 2006 02:20:11 +0000 Subject: [PATCH] Stuff now shoots out of what appears to be the actual muzzles of the weapons. I modified all the weapons except the Nex, because I'm not sure what the heck's going on with that one. (I think it works already anyway) Bug: Trueaim when you're near a wall looks BAD (bullets leaving the gun at near-90 degree angles). Usually you don't notice it, but with the shotgun you will see a very strange bullethole pattern. git-svn-id: svn://svn.icculus.org/nexuiz/trunk@1162 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/gamec/cl_weaponsystem.c | 47 +++++++++++++-------- data/qcsrc/server/gamec/defs.h | 1 - data/qcsrc/server/gamec/w_crylink.c | 12 +++--- data/qcsrc/server/gamec/w_electro.c | 18 ++++---- data/qcsrc/server/gamec/w_grenadelauncher.c | 12 ++---- data/qcsrc/server/gamec/w_hagar.c | 12 ++---- data/qcsrc/server/gamec/w_laser.c | 5 +-- data/qcsrc/server/gamec/w_nex.c | 3 +- data/qcsrc/server/gamec/w_rocketlauncher.c | 6 +-- data/qcsrc/server/gamec/w_shotgun.c | 32 ++++++-------- data/qcsrc/server/gamec/w_uzi.c | 20 ++++----- 11 files changed, 81 insertions(+), 87 deletions(-) diff --git a/data/qcsrc/server/gamec/cl_weaponsystem.c b/data/qcsrc/server/gamec/cl_weaponsystem.c index cc1342b12..b41bc9fbb 100644 --- a/data/qcsrc/server/gamec/cl_weaponsystem.c +++ b/data/qcsrc/server/gamec/cl_weaponsystem.c @@ -27,6 +27,36 @@ vector() W_TrueAim = { return trace_endpos; } +// this function allows you to spawn projectiles ahead of the player so they appear to come out of +// the muzzle properly, but won't put shots inside walls if you're too close. +// make sure you call makevectors first (FIXME?) +vector W_MuzzleOrigin (entity ent, vector vecs) +{ + vector startorg; + vector idealorg; + + startorg = ent.origin + ent.view_ofs - '0 0 8'; + idealorg = ent.origin + ent.view_ofs + v_forward * vecs_x + v_right * vecs_y + v_up * vecs_z; + + traceline_hitcorpse (ent, startorg, idealorg, MOVE_NORMAL, ent); + +// if obstructed, back off a bit so the shot will definitely hit it + if (trace_fraction < 1.0) + { + // FIXME! this whole thing messes up W_TrueAim... if you're up against a wall, the trueaim and the muzzle + // origin will be about the same distance from the player, causing the bullets to fly out at a near 90 + // degree angle +// trace_endpos = trace_endpos - normalize (idealorg - startorg); + + + // nasty placeholder (well I admit you don't really notice it all... especially since the + // weapon model sinking into the wall provides such a nice distraction) + trace_endpos = startorg; + } + + return trace_endpos; +} + void LaserTarget_Think() { entity e; @@ -286,15 +316,6 @@ void(float windex, string wmodel, float hudammo) weapon_setup = // CL_ViswepUpdate(); }; -// shot direction -float WEAPON_MAXRELX = 14; // if more, shot can be spawned after wall surface (in empty worldspace) or inside other entity if client stands close to it -void(float x, float y, float z) weapon_shotdir = -{ - makevectors(self.v_angle); - self.shotorg = self.origin + self.view_ofs + v_forward*bound(0, x, WEAPON_MAXRELX) + v_right*(y + self.weaponentity.view_ofs_y) + v_up*z; - self.shotdir = aim(self, 1000); -}; - // perform weapon to attack (weaponstate and attack_finished check is here) void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack = { @@ -339,14 +360,6 @@ void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now }; -void(entity ent, float recoil) weapon_recoil = -{ - ent.punchangle = (randomvec() + '-1 0 0')*recoil; - ent.punchangle_z = 0; // don't want roll - if (recoil > 3) // push back if large recoil - ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25; -}; - void(float fr, float t, void() func) weapon_thinkf = { if (fr >= 0) diff --git a/data/qcsrc/server/gamec/defs.h b/data/qcsrc/server/gamec/defs.h index 3cfb59c83..1aabeab45 100644 --- a/data/qcsrc/server/gamec/defs.h +++ b/data/qcsrc/server/gamec/defs.h @@ -116,7 +116,6 @@ void() w_clear; // VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies) .float weapon_nextthink; .void() weapon_think; -.vector shotdir, shotorg; // new generic aiming system for all weapons (not finished yet, can be removed) float weapon_hasammo; // sets by WR_CHECKAMMO request //float PLAYER_WEAPONSELECTION_DELAY = ); diff --git a/data/qcsrc/server/gamec/w_crylink.c b/data/qcsrc/server/gamec/w_crylink.c index 7eb35794c..7884a6366 100644 --- a/data/qcsrc/server/gamec/w_crylink.c +++ b/data/qcsrc/server/gamec/w_crylink.c @@ -98,14 +98,14 @@ void W_Crylink_Attack (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/crylink_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition")) self.ammo_cells = self.ammo_cells - cvar("g_balance_crylink_primary_ammo"); self.punchangle_x = -2; - org = self.origin + self.view_ofs + v_forward * 10 + v_right * 5 + v_up * -14; + + org = W_MuzzleOrigin (self, '24 7 -8'); te_smallflash(org); shots = cvar("g_balance_crylink_primary_shots"); @@ -148,14 +148,14 @@ void W_Crylink_Attack2 (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/crylink_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition")) self.ammo_cells = self.ammo_cells - cvar("g_balance_crylink_secondary_ammo"); self.punchangle_x = -2; - org = self.origin + self.view_ofs + v_forward * 10 + v_right * 5 + v_up * -14; + + org = W_MuzzleOrigin (self, '20 7 -8'); te_smallflash(org); shots = cvar("g_balance_crylink_secondary_shots"); diff --git a/data/qcsrc/server/gamec/w_electro.c b/data/qcsrc/server/gamec/w_electro.c index 8f5b57417..970ce9ced 100644 --- a/data/qcsrc/server/gamec/w_electro.c +++ b/data/qcsrc/server/gamec/w_electro.c @@ -109,26 +109,25 @@ void() W_Electro_Attack postion = self.electrocount; sound (self, CHAN_WEAPON, "weapons/electro_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } self.punchangle_x = -2; if (self.electrocount == 0) { self.electrocount = 1; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -14; + org = W_MuzzleOrigin (self, '24 6 -9'); } else if (self.electrocount == 1) { self.electrocount = 2; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 10 + v_up * -12; + org = W_MuzzleOrigin (self, '24 8 -7'); } else { self.electrocount = 0; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 15 + v_up * -14; + org = W_MuzzleOrigin (self, '24 10 -9'); } proj = spawn (); @@ -160,26 +159,25 @@ void() W_Electro_Attack2 postion = self.electrocount; sound (self, CHAN_WEAPON, "weapons/electro_fire2.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } self.punchangle_x = -2; if (self.electrocount == 0) { self.electrocount = 1; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -14; + org = W_MuzzleOrigin (self, '24 6 -12'); } else if (self.electrocount == 1) { self.electrocount = 2; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 10 + v_up * -12; + org = W_MuzzleOrigin (self, '24 8 -10'); } else { self.electrocount = 0; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 15 + v_up * -14; + org = W_MuzzleOrigin (self, '24 10 -12'); } proj = spawn (); diff --git a/data/qcsrc/server/gamec/w_grenadelauncher.c b/data/qcsrc/server/gamec/w_grenadelauncher.c index 25593d9d8..fe4ff22dd 100644 --- a/data/qcsrc/server/gamec/w_grenadelauncher.c +++ b/data/qcsrc/server/gamec/w_grenadelauncher.c @@ -89,16 +89,14 @@ void W_Grenade_Attack (void) local entity gren; local vector org; - sound (self, CHAN_WEAPON, "weapons/grenade_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } self.punchangle_x = -4; if (cvar("g_use_ammunition")) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_grenadelauncher_primary_ammo"); - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -12; + org = W_MuzzleOrigin (self, '24 8 -8'); gren = spawn (); gren.owner = self; @@ -124,16 +122,14 @@ void W_Grenade_Attack2 (void) local entity gren; local vector org; - sound (self, CHAN_WEAPON, "weapons/grenade_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } self.punchangle_x = -4; if (cvar("g_use_ammunition")) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_grenadelauncher_secondary_ammo"); - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -12; + org = W_MuzzleOrigin (self, '24 8 -8'); gren = spawn (); gren.owner = self; diff --git a/data/qcsrc/server/gamec/w_hagar.c b/data/qcsrc/server/gamec/w_hagar.c index 219454553..8caac7272 100644 --- a/data/qcsrc/server/gamec/w_hagar.c +++ b/data/qcsrc/server/gamec/w_hagar.c @@ -108,16 +108,14 @@ void W_Hagar_Attack (void) local vector trueaim; trueaim = W_TrueAim(); - sound (self, CHAN_WEAPON, "weapons/hagar_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition")) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_hagar_primary_ammo"); self.punchangle_x = -2; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -8; + org = W_MuzzleOrigin (self, '18 5 -8'); missile = spawn (); missile.owner = self; @@ -150,16 +148,14 @@ void W_Hagar_Attack2 (void) local vector trueaim; trueaim = W_TrueAim(); - sound (self, CHAN_WEAPON, "weapons/hagar_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition")) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_hagar_secondary_ammo"); self.punchangle_x = -2; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -8; + org = W_MuzzleOrigin (self, '18 5 -8'); missile = spawn (); missile.owner = self; diff --git a/data/qcsrc/server/gamec/w_laser.c b/data/qcsrc/server/gamec/w_laser.c index 5d6746cc6..18d93cace 100644 --- a/data/qcsrc/server/gamec/w_laser.c +++ b/data/qcsrc/server/gamec/w_laser.c @@ -72,11 +72,10 @@ void W_Laser_Attack (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/lasergun_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -12; + org = W_MuzzleOrigin (self, '24 9 -9'); //te_customflash(org, 160, 0.2, '1 0 0'); missile = spawn (); diff --git a/data/qcsrc/server/gamec/w_nex.c b/data/qcsrc/server/gamec/w_nex.c index 39822d1d9..83a60f33f 100644 --- a/data/qcsrc/server/gamec/w_nex.c +++ b/data/qcsrc/server/gamec/w_nex.c @@ -126,9 +126,8 @@ void W_Nex_Attack (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/nexfire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH && !cvar("g_minstagib")) { + if (self.items & IT_STRENGTH && !cvar("g_minstagib")) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } self.punchangle_x = -5; diff --git a/data/qcsrc/server/gamec/w_rocketlauncher.c b/data/qcsrc/server/gamec/w_rocketlauncher.c index 55dc2aac1..06f17640e 100644 --- a/data/qcsrc/server/gamec/w_rocketlauncher.c +++ b/data/qcsrc/server/gamec/w_rocketlauncher.c @@ -228,14 +228,14 @@ void W_Rocket_Attack (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/rocket_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition") && !cvar("g_rocketarena")) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_rocketlauncher_ammo"); self.punchangle_x = -4; - org = self.origin + self.view_ofs + v_forward * 15 + v_right * 3 + v_up * -11; + + org = W_MuzzleOrigin (self, '15 3 -11'); te_smallflash(org); missile = spawn (); diff --git a/data/qcsrc/server/gamec/w_shotgun.c b/data/qcsrc/server/gamec/w_shotgun.c index 54437c499..189b08c76 100644 --- a/data/qcsrc/server/gamec/w_shotgun.c +++ b/data/qcsrc/server/gamec/w_shotgun.c @@ -50,31 +50,29 @@ void W_Shotgun_Attack (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/shotgun_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } bullets = cvar("g_balance_shotgun_primary_bullets"); d = cvar("g_balance_shotgun_primary_damage"); - - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 5); spread = cvar("g_balance_shotgun_primary_spread"); + + org = W_MuzzleOrigin (self, '26 9 -10'); for (sc = 0;sc < bullets;sc = sc + 1) fireBullet (org, normalize(trueaim - org), spread, d, IT_SHOTGUN, sc < 3); if (cvar("g_use_ammunition")) self.ammo_shells = self.ammo_shells - cvar("g_balance_shotgun_primary_ammo"); + W_Smoke(org, v_forward, 12); + //te_smallflash(org); + // casing code if (cvar("g_casings") >= 1) { - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 10); + org = W_MuzzleOrigin (self, '10 10 -8'); SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 1); } - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 20); - W_Smoke(org, v_forward, 12); - //te_smallflash(org); - self.punchangle_x = -5; } @@ -90,31 +88,29 @@ void W_Shotgun_Attack2 (void) trueaim = W_TrueAim(); sound (self, CHAN_WEAPON, "weapons/shotgun_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } bullets = cvar("g_balance_shotgun_secondary_bullets"); d = cvar("g_balance_shotgun_secondary_damage"); - - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 5); spread = cvar("g_balance_shotgun_secondary_spread"); + + org = W_MuzzleOrigin (self, '26 9 -10'); for (sc = 0;sc < bullets;sc = sc + 1) fireBullet (org, normalize(trueaim - org), spread, d, IT_SHOTGUN, sc < 3); if (cvar("g_use_ammunition")) self.ammo_shells = self.ammo_shells - cvar("g_balance_shotgun_secondary_ammo"); + W_Smoke(org, v_forward, 12); + //te_smallflash(org); + // casing code if (cvar("g_casings") >= 1) { - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 10); + org = W_MuzzleOrigin (self, '10 10 -8'); SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 1); } - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 20); - W_Smoke(org, v_forward, 12); - //te_smallflash(org); - self.punchangle_x = -5; } diff --git a/data/qcsrc/server/gamec/w_uzi.c b/data/qcsrc/server/gamec/w_uzi.c index f694a8c20..038e9f2f5 100644 --- a/data/qcsrc/server/gamec/w_uzi.c +++ b/data/qcsrc/server/gamec/w_uzi.c @@ -45,9 +45,8 @@ void W_Uzi_Attack (void) entity flash; sound (self, CHAN_WEAPON, "weapons/uzi_fire.ogg", 1, ATTN_NORM); - if (self.items & IT_STRENGTH) { + if (self.items & IT_STRENGTH) sound (self, CHAN_AUTO, "weapons/strength_fire.ogg", 1, ATTN_NORM); - } if (cvar("g_use_ammunition")) { @@ -58,7 +57,7 @@ void W_Uzi_Attack (void) } self.punchangle_x = random () - 0.5; self.punchangle_y = random () - 0.5; - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 15); + org = W_MuzzleOrigin (self, '32 6 -8'); // this attack_finished just enforces a cooldown at the end of a burst self.attack_finished = time + cvar("g_balance_uzi_first_refire"); @@ -68,15 +67,8 @@ void W_Uzi_Attack (void) else fireBullet (org, normalize(trueaim - org), cvar("g_balance_uzi_sustained_spread"), cvar("g_balance_uzi_sustained_damage"), IT_UZI, (self.uzi_bulletcounter & 3) == 0); - // casing code - if (cvar("g_casings") >= 2) - { - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 8) + (v_forward * 10); - SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 2); - } - flash = spawn (); - org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 10) + (v_forward * 40); +// org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 10) + (v_forward * 40); setorigin (flash, org); setmodel (flash, "models/uziflash.md3"); flash.velocity = v_forward * 20; @@ -87,6 +79,12 @@ void W_Uzi_Attack (void) SUB_SetFade (flash, time, 0.2); flash.effects = flash.effects | EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION; + // casing code + if (cvar("g_casings") >= 2) + { + org = W_MuzzleOrigin (self, '10 6 -8'); + SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 2); + } } // weapon frames -- 2.39.2