From ce88347ded497cb5a415c6e254e4230709a2c527 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 30 Nov 2015 16:07:04 +1000 Subject: [PATCH] Fix prediction of jumping onto ledges --- qcsrc/common/physics.qc | 46 +++++++------------- qcsrc/common/physics.qh | 6 +++ qcsrc/common/triggers/trigger/impulse.qc | 53 +++++++++++++++++++----- qcsrc/lib/csqcmodel/cl_player.qc | 11 +++++ 4 files changed, 74 insertions(+), 42 deletions(-) diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 7e85ef3b8..d21579fa6 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -80,8 +80,6 @@ float GeomLerp(float a, float lerp, float b) : a * pow(fabs(b / a), lerp); } -noref float pmove_waterjumptime; - #define unstick_offsets(X) \ /* 1 no nudge (just return the original if this test passes) */ \ X(' 0.000 0.000 0.000') \ @@ -122,6 +120,7 @@ void PM_ClientMovement_Unstick(entity this) void PM_ClientMovement_UpdateStatus(entity this, bool ground) { +#ifdef CSQC // make sure player is not stuck PM_ClientMovement_Unstick(this); @@ -145,7 +144,7 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground) vector origin1 = this.origin + '0 0 1'; vector origin2 = this.origin - '0 0 1'; - if (ground) + if (ground && autocvar_cl_movement != 3) { tracebox(origin1, this.mins, this.maxs, origin2, MOVE_NORMAL, this); if (trace_fraction < 1.0 && trace_plane_normal.z > 0.7) @@ -183,8 +182,9 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground) } } - if (IS_ONGROUND(this) || this.velocity.z <= 0 || pmove_waterjumptime <= 0) - pmove_waterjumptime = 0; + if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_TELEPORT_TIME(this) <= 0) + PHYS_TELEPORT_TIME(this) = 0; +#endif } void PM_ClientMovement_Move(entity this) @@ -274,7 +274,7 @@ void PM_ClientMovement_Move(entity this) f = (this.velocity * trace1_plane_normal); this.velocity = this.velocity + -f * trace1_plane_normal; } - if(pmove_waterjumptime > 0) + if(PHYS_TELEPORT_TIME(this) > 0) this.velocity = primalvelocity; #endif } @@ -542,11 +542,7 @@ void CheckWaterJump(entity this) this.velocity_z = 225; this.flags |= FL_WATERJUMP; SET_JUMP_HELD(this); -#ifdef SVQC - this.teleport_time = time + 2; // safety net -#elif defined(CSQC) - pmove_waterjumptime = time + 2; -#endif + PHYS_TELEPORT_TIME(this) = time + 2; // safety net } } } @@ -782,9 +778,7 @@ void PM_fly(entity this, float maxspd_mod) // acceleration vector wishdir = normalize(wishvel); float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod); -#ifdef SVQC - if (time >= this.teleport_time) -#endif + if(time >= PHYS_TELEPORT_TIME(this)) PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0); PM_ClientMovement_Move(this); } @@ -813,7 +807,7 @@ void PM_swim(entity this, float maxspd_mod) { this.velocity = forward * 50; this.velocity_z = 310; - pmove_waterjumptime = 2; + PHYS_TELEPORT_TIME(this) = 2; UNSET_ONGROUND(this); SET_JUMP_HELD(this); } @@ -917,9 +911,7 @@ void PM_ladder(entity this, float maxspd_mod) // acceleration vector wishdir = normalize(wishvel); float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod); -#ifdef SVQC - if (time >= this.teleport_time) -#endif + if(time >= PHYS_TELEPORT_TIME(this)) // water acceleration PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this)*maxspd_mod, 1, 0, 0, 0); PM_ClientMovement_Move(this); @@ -1146,11 +1138,7 @@ void PM_air(entity this, float buttons_prev, float maxspd_mod) vector wishdir = normalize(wishvel); float wishspeed = vlen(wishvel); -#ifdef SVQC - if (time >= this.teleport_time) -#else - if (pmove_waterjumptime <= 0) -#endif + if(PHYS_TELEPORT_TIME(this) < time) { float maxairspd = PHYS_MAXAIRSPEED(this) * min(maxspd_mod, 1); @@ -1245,7 +1233,7 @@ void PM_Main(entity this) this.team = myteam + 1; // is this correct? if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump UNSET_JUMP_HELD(this); // canjump = true - pmove_waterjumptime -= PHYS_INPUT_TIMELENGTH; + PHYS_TELEPORT_TIME(this) -= PHYS_INPUT_TIMELENGTH; PM_ClientMovement_UpdateStatus(this, true); #endif @@ -1418,10 +1406,10 @@ void PM_Main(entity this) { this.velocity_x = this.movedir.x; this.velocity_y = this.movedir.y; - if (time > this.teleport_time || this.waterlevel == WATERLEVEL_NONE) + if (time > PHYS_TELEPORT_TIME(this) || this.waterlevel == WATERLEVEL_NONE) { this.flags &= ~FL_WATERJUMP; - this.teleport_time = 0; + PHYS_TELEPORT_TIME(this) = 0; } } @@ -1478,10 +1466,4 @@ void CSQC_ClientMovement_PlayerMove_Frame(entity this) SELFPARAM(); #endif PM_Main(this); -#ifdef CSQC - this.pmove_flags = - ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) | - (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) | - ((this.flags & FL_ONGROUND) ? PMF_ONGROUND : 0); -#endif } diff --git a/qcsrc/common/physics.qh b/qcsrc/common/physics.qh index b266c3c0f..9c1bed68f 100644 --- a/qcsrc/common/physics.qh +++ b/qcsrc/common/physics.qh @@ -93,6 +93,8 @@ bool IsFlying(entity a); #ifdef CSQC + noref float pmove_waterjumptime; + const int FL_WATERJUMP = 2048; // player jumping out of water const int FL_JUMPRELEASED = 4096; // for jump debouncing @@ -111,6 +113,8 @@ bool IsFlying(entity a); //float player_multijump; //float player_jumpheight; + #define PHYS_TELEPORT_TIME(s) pmove_waterjumptime + #define TICRATE ticrate #define PHYS_INPUT_ANGLES(s) input_angles @@ -175,6 +179,8 @@ bool IsFlying(entity a); /** Not real stats */ .string stat_jumpspeedcap_min, stat_jumpspeedcap_max; + #define PHYS_TELEPORT_TIME(s) s.teleport_time + #define TICRATE sys_frametime #define PHYS_INPUT_ANGLES(s) s.v_angle diff --git a/qcsrc/common/triggers/trigger/impulse.qc b/qcsrc/common/triggers/trigger/impulse.qc index 77c491c35..e8d85a013 100644 --- a/qcsrc/common/triggers/trigger/impulse.qc +++ b/qcsrc/common/triggers/trigger/impulse.qc @@ -21,7 +21,11 @@ void trigger_impulse_touch1() return; } +#ifdef SVQC str = min(self.radius, vlen(self.origin - other.origin)); +#elif defined(CSQC) + str = min(self.radius, vlen(self.move_origin - other.move_origin)); +#endif if(self.falloff == 1) str = (str / self.radius) * self.strength; @@ -37,18 +41,35 @@ void trigger_impulse_touch1() if(self.spawnflags & 64) { +#ifdef SVQC float addspeed = str - other.velocity * normalize(targ.origin - self.origin); if (addspeed > 0) { float accelspeed = min(8 * pushdeltatime * str, addspeed); other.velocity += accelspeed * normalize(targ.origin - self.origin); } +#elif defined(CSQC) + float addspeed = str - other.move_velocity * normalize(targ.move_origin - self.move_origin); + if (addspeed > 0) + { + float accelspeed = min(8 * pushdeltatime * str, addspeed); + other.move_velocity += accelspeed * normalize(targ.move_origin - self.move_origin); + } +#endif } else +#ifdef SVQC other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime; - other.flags &= ~FL_ONGROUND; +#elif defined(CSQC) + other.move_velocity = other.move_velocity + normalize(targ.move_origin - self.move_origin) * str * pushdeltatime; +#endif + #ifdef SVQC + other.flags &= ~FL_ONGROUND; + UpdateCSQCProjectile(other); +#elif defined(CSQC) + other.move_flags &= ~FL_ONGROUND; #endif } @@ -71,9 +92,12 @@ void trigger_impulse_touch2() if(!pushdeltatime) return; // div0: ticrate independent, 1 = identity (not 20) - other.velocity = other.velocity * pow(self.strength, pushdeltatime); #ifdef SVQC + other.velocity = other.velocity * pow(self.strength, pushdeltatime); + UpdateCSQCProjectile(other); +#elif defined(CSQC) + other.move_velocity = other.move_velocity * pow(self.strength, pushdeltatime); #endif } @@ -98,7 +122,11 @@ void trigger_impulse_touch3() setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius); +#ifdef SVQC str = min(self.radius, vlen(self.origin - other.origin)); +#elif defined(CSQC) + str = min(self.radius, vlen(self.move_origin - other.move_origin)); +#endif if(self.falloff == 1) str = (1 - str / self.radius) * self.strength; // 1 in the inside @@ -107,9 +135,12 @@ void trigger_impulse_touch3() else str = self.strength; - other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime; #ifdef SVQC + other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime; + UpdateCSQCProjectile(other); +#elif defined(CSQC) + other.move_velocity = other.move_velocity + normalize(other.move_origin - self.move_origin) * str * pushdeltatime; #endif } @@ -133,10 +164,11 @@ Use a brush textured with common/origin in the trigger entity to determine the o in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect). */ #ifdef SVQC -bool trigger_impulse_send(entity to, int sf) -{SELFPARAM(); +bool trigger_impulse_send(entity this, entity to, int sf) +{ WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE); + WriteInt24_t(MSG_ENTITY, self.spawnflags); WriteCoord(MSG_ENTITY, self.radius); WriteCoord(MSG_ENTITY, self.strength); WriteByte(MSG_ENTITY, self.falloff); @@ -149,7 +181,7 @@ bool trigger_impulse_send(entity to, int sf) void trigger_impulse_link() { - //Net_LinkEntity(self, 0, false, trigger_impulse_send); + Net_LinkEntity(self, 0, false, trigger_impulse_send); } spawnfunc(trigger_impulse) @@ -184,6 +216,7 @@ spawnfunc(trigger_impulse) #elif defined(CSQC) NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew) { + self.spawnflags = ReadInt24_t(); self.radius = ReadCoord(); self.strength = ReadCoord(); self.falloff = ReadByte(); @@ -195,12 +228,12 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew) self.classname = "trigger_impulse"; self.solid = SOLID_TRIGGER; self.entremove = trigger_remove_generic; - self.draw = trigger_draw_generic; + //self.draw = trigger_draw_generic; self.drawmask = MASK_NORMAL; self.move_time = time; - if(self.radius) { self.trigger_touch = trigger_impulse_touch3; } - else if(self.target) { self.trigger_touch = trigger_impulse_touch1; } - else { self.trigger_touch = trigger_impulse_touch2; } + if(self.radius) { self.move_touch = trigger_impulse_touch3; } + else if(self.target) { self.move_touch = trigger_impulse_touch1; } + else { self.move_touch = trigger_impulse_touch2; } } #endif diff --git a/qcsrc/lib/csqcmodel/cl_player.qc b/qcsrc/lib/csqcmodel/cl_player.qc index fc6979ed5..ff8d4ff62 100644 --- a/qcsrc/lib/csqcmodel/cl_player.qc +++ b/qcsrc/lib/csqcmodel/cl_player.qc @@ -141,6 +141,9 @@ void Movetype_Physics_Spam(entity this) // optimized this.velocity = this.move_velocity; this.angles = this.move_angles; this.flags = BITSET(this.flags, FL_ONGROUND, boolean(this.move_flags & FL_ONGROUND)); + this.flags = BITSET(this.flags, FL_WATERJUMP, boolean(this.move_flags & FL_WATERJUMP)); + this.waterlevel = this.move_waterlevel; + this.watertype = this.move_watertype; setorigin(this, this.move_origin); } @@ -158,8 +161,16 @@ void CSQCPlayer_Physics(entity this) this.move_velocity = this.velocity; this.move_avelocity = this.avelocity; this.move_flags = BITSET(this.move_flags, FL_ONGROUND, boolean(this.flags & FL_ONGROUND)); + this.move_flags = BITSET(this.move_flags, FL_WATERJUMP, boolean(this.flags & FL_WATERJUMP)); + this.move_waterlevel = this.waterlevel; + this.move_watertype = this.watertype; Movetype_Physics_Spam(this); } + + this.pmove_flags = + ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) | + (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) | + ((this.flags & FL_ONGROUND) ? PMF_ONGROUND : 0); } } -- 2.39.2