X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_weaponsystem.qc;h=4537573c5d57b28c6ed7757a4aea131bcd78d109;hp=f48f75c3ef801ef0f50285a2d3865240236889ea;hb=4fc59bbd7e2d4f25ba21952ed50ae754295a7faa;hpb=bea0e7fc9e503bb0ef95152d3f73343cc0d49e6c diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index f48f75c3e..4537573c5 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -125,14 +125,16 @@ void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright, vector w_shotorg; vector w_shotdir; +vector w_shotend; // this function calculates w_shotorg and w_shotdir based on the weapon model // offset, trueaim and antilag, and won't put w_shotorg inside a wall. // make sure you call makevectors first (FIXME?) -void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float maxdamage) +.float prevstrengthsound; +.float prevstrengthsoundattempt; +void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float maxdamage, float range) { float nudge = 1; // added to traceline target and subtracted from result - local vector trueaimpoint; local float oldsolid; vector vecs, dv; oldsolid = ent.dphitcontentsmask; @@ -141,17 +143,17 @@ void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vec else ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; if(antilag) - WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent)); + WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent)); // passing world, because we do NOT want it to touch dphitcontentsmask else - WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, ent); + WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent); ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; vector vf, vr, vu; vf = v_forward; vr = v_right; vu = v_up; - trueaimpoint = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support + w_shotend = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support v_forward = vf; v_right = vr; v_up = vu; @@ -169,17 +171,13 @@ void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vec W_HitPlotAnalysis(ent, v_forward, v_right, v_up); if(ent.weaponentity.movedir_x > 0) - { vecs = ent.weaponentity.movedir; - vecs_y = -vecs_y; - } else vecs = '0 0 0'; - if(debug_shotorg != '0 0 0') vecs = debug_shotorg; - dv = v_right * vecs_y + v_up * vecs_z; + dv = v_right * -vecs_y + v_up * vecs_z; w_shotorg = ent.origin + ent.view_ofs + dv; // now move the shotorg forward as much as requested if possible @@ -194,17 +192,17 @@ void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vec tracebox(w_shotorg, mi, ma, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent); w_shotorg = trace_endpos - v_forward * nudge; // calculate the shotdir from the chosen shotorg - w_shotdir = normalize(trueaimpoint - w_shotorg); + w_shotdir = normalize(w_shotend - w_shotorg); if (antilag) if (!ent.cvar_cl_noantilag) { if (cvar("g_antilag") == 1) // switch to "ghost" if not hitting original { - traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent); + traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent); if (!trace_ent.takedamage) { - traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent)); + traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent)); if (trace_ent.takedamage && trace_ent.classname == "player") { entity e; @@ -225,7 +223,7 @@ void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vec { // verify that the shot would miss without antilag // (avoids an issue where guns would always shoot at their origin) - traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent); + traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent); if (!trace_ent.takedamage) { // verify that the shot would hit if altered @@ -249,14 +247,28 @@ void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vec sound (ent, CHAN_WEAPON, snd, VOL_BASE, ATTN_NORM); } - if (ent.items & IT_STRENGTH) - if (!g_minstagib) - sound (ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM); + if(ent.items & IT_STRENGTH) + if(!g_minstagib) + if( + (time > ent.prevstrengthsound + cvar("sv_strengthsound_antispam_time")) + || + (time > ent.prevstrengthsoundattempt + cvar("sv_strengthsound_antispam_refire_threshold")) + ) // prevent insane sound spam + { + sound(ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM); + ent.prevstrengthsound = time; + } + ent.prevstrengthsoundattempt = time; + + // nudge w_shotend so a trace to w_shotend hits + w_shotend = w_shotend + normalize(w_shotend - w_shotorg) * nudge; }; +#define W_SetupShot_Dir_ProjectileSize(ent,s_forward,mi,ma,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize_Range(ent, s_forward, mi, ma, antilag, recoil, snd, maxdamage, MAX_SHOT_DISTANCE) #define W_SetupShot_ProjectileSize(ent,mi,ma,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize(ent, v_forward, mi, ma, antilag, recoil, snd, maxdamage) #define W_SetupShot_Dir(ent,s_forward,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize(ent, s_forward, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage) #define W_SetupShot(ent,antilag,recoil,snd,maxdamage) W_SetupShot_ProjectileSize(ent, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage) +#define W_SetupShot_Range(ent,antilag,recoil,snd,maxdamage,range) W_SetupShot_Dir_ProjectileSize_Range(ent, v_forward, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage, range) void LaserTarget_Think() { @@ -980,6 +992,13 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain) self = cl; f = weapon_action(wpn, WR_CHECKAMMO1); f = f + weapon_action(wpn, WR_CHECKAMMO2); + + // always allow selecting the Mine Layer if we placed mines, so that we can detonate them + local entity mine; + if(wpn == WEP_MINE_LAYER) + for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self) + f = 1; + self = oldself; } if (!f) @@ -1092,6 +1111,15 @@ float weapon_prepareattack_checkammo(float secondary) if not(self.items & IT_UNLIMITED_WEAPON_AMMO) if (!weapon_action(self.weapon, WR_CHECKAMMO1 + secondary)) { + // always keep the Mine Layer if we placed mines, so that we can detonate them + local entity mine; + if(self.weapon == WEP_MINE_LAYER) + for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self) + return FALSE; + + if(self.weapon == self.switchweapon) // only play once BEFORE starting to switch weapons + sound (self, CHAN_AUTO, "weapons/dryfire.wav", VOL_BASE, ATTN_NORM); + W_SwitchToOtherWeapon(self); return FALSE; }