vector traceorigin = entcs_receiver(player_localentnum - 1).origin + (eZ * STAT(VIEWHEIGHT));
- vecs = decompressShotOrigin(STAT(SHOTORG));
-
traceline(traceorigin, traceorigin + view_forward * max_shot_distance, mv, ta);
trueaimpoint = trace_endpos;
// move trueaimpoint a little bit forward to make the final tracebox reliable
if(vdist((trueaimpoint - traceorigin), <, g_trueaim_minrange))
trueaimpoint = traceorigin + view_forward * g_trueaim_minrange;
+ vecs = decompressShotOrigin(STAT(SHOTORG));
+
if(vecs.x > 0)
vecs.y = -vecs.y;
else
this.movedir_aligned = shotorg_adjust(v, false, true, algn);
this.view_ofs = this.movedir_aligned - v;
}
- int compressed_shotorg = compressShotOrigin(this.movedir);
- // make them match perfectly
-#ifdef SVQC
- // null during init
- if (this.owner) STAT(SHOTORG, this.owner) = compressed_shotorg;
-#endif
- this.movedir = decompressShotOrigin(compressed_shotorg);
+
+ // shotorg_adjust can give negative .x from shootfromfixedorigin
+ // recheck .x here due to it
+ if (this.movedir.x >= 0)
+ {
+ int compressed_shotorg = compressShotOrigin(this.movedir);
+ // make them match perfectly
+ #ifdef SVQC
+ // null during init
+ if (this.owner) STAT(SHOTORG, this.owner) = compressed_shotorg;
+ #endif
+ this.movedir = decompressShotOrigin(compressed_shotorg);
+ }
+ else
+ {
+ // don't support negative x shotorgs
+ this.movedir = '0 0 0';
+
+ // reset _aligned here too even though as a side effect
+ // g_shootfromfixedorigin can make it reset
+ // it'd be only slightly better if it was checked individually
+ this.movedir_aligned = '0 0 0';
+
+ #ifdef SVQC
+ // null during init
+ if (this.owner) STAT(SHOTORG, this.owner) = 0;
+ #endif
+ }
#ifdef SVQC
this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount
rlplayer = csqcplayer; // fall back to the global
vector md = wepent.movedir_aligned;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
- vector dv = forward * vecs.x + right * -vecs.y + up * vecs.z;
+ vector dv = forward * md.x + right * -md.y + up * md.z;
vector org = rlplayer.origin + rlplayer.view_ofs + dv;
pointparticles(thiswep.m_muzzleeffect, org, forward * 1000, 1);
makevectors(actor.v_angle);
w_shotdir = v_forward;
vector md = actor.(weaponentity).movedir;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
- vector dv = v_forward * vecs.x + v_right * -vecs.y + v_up * vecs.z;
+ vector dv = v_forward * md.x + v_right * -md.y + v_up * md.z;
w_shotorg = actor.origin + actor.view_ofs + dv;
//W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,thiswep.m_id);
f = 1;
vector md = this.realowner.(weaponentity).movedir;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
-
- vector dv = v_right * -vecs.y + v_up * vecs.z;
+ vector dv = v_right * -md.y + v_up * md.z;
if(!W_DualWielding(this.realowner))
dv = '0 0 0'; // don't override!
#if 0
// code stolen from W_SetupShot_Dir_ProjectileSize_Range()
vector md = targ.(weaponentity).movedir;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
- vector dv = v_right * -vecs.y + v_up * vecs.z;
+ vector dv = v_right * -md.y + v_up * md.z;
vector mi = '0 0 0', ma = '0 0 0';
if(IS_CLIENT(targ)) // no antilag for non-clients!
center.z = trace_endpos.z;
#else
- // very cheap way but it skips movedir.x > 0 checks and move into solid checks which is fine most of the time for now AFAIK
- // this should only really be an issue with absurd g_shootfromfixedorigin custom values like "-1 0 9001"
+ // very cheap way but it skips move into solid checks which is fine most of the time for now AFAIK
+ // this should only really be an issue with some rare edge cases where
+ // shot origin was prevented from going into a ceiling but it still explodes at the ceiling
+ // shot origin wasn't raised as high as possible and the shooter gets upwards knockback
+ // TL;DR: no bugs if vertical shot origin is always within player bbox
center.z = center.z + targ.(weaponentity).movedir.z;
#endif
}
{
.entity weaponentity = weaponentities[slot];
vector md = this.(weaponentity).movedir;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
- vector dv = v_right * -vecs.y;
+ vector dv = v_right * -md.y;
if(!is_dualwielding)
dv = '0 0 0'; // don't override!
W_ThrowWeapon(this, weaponentity, W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), dv, true);
if(IS_PLAYER(ent))
W_HitPlotAnalysis(ent, wep, forward, right, up);
+ // read shot origin offset, like g_shootfromcenter
+ // set in CL_WeaponEntity_SetModel (not a CSQC exclusive function...)
vector md = ent.(weaponentity).movedir;
- vector vecs = ((md.x > 0) ? md : '0 0 0');
+ //print(sprintf("offset of %s: %v\n", ent.(weaponentity).m_weapon.netname, md));
+ vector dv = right * -md.y + up * md.z;
- vector dv = right * -vecs.y + up * vecs.z;
w_shotorg = ent.origin + ent.view_ofs;
+
+ // move the shotorg sideways and vertically as much as requested if possible
if(antilag)
{
if(CS(ent).antilag_debug)
if(antilag)
{
if(CS(ent).antilag_debug)
- tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
+ tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (md.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
else
- tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+ tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (md.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
}
else
- tracebox(w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent);
+ tracebox(w_shotorg, mi, ma, w_shotorg + forward * (md.x + nudge), MOVE_NORMAL, ent);
w_shotorg = trace_endpos - forward * nudge;
+
+ //print(sprintf("w_shotorg %v\n\n", w_shotorg - (ent.origin + ent.view_ofs)));
+
// calculate the shotdir from the chosen shotorg
if(W_DualWielding(ent))
w_shotdir = s_forward;