From: Rudolf Polzer Date: Fri, 16 May 2014 19:27:56 +0000 (+0200) Subject: w_arc: various teleport/warp related fixes. X-Git-Tag: xonotic-v0.8.0~152^2~29^2~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a84b696dfa64e566e791cab2a026c42bbba4e518;p=xonotic%2Fxonotic-data.pk3dir.git w_arc: various teleport/warp related fixes. - Reset arc beam on warp/teleport. - Lock arc beam for a RTT after reset (so the beam is straight at matching times/locations on client/server, after which everything is consistent again). - Use unwarped view origin and angles on client to fix behaviour when the client is currently predicting the warp, as there's no signal for begin of warp prediction. - Fix TrueAim-like logic on client when standing right against a wall (use the same avoid-shotorigin-poking-into-solid hack as other TrueAim code does). warpzonelib: provide unwarped origin/angles in a variable. --- diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index d10713094..ecc3fa126 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -269,7 +269,7 @@ float EnemyHitCheck() float TrueAimCheck() { - float nudge = 1; // added to traceline target and subtracted from result + float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us? vector vecs, trueaimpoint, w_shotorg; vector mi, ma, dv; float shottype; diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index 120b6658d..077b7d972 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -470,8 +470,14 @@ void CSQCModel_Effects_PreUpdate(void) self.effects = self.csqcmodel_effects; self.modelflags = self.csqcmodel_modelflags; } +void Reset_ArcBeam(void); void CSQCModel_Effects_PostUpdate(void) { + if (self == csqcplayer) { + if (self.csqcmodel_teleported) { + Reset_ArcBeam(); + } + } self.csqcmodel_effects = self.effects; self.csqcmodel_modelflags = self.modelflags; self.effects = 0; diff --git a/qcsrc/common/weapons/w_arc.qc b/qcsrc/common/weapons/w_arc.qc index 74f51a541..e4376e868 100644 --- a/qcsrc/common/weapons/w_arc.qc +++ b/qcsrc/common/weapons/w_arc.qc @@ -81,6 +81,7 @@ ARC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP) .float beam_prev; .float beam_initialized; .float beam_bursting; +.float beam_teleporttime; #endif #ifdef CSQC void Ent_ReadArcBeam(float isnew); @@ -166,6 +167,15 @@ float W_Arc_Beam_Send(entity to, float sf) return TRUE; } +void Reset_ArcBeam(entity player, vector forward) +{ + if (!player.arc_beam) { + return; + } + player.arc_beam.beam_dir = forward; + player.arc_beam.beam_teleporttime = time; +} + void W_Arc_Beam_Think(void) { if(self != self.owner.arc_beam) @@ -234,6 +244,11 @@ void W_Arc_Beam_Think(void) WEP_CVAR(arc, beam_range) ); + // After teleport, "lock" the beam until the teleport is confirmed. + if (time < self.beam_teleporttime + ANTILAG_LATENCY(self.owner)) { + w_shotdir = self.beam_dir; + } + // network information: shot origin and want/aim direction if(self.beam_start != w_shotorg) { @@ -472,6 +487,8 @@ void W_Arc_Beam_Think(void) } } + // te_explosion(trace_endpos); + // if we're bursting, use burst visual effects new_beam_type += burst; @@ -724,6 +741,17 @@ void Draw_ArcBeam_callback(vector start, vector hit, vector end) Draw_ArcBeam_callback_last_bottom = WarpZone_UnTransformOrigin(WarpZone_trace_transform, bottom); } +void Reset_ArcBeam(void) +{ + entity e; + for (e = world; (e = findfloat(e, beam_usevieworigin, 1)); ) { + e.beam_initialized = FALSE; + } + for (e = world; (e = findfloat(e, beam_usevieworigin, 2)); ) { + e.beam_initialized = FALSE; + } +} + void Draw_ArcBeam(void) { if(!self.beam_usevieworigin) @@ -749,44 +777,43 @@ void Draw_ArcBeam(void) // into a weapon system for client code. // find where we are aiming - makevectors(view_angles); + makevectors(warpzone_save_view_angles); + vector forward = v_forward; + vector right = v_right; + vector up = v_up; // decide upon start position if(self.beam_usevieworigin == 2) - { start_pos = view_origin; } + { start_pos = warpzone_save_view_origin; } else { start_pos = self.origin; } // trace forward with an estimation WarpZone_TraceLine( start_pos, - start_pos + view_forward * self.beam_range, + start_pos + forward * self.beam_range, MOVE_NOMONSTERS, self ); // untransform in case our trace went through a warpzone - vector vf, vr, vu; - vf = view_forward; - vr = view_right; - vu = view_up; vector end_pos = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); - view_forward = vf; - view_right = vr; - view_up = vu; // un-adjust trueaim if shotend is too close - if(vlen(end_pos - view_origin) < g_trueaim_minrange) - end_pos = view_origin + (view_forward * g_trueaim_minrange); + if(vlen(end_pos - start_pos) < g_trueaim_minrange) + end_pos = start_pos + (forward * g_trueaim_minrange); // move shot origin to the actual gun muzzle origin vector origin_offset = - view_forward * self.beam_shotorigin_x - + view_right * -self.beam_shotorigin_y - + view_up * self.beam_shotorigin_z; + right * -self.beam_shotorigin_y + + up * self.beam_shotorigin_z; start_pos = start_pos + origin_offset; + // Move it also forward, but only as far as possible without hitting anything. Don't poke into walls! + traceline(start_pos, start_pos + forward * self.beam_shotorigin_x, MOVE_NORMAL, self); + start_pos = trace_endpos; + // calculate the aim direction now wantdir = normalize(end_pos - start_pos); @@ -861,7 +888,7 @@ void Draw_ArcBeam(void) beamdir = self.beam_dir; // finally, set self.angles to the proper direction so that muzzle attachment points in proper direction - self.angles = fixedvectoangles2(view_forward, view_up); + self.angles = fixedvectoangles2(forward, up); // TODO(Samual): is this == warpzone_save_view_angles? } else { @@ -962,6 +989,9 @@ void Draw_ArcBeam(void) // visual effects for startpoint and endpoint if(self.beam_hiteffect) { + // FIXME we really should do this on the server so it actually + // matches gameplay. What this client side stuff is doing is no + // more than guesswork. pointparticles( self.beam_hiteffect, last_origin, diff --git a/qcsrc/server/t_teleporters.qc b/qcsrc/server/t_teleporters.qc index 8f15a4f82..943f01ae3 100644 --- a/qcsrc/server/t_teleporters.qc +++ b/qcsrc/server/t_teleporters.qc @@ -80,6 +80,7 @@ void spawn_tdeath(vector v0, entity e, vector v) #define TELEPORT_NORMAL 1 // play sounds/effects etc #define TELEPORT_SIMPLE 2 // only do teleport, nothing special +void Reset_ArcBeam(entity player, vector forward); void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags) { entity telefragger; @@ -117,6 +118,8 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle player.velocity = to_velocity; BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT); + makevectors(player.angles); + Reset_ArcBeam(player, v_forward); UpdateCSQCProjectileAfterTeleport(player); if(IS_PLAYER(player)) @@ -337,6 +340,8 @@ void spawnfunc_trigger_teleport (void) void WarpZone_PostTeleportPlayer_Callback(entity pl) { + makevectors(pl.angles); + Reset_ArcBeam(pl, v_forward); UpdateCSQCProjectileAfterTeleport(pl); // "disown" projectiles after teleport if(pl.owner) diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index 467da632b..75cf5b1d4 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -3,7 +3,7 @@ // make sure you call makevectors first (FIXME?) void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float chan, float maxdamage, float range) { - float nudge = 1; // added to traceline target and subtracted from result + float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us? float oldsolid; vector vecs, dv; oldsolid = ent.dphitcontentsmask; diff --git a/qcsrc/warpzonelib/client.qc b/qcsrc/warpzonelib/client.qc index f55cec1d5..c2a110b4a 100644 --- a/qcsrc/warpzonelib/client.qc +++ b/qcsrc/warpzonelib/client.qc @@ -239,8 +239,8 @@ void WarpZone_FixView() vector org, ang, nearclip, corner0, corner1, corner2, corner3, o; float f; - org = getpropertyvec(VF_ORIGIN); - ang = getpropertyvec(VF_ANGLES); + warpzone_save_view_origin = org = getpropertyvec(VF_ORIGIN); + warpzone_save_view_angles = ang = getpropertyvec(VF_ANGLES); #ifdef WORKAROUND_XON010 float dirty; dirty = checkextension("DP_CSQC_ROTATEMOVES"); diff --git a/qcsrc/warpzonelib/client.qh b/qcsrc/warpzonelib/client.qh index 446c917db..c0a4ca0f0 100644 --- a/qcsrc/warpzonelib/client.qh +++ b/qcsrc/warpzonelib/client.qh @@ -7,3 +7,6 @@ void WarpZone_FixView(); void WarpZone_Init(); void WarpZone_Shutdown(); + +vector warpzone_save_view_origin; +vector warpzone_save_view_angles;