From 80034856c349eb74bdbd70f9133b023392cffecc Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 17 Mar 2015 02:29:22 +1100 Subject: [PATCH] Add movetype updates from QC physics branch --- qcsrc/common/movetypes/include.qc | 1 + qcsrc/common/movetypes/include.qh | 3 +- qcsrc/common/movetypes/movetypes.qc | 459 ++++++++++++++++------- qcsrc/common/movetypes/movetypes.qh | 39 +- qcsrc/common/movetypes/push.qc | 234 ++++++------ qcsrc/common/movetypes/toss.qc | 92 ++--- qcsrc/common/movetypes/walk.qc | 167 +++++++++ qcsrc/common/movetypes/walk.qh | 6 + qcsrc/common/physics.qc | 5 +- qcsrc/common/physics.qh | 73 ++++ qcsrc/common/stats.qh | 44 +-- qcsrc/common/triggers/trigger/impulse.qc | 4 - 12 files changed, 775 insertions(+), 352 deletions(-) create mode 100644 qcsrc/common/movetypes/walk.qc create mode 100644 qcsrc/common/movetypes/walk.qh diff --git a/qcsrc/common/movetypes/include.qc b/qcsrc/common/movetypes/include.qc index e4d6f39db..64d92d4a9 100644 --- a/qcsrc/common/movetypes/include.qc +++ b/qcsrc/common/movetypes/include.qc @@ -1,4 +1,5 @@ #include "push.qc" #include "toss.qc" +#include "walk.qc" #include "movetypes.qc" diff --git a/qcsrc/common/movetypes/include.qh b/qcsrc/common/movetypes/include.qh index 126d3b6af..a96e5957a 100644 --- a/qcsrc/common/movetypes/include.qh +++ b/qcsrc/common/movetypes/include.qh @@ -3,5 +3,6 @@ #include "push.qh" #include "toss.qh" +#include "walk.qh" -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/movetypes/movetypes.qc b/qcsrc/common/movetypes/movetypes.qc index 5a45e9866..a7351ac66 100644 --- a/qcsrc/common/movetypes/movetypes.qc +++ b/qcsrc/common/movetypes/movetypes.qc @@ -14,21 +14,254 @@ #include "../../server/autocvars.qh" #endif -void _Movetype_CheckVelocity() // SV_CheckVelocity +void _Movetype_WallFriction(vector stepnormal) // SV_WallFriction { + /*float d, i; + vector into, side; + makevectors(self.v_angle); + d = (stepnormal * v_forward) + 0.5; + + if(d < 0) + { + i = (stepnormal * self.move_velocity); + into = i * stepnormal; + side = self.move_velocity - into; + self.move_velocity_x = side.x * (1 * d); + self.move_velocity_y = side.y * (1 * d); + }*/ +} + +vector planes[MAX_CLIP_PLANES]; +int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove +{ + int blocked = 0, bumpcount; + int i, j, numplanes = 0; + float time_left = dt, grav = 0; + vector push; + vector primal_velocity, original_velocity, new_velocity = '0 0 0', restore_velocity; + + for(i = 0; i <= MAX_CLIP_PLANES; ++i) + planes[i] = '0 0 0'; + + grav = 0; + + restore_velocity = self.move_velocity; + + if(applygravity) + { + self.move_didgravity = 1; + grav = dt * (PHYS_ENTGRAVITY(self) ? PHYS_ENTGRAVITY(self) : 1) * PHYS_GRAVITY; + + if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND)) + { + if(GRAVITY_UNAFFECTED_BY_TICRATE) + self.move_velocity_z -= grav * 0.5; + else + self.move_velocity_z -= grav; + } + } + + original_velocity = primal_velocity = self.move_velocity; + + for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++) + { + if(!self.move_velocity_x && !self.move_velocity_y && !self.move_velocity_z) + break; + + push = self.move_velocity * time_left; + if(!_Movetype_PushEntity(push, false)) + { + // we got teleported by a touch function + // let's abort the move + blocked |= 8; + break; + } + + // this code is used by MOVETYPE_WALK and MOVETYPE_STEP and SV_UnstickEntity + // abort move if we're stuck in the world (and didn't make it out) + if(trace_startsolid && trace_allsolid) + { + self.move_velocity = restore_velocity; + return 3; + } + + if(trace_fraction == 1) + break; + if(trace_plane_normal_z) + { + if(trace_plane_normal_z > 0.7) + { + // floor + blocked |= 1; + + if(!trace_ent) + { + //dprint("_Movetype_FlyMove: !trace_ent\n"); + trace_ent = world; + } + + self.move_flags |= FL_ONGROUND; + self.move_groundentity = trace_ent; + } + } + else if(stepheight) + { + // step - handle it immediately + vector org; + vector steppush; + //Con_Printf("step %f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]); + steppush = '0 0 1' * stepheight; + org = self.move_origin; + if(!_Movetype_PushEntity(steppush, false)) + { + blocked |= 8; + break; + } + //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]); + if(!_Movetype_PushEntity(push, false)) + { + blocked |= 8; + break; + } + float trace2_fraction = trace_fraction; + //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]); + steppush = '0 0 1' * (org_z - self.move_origin_z); + if(!_Movetype_PushEntity(steppush, false)) + { + blocked |= 8; + break; + } + //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]); + // accept the new position if it made some progress... + if(fabs(self.move_origin_x - org_x) >= 0.03125 || fabs(self.move_origin_y - org_y) >= 0.03125) + { + //Con_Printf("accepted (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]); + trace_endpos = self.move_origin; + time_left *= 1 - trace2_fraction; + numplanes = 0; + continue; + } + else + { + //Con_Printf("REJECTED (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]); + self.move_origin = org; + } + } + else + { + // step - return it to caller + blocked |= 2; + // save the trace for player extrafriction + if(stepnormal) + stepnormal = trace_plane_normal; + } + if(trace_fraction >= 0.001) + { + // actually covered some distance + original_velocity = self.move_velocity; + numplanes = 0; + } + + time_left *= 1 - trace_fraction; + + // clipped to another plane + if(numplanes >= MAX_CLIP_PLANES) + { + // this shouldn't really happen + self.move_velocity = '0 0 0'; + blocked = 3; + break; + } + + planes[numplanes] = trace_plane_normal; + numplanes++; + + // modify original_velocity so it parallels all of the clip planes + for (i = 0;i < numplanes;i++) + { + new_velocity = _Movetype_ClipVelocity(original_velocity, planes[i], 1); + for (j = 0;j < numplanes;j++) + { + if(j != i) + { + // not ok + if((new_velocity * planes[j]) < 0) + break; + } + } + if(j == numplanes) + break; + } + + if(i != numplanes) + { + // go along this plane + self.move_velocity = new_velocity; + } + else + { + // go along the crease + if(numplanes != 2) + { + self.move_velocity = '0 0 0'; + blocked = 7; + break; + } + vector dir; + dir.x = planes[0].y * planes[1].z - planes[0].z * planes[1].y; + dir.y = planes[0].z * planes[1].x - planes[0].x * planes[1].z; + dir.z = planes[0].x * planes[1].y - planes[0].y * planes[1].x; + // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners + float ilength = sqrt((dir * dir)); + if(ilength) + ilength = 1.0 / ilength; + dir.x *= ilength; + dir.y *= ilength; + dir.z *= ilength; + float d = (dir * self.move_velocity); + self.move_velocity = dir * d; + } + + // if current velocity is against the original velocity, + // stop dead to avoid tiny occilations in sloping corners + if((self.move_velocity * primal_velocity) <= 0) + { + self.move_velocity = '0 0 0'; + break; + } + } + + // LordHavoc: this came from QW and allows you to get out of water more easily + if(GAMEPLAYFIX_EASIERWATERJUMP && (self.move_flags & FL_WATERJUMP) && !(blocked & 8)) + self.move_velocity = primal_velocity; + + if(applygravity) + { + if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND)) + { + if(GRAVITY_UNAFFECTED_BY_TICRATE) + self.move_velocity_z -= grav * 0.5f; + } + } + + return blocked; } -float _Movetype_CheckWater(entity ent) // SV_CheckWater +void _Movetype_CheckVelocity() // SV_CheckVelocity +{ + // if(vlen(self.move_velocity) < 0.0001) + // self.move_velocity = '0 0 0'; +} + +bool _Movetype_CheckWater(entity ent) // SV_CheckWater { vector point = ent.move_origin; - point_z += (ent.mins_z + 1); + point.z += (ent.mins.z + 1); int nativecontents = pointcontents(point); - - if(ent.move_watertype) - if(ent.move_watertype != nativecontents) + if(ent.move_watertype && ent.move_watertype != nativecontents) { - //dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents); + // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents); if(ent.contentstransition) ent.contentstransition(ent.move_watertype, nativecontents); } @@ -41,22 +274,22 @@ float _Movetype_CheckWater(entity ent) // SV_CheckWater { ent.move_watertype = nativecontents; ent.move_waterlevel = 1; - point_y = (ent.origin_y + ((ent.mins_z + ent.maxs_y) * 0.5)); + point.y = (ent.origin.y + ((ent.mins.z + ent.maxs.y) * 0.5)); if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK) { ent.move_waterlevel = 2; - point_y = ent.origin_y + ent.view_ofs_y; + point.y = ent.origin.y + ent.view_ofs.y; if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK) ent.move_waterlevel = 3; } } - return (ent.move_waterlevel > 1); + return ent.move_waterlevel > 1; } -void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition +void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition { - float contents = pointcontents(ent.move_origin); + int contents = pointcontents(ent.move_origin); if(!ent.move_watertype) { @@ -70,7 +303,7 @@ void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition } else if(ent.move_watertype != contents) { - //dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents); + // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents); if(ent.contentstransition) ent.contentstransition(ent.move_watertype, contents); } @@ -87,12 +320,10 @@ void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition } } -void _Movetype_Impact(entity oth) // SV_Impact +void _Movetype_Impact(entity oth) // SV_Impact { - entity oldother, oldself; - - oldself = self; - oldother = other; + entity oldself = self; + entity oldother = other; if(self.move_touch) { @@ -115,17 +346,14 @@ void _Movetype_Impact(entity oth) // SV_Impact } } -void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid +void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid { - entity e, oldself, oldother; - - oldself = self; - oldother = other; + entity oldself = self; + entity oldother = other; - for(e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain) + for (entity e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain) { - if(e.move_touch) - if(boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax)) + if(e.move_touch && boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax)) { self = e; other = oldself; @@ -148,7 +376,7 @@ void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid self = oldself; } -void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict +void _Movetype_LinkEdict(bool touch_triggers) // SV_LinkEdict { vector mi, ma; if(self.solid == SOLID_BSP) @@ -162,26 +390,26 @@ void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict mi = self.mins; ma = self.maxs; } - mi = mi + self.origin; - ma = ma + self.origin; + mi += self.move_origin; + ma += self.move_origin; if(self.move_flags & FL_ITEM) { - mi_x -= 15; - mi_y -= 15; - mi_z -= 1; - ma_x += 15; - ma_y += 15; - ma_z += 1; + mi.x -= 15; + mi.y -= 15; + mi.z -= 1; + ma.x += 15; + ma.y += 15; + ma.z += 1; } else { - mi_x -= 1; - mi_y -= 1; - mi_z -= 1; - ma_x += 1; - ma_y += 1; - ma_z += 1; + mi.x -= 1; + mi.y -= 1; + mi.z -= 1; + ma.x += 1; + ma.y += 1; + ma.z += 1; } self.absmin = mi; @@ -191,10 +419,9 @@ void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict _Movetype_LinkEdict_TouchAreaGrid(); } -float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition +bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition { - vector org; - org = self.move_origin + ofs; +// vector org = self.move_origin + ofs; int cont = self.dphitcontentsmask; self.dphitcontentsmask = DPCONTENTS_SOLID; @@ -209,10 +436,9 @@ float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition return false; } -float _Movetype_UnstickEntity() // SV_UnstickEntity +bool _Movetype_UnstickEntity() // SV_UnstickEntity { - if(!_Movetype_TestEntityPosition('0 0 0')) - return true; + if(!_Movetype_TestEntityPosition('0 0 0')) return true; if(!_Movetype_TestEntityPosition('-1 0 0')) goto success; if(!_Movetype_TestEntityPosition('1 0 0')) goto success; if(!_Movetype_TestEntityPosition('0 -1 0')) goto success; @@ -221,38 +447,36 @@ float _Movetype_UnstickEntity() // SV_UnstickEntity if(!_Movetype_TestEntityPosition('1 -1 0')) goto success; if(!_Movetype_TestEntityPosition('-1 1 0')) goto success; if(!_Movetype_TestEntityPosition('1 1 0')) goto success; - float i; - for(i = 1; i <= 17; ++i) + for (int i = 1; i <= 17; ++i) { if(!_Movetype_TestEntityPosition('0 0 -1' * i)) goto success; if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success; } - dprintf("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", num_for_edict(self), self.classname, vtos(self.move_origin)); + dprintf("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", + num_for_edict(self), self.classname, vtos(self.move_origin)); return false; -:success - dprintf("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n", num_for_edict(self), self.classname, vtos(self.move_origin)); + : success; + dprintf("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n", + num_for_edict(self), self.classname, vtos(self.move_origin)); _Movetype_LinkEdict(true); return true; } -vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity +vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity { - vel = vel - ((vel * norm) * norm) * f; + vel -= ((vel * norm) * norm) * f; - if(vel_x > -0.1 && vel_x < 0.1) vel_x = 0; - if(vel_y > -0.1 && vel_y < 0.1) vel_y = 0; - if(vel_z > -0.1 && vel_z < 0.1) vel_z = 0; + if(vel.x > -0.1 && vel.x < 0.1) vel.x = 0; + if(vel.y > -0.1 && vel.y < 0.1) vel.y = 0; + if(vel.z > -0.1 && vel.z < 0.1) vel.z = 0; return vel; } void _Movetype_PushEntityTrace(vector push) { - vector end; - float type; - - end = self.move_origin + push; - + vector end = self.move_origin + push; + int type; if(self.move_nomonsters) type = max(0, self.move_nomonsters); else if(self.move_movetype == MOVETYPE_FLYMISSILE) @@ -265,7 +489,7 @@ void _Movetype_PushEntityTrace(vector push) tracebox(self.move_origin, self.mins, self.maxs, end, type, self); } -float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity +float _Movetype_PushEntity(vector push, bool failonstartsolid) // SV_PushEntity { _Movetype_PushEntityTrace(push); @@ -285,57 +509,55 @@ float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity .float ltime; .void() blocked; // matrix version of makevectors, sets v_forward, v_right and v_up -void makevectors_matrix(vector myangles) // AngleVectorsFLU +void makevectors_matrix(vector myangles) // AngleVectorsFLU { - float angle, sr, sp, sy, cr, cp, cy; - v_forward = v_right = v_up = '0 0 0'; - angle = myangles_y * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = myangles_x * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); + float y = myangles.y * (M_PI * 2 / 360); + float sy = sin(y); + float cy = cos(y); + float p = myangles.x * (M_PI * 2 / 360); + float sp = sin(p); + float cp = cos(p); if(v_forward) { - v_forward_x = cp*cy; - v_forward_y = cp*sy; - v_forward_z = -sp; + v_forward.x = cp * cy; + v_forward.y = cp * sy; + v_forward.z = -sp; } if(v_right || v_up) { - if(myangles_z) + if(myangles.z) { - angle = myangles_z * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); + float r = myangles.z * (M_PI * 2 / 360); + float sr = sin(r); + float cr = cos(r); if(v_right) { - v_right_x = sr*sp*cy+cr*-sy; - v_right_y = sr*sp*sy+cr*cy; - v_right_z = sr*cp; + v_right.x = sr * sp * cy + cr * -sy; + v_right.y = sr * sp * sy + cr * cy; + v_right.z = sr * cp; } if(v_up) { - v_up_x = cr*sp*cy+-sr*-sy; - v_up_y = cr*sp*sy+-sr*cy; - v_up_z = cr*cp; + v_up.x = cr * sp * cy + -sr * -sy; + v_up.y = cr * sp * sy + -sr * cy; + v_up.z = cr * cp; } } else { if(v_right) { - v_right_x = -sy; - v_right_y = cy; - v_right_z = 0; + v_right.x = -sy; + v_right.y = cy; + v_right.z = 0; } if(v_up) { - v_up_x = sp*cy; - v_up_y = sp*sy; - v_up_z = cp; + v_up.x = sp * cy; + v_up.y = sp * sy; + v_up.z = cp; } } } @@ -344,7 +566,7 @@ void makevectors_matrix(vector myangles) // AngleVectorsFLU void _Movetype_Physics_Frame(float movedt) { self.move_didgravity = -1; - switch(self.move_movetype) + switch (self.move_movetype) { case MOVETYPE_PUSH: case MOVETYPE_FAKEPUSH: @@ -365,7 +587,7 @@ void _Movetype_Physics_Frame(float movedt) error("SV_Physics_Step not implemented"); break; case MOVETYPE_WALK: - error("SV_Physics_Walk not implemented"); + _Movetype_Physics_Walk(movedt); break; case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: @@ -377,11 +599,9 @@ void _Movetype_Physics_Frame(float movedt) } } -void Movetype_Physics_NoMatchServer() // optimized +void Movetype_Physics_NoMatchServer() // optimized { - float movedt; - - movedt = time - self.move_time; + float movedt = time - self.move_time; self.move_time = time; _Movetype_Physics_Frame(movedt); @@ -399,29 +619,26 @@ void Movetype_Physics_MatchServer(bool sloppy) Movetype_Physics_MatchTicrate(TICRATE, sloppy); } -void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity +void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity { - float n, i, dt, movedt; - if(tr <= 0) { Movetype_Physics_NoMatchServer(); return; } - dt = time - self.move_time; + float dt = time - self.move_time; - movedt = tr; - n = max(0, floor(dt / tr)); + int n = max(0, floor(dt / tr)); dt -= n * tr; self.move_time += n * tr; if(!self.move_didgravity) self.move_didgravity = ((self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) && !(self.move_flags & FL_ONGROUND)); - for(i = 0; i < n; ++i) + for (int i = 0; i < n; ++i) { - _Movetype_Physics_Frame(movedt); + _Movetype_Physics_Frame(tr); if(wasfreed(self)) return; } @@ -435,25 +652,15 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity if(self.move_didgravity > 0) { - if(GRAVITY_UNAFFECTED_BY_TICRATE) - { - if(self.gravity) - self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY; - else - self.velocity_z -= 0.5 * dt * PHYS_GRAVITY; - } - else - { - if(self.gravity) - self.velocity_z -= dt * self.gravity * PHYS_GRAVITY; - else - self.velocity_z -= dt * PHYS_GRAVITY; - } + self.velocity_z -= (GRAVITY_UNAFFECTED_BY_TICRATE ? 0.5 : 1) + * dt + * (self.gravity ? self.gravity : 1) + * PHYS_GRAVITY; } self.angles = self.move_angles + dt * self.avelocity; - if(sloppy || self.movetype == MOVETYPE_NOCLIP) + if(sloppy || self.move_movetype == MOVETYPE_NOCLIP) { setorigin(self, self.move_origin + dt * self.velocity); } @@ -464,16 +671,8 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity setorigin(self, trace_endpos); } - if(self.move_didgravity > 0) - { - if(GRAVITY_UNAFFECTED_BY_TICRATE) - { - if(self.gravity) - self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY; - else - self.velocity_z -= 0.5 * dt * PHYS_GRAVITY; - } - } + if(self.move_didgravity > 0 && GRAVITY_UNAFFECTED_BY_TICRATE) + self.velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY; } else { diff --git a/qcsrc/common/movetypes/movetypes.qh b/qcsrc/common/movetypes/movetypes.qh index 85c07fce6..88b545fe1 100644 --- a/qcsrc/common/movetypes/movetypes.qh +++ b/qcsrc/common/movetypes/movetypes.qh @@ -2,9 +2,9 @@ #define MOVETYPES_H .float move_ltime; -.void(void) move_think; +.void(void)move_think; .float move_nextthink; -.void(void) move_blocked; +.void(void)move_blocked; .float move_movetype; .float move_time; @@ -15,11 +15,11 @@ .int move_flags; .int move_watertype; .int move_waterlevel; -.void(void) move_touch; -.void(float, float) contentstransition; +.void(void)move_touch; +.void(float, float)contentstransition; .float move_bounce_factor; .float move_bounce_stopspeed; -.float move_nomonsters; // -1 for MOVE_NORMAL, otherwise a MOVE_ constant +.float move_nomonsters; // -1 for MOVE_NORMAL, otherwise a MOVE_ constant // should match sv_gameplayfix_fixedcheckwatertransition float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1; @@ -34,12 +34,15 @@ float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1; #define TICRATE ticrate #endif -.entity move_groundentity; // FIXME add move_groundnetworkentity? +.entity move_groundentity; // FIXME add move_groundnetworkentity? .float move_suspendedinair; .float move_didgravity; +void _Movetype_WallFriction(vector stepnormal); +int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight); void _Movetype_CheckVelocity(); void _Movetype_CheckWaterTransition(entity ent); +float _Movetype_CheckWater(entity ent); void _Movetype_LinkEdict_TouchAreaGrid(); void _Movetype_LinkEdict(float touch_triggers); float _Movetype_TestEntityPosition(vector ofs); @@ -60,18 +63,18 @@ float _Movetype_UnstickEntity(); const int MAX_CLIP_PLANES = 5; #ifdef CSQC -const int MOVETYPE_NONE = 0; -const int MOVETYPE_ANGLENOCLIP = 1; -const int MOVETYPE_ANGLECLIP = 2; -const int MOVETYPE_WALK = 3; -const int MOVETYPE_STEP = 4; -const int MOVETYPE_FLY = 5; -const int MOVETYPE_TOSS = 6; -const int MOVETYPE_PUSH = 7; -const int MOVETYPE_NOCLIP = 8; -const int MOVETYPE_FLYMISSILE = 9; -const int MOVETYPE_BOUNCE = 10; -const int MOVETYPE_BOUNCEMISSILE = 11; // Like bounce but doesn't lose speed on bouncing +const int MOVETYPE_NONE = 0; +const int MOVETYPE_ANGLENOCLIP = 1; +const int MOVETYPE_ANGLECLIP = 2; +const int MOVETYPE_WALK = 3; +const int MOVETYPE_STEP = 4; +const int MOVETYPE_FLY = 5; +const int MOVETYPE_TOSS = 6; +const int MOVETYPE_PUSH = 7; +const int MOVETYPE_NOCLIP = 8; +const int MOVETYPE_FLYMISSILE = 9; +const int MOVETYPE_BOUNCE = 10; +const int MOVETYPE_BOUNCEMISSILE = 11; // Like bounce but doesn't lose speed on bouncing const int MOVETYPE_FOLLOW = 12; const int MOVETYPE_FLY_WORLDONLY = 33; diff --git a/qcsrc/common/movetypes/push.qc b/qcsrc/common/movetypes/push.qc index 7ae5e2eb5..1f563f58d 100644 --- a/qcsrc/common/movetypes/push.qc +++ b/qcsrc/common/movetypes/push.qc @@ -1,171 +1,161 @@ -void _Movetype_PushMove(float dt) // SV_PushMove +void _Movetype_PushMove(float dt) // SV_PushMove { - bool rotated; - int savesolid; - float movetime2, pushltime; - vector move, move1, moveangle, pushorig, pushang; - vector a; - vector pivot; - entity oldself; - entity check; - - if(self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0') + if (self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0') { self.move_ltime += dt; return; } - switch(self.solid) + switch (self.solid) { - // LordHavoc: valid pusher types - case SOLID_BSP: - case SOLID_BBOX: - case SOLID_SLIDEBOX: - case SOLID_CORPSE: // LordHavoc: this would be weird... - break; - // LordHavoc: no collisions - case SOLID_NOT: - case SOLID_TRIGGER: - self.move_origin = self.move_origin + dt * self.move_velocity; - self.move_angles = self.move_angles + dt * self.move_avelocity; - self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0)); - self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0)); - self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0)); - self.move_ltime += dt; - _Movetype_LinkEdict(true); - return; - default: - dprintf("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid); - return; + // LordHavoc: valid pusher types + case SOLID_BSP: + case SOLID_BBOX: + case SOLID_SLIDEBOX: + case SOLID_CORPSE: // LordHavoc: this would be weird... + break; + // LordHavoc: no collisions + case SOLID_NOT: + case SOLID_TRIGGER: + self.move_origin = self.move_origin + dt * self.move_velocity; + self.move_angles = self.move_angles + dt * self.move_avelocity; + self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0)); + self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0)); + self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0)); + self.move_ltime += dt; + _Movetype_LinkEdict(true); + return; + default: + dprintf("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid); + return; } - rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0; + bool rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0; - movetime2 = dt; + vector move1 = self.move_velocity * dt; + vector moveangle = self.move_avelocity * dt; - move1 = self.move_velocity * movetime2; - moveangle = self.move_avelocity * movetime2; + makevectors_matrix(-moveangle); - a = -moveangle; - makevectors_matrix(a); - - pushorig = self.move_origin; - pushang = self.move_angles; - pushltime = self.move_ltime; +// vector pushorig = self.move_origin; +// vector pushang = self.move_angles; +// float pushltime = self.move_ltime; // move the pusher to its final position self.move_origin = self.move_origin + dt * self.move_velocity; self.move_angles = self.move_angles + dt * self.move_avelocity; - + self.move_ltime += dt; _Movetype_LinkEdict(true); - savesolid = self.solid; + int savesolid = self.solid; - if(self.move_movetype != MOVETYPE_FAKEPUSH) - for(check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain) + if (self.move_movetype != MOVETYPE_FAKEPUSH) { - switch(check.move_movetype) + for (entity check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain) { - case MOVETYPE_NONE: - case MOVETYPE_PUSH: - case MOVETYPE_FOLLOW: - case MOVETYPE_NOCLIP: - case MOVETYPE_FLY_WORLDONLY: - continue; - default: - break; - } - - if(check.owner == self) - continue; - - if(self.owner == check) - continue; - - pivot = check.mins + 0.5 * (check.maxs - check.mins); - - if (rotated) - { - vector org2; - vector org = check.move_origin - self.move_origin; - org = org + pivot; - org2_x = dotproduct(org, v_forward); - org2_y = dotproduct(org, v_right); - org2_z = dotproduct(org, v_up); - move = org2 - org; - move = move + move1; - } - else - move = move1; - - // physics objects need better collisions than this code can do - if(check.move_movetype == 32) // MOVETYPE_PHYSICS - { - check.move_origin = check.move_origin + move; - oldself = self; + switch (check.move_movetype) + { + case MOVETYPE_NONE: + case MOVETYPE_PUSH: + case MOVETYPE_FOLLOW: + case MOVETYPE_NOCLIP: + case MOVETYPE_FLY_WORLDONLY: + continue; + default: + break; + } + + if (check.owner == self) + continue; + + if (self.owner == check) + continue; + + vector pivot = check.mins + 0.5 * (check.maxs - check.mins); + vector move; + if (rotated) + { + vector org = (check.move_origin - self.move_origin) + pivot; + vector org2; + org2.x = org * v_forward; + org2.y = org * v_right; + org2.z = org * v_up; + move = (org2 - org) + move1; + } + else + { + move = move1; + } + + // physics objects need better collisions than this code can do + if (check.move_movetype == 32) // MOVETYPE_PHYSICS + { + check.move_origin = check.move_origin + move; + entity oldself = self; + self = check; + _Movetype_LinkEdict(true); + self = oldself; + continue; + } + + // try moving the contacted entity + self.solid = SOLID_NOT; + entity oldself = self; self = check; - _Movetype_LinkEdict(true); - self = oldself; - continue; - } - - // try moving the contacted entity - self.solid = SOLID_NOT; - oldself = self; - self = check; - if(!_Movetype_PushEntity(move, true)) - { + if (!_Movetype_PushEntity(move, true)) + { + self = oldself; + // entity "check" got teleported + check.move_angles_y += trace_fraction * moveangle.y; + self.solid = savesolid; + continue; // pushed enough + } self = oldself; - // entity "check" got teleported - check.move_angles_y += trace_fraction * moveangle_y; + // FIXME: turn players specially + check.move_angles_y += trace_fraction * moveangle.y; self.solid = savesolid; - continue; // pushed enough + + // this trace.fraction < 1 check causes items to fall off of pushers + // if they pass under or through a wall + // the groundentity check causes items to fall off of ledges + if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self)) + check.move_flags &= ~FL_ONGROUND; } - self = oldself; - // FIXME: turn players specially - check.move_angles_y += trace_fraction * moveangle_y; - self.solid = savesolid; - - // this trace.fraction < 1 check causes items to fall off of pushers - // if they pass under or through a wall - // the groundentity check causes items to fall off of ledges - if(check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self)) - check.move_flags &= ~FL_ONGROUND; } - self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0)); - self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0)); - self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0)); + self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0)); + self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0)); + self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0)); } -void _Movetype_Physics_Pusher(float dt) // SV_Physics_Pusher +void _Movetype_Physics_Pusher(float dt) // SV_Physics_Pusher { - float thinktime, oldltime, movetime; - - oldltime = self.move_ltime; - - thinktime = self.move_nextthink; - if(thinktime < self.move_ltime + dt) + float oldltime = self.move_ltime; + float thinktime = self.move_nextthink; + float movetime; + if (thinktime < self.move_ltime + dt) { movetime = thinktime - self.move_ltime; - if(movetime < 0) + if (movetime < 0) movetime = 0; } else + { movetime = dt; + } - if(movetime) + if (movetime) // advances self.move_ltime if not blocked _Movetype_PushMove(movetime); - if(thinktime > oldltime && thinktime <= self.move_ltime) + if (thinktime > oldltime && thinktime <= self.move_ltime) { self.move_nextthink = 0; self.move_time = time; other = world; - if(self.move_think) + if (self.move_think) self.move_think(); } } diff --git a/qcsrc/common/movetypes/toss.qc b/qcsrc/common/movetypes/toss.qc index df9c9b8e3..6ed0407eb 100644 --- a/qcsrc/common/movetypes/toss.qc +++ b/qcsrc/common/movetypes/toss.qc @@ -1,14 +1,18 @@ #include "../physics.qh" -void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss +void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss { - if(self.move_flags & FL_ONGROUND) + if (self.move_flags & FL_ONGROUND) { - if(self.move_velocity_z >= 1/32) + if (self.move_velocity.z >= 1 / 32) + { self.move_flags &= ~FL_ONGROUND; - else if(!self.move_groundentity) + } + else if (!self.move_groundentity) + { return; - else if(self.move_suspendedinair && wasfreed(self.move_groundentity)) + } + else if (self.move_suspendedinair && wasfreed(self.move_groundentity)) { self.move_groundentity = world; return; @@ -19,70 +23,53 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss _Movetype_CheckVelocity(); - if(self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) + if (self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) { self.move_didgravity = 1; - if(GRAVITY_UNAFFECTED_BY_TICRATE) - { - if(self.gravity) - self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY; - else - self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY; - } - else - { - if(self.gravity) - self.move_velocity_z -= dt * self.gravity * PHYS_GRAVITY; - else - self.move_velocity_z -= dt * PHYS_GRAVITY; - } + self.move_velocity_z -= (GRAVITY_UNAFFECTED_BY_TICRATE ? 0.5 : 1) + * dt + * (self.gravity ? self.gravity : 1) + * PHYS_GRAVITY; } self.move_angles = self.move_angles + self.move_avelocity * dt; - float movetime, bump; - movetime = dt; - for(bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump) + float movetime = dt; + for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump) { - vector move; - move = self.move_velocity * movetime; + vector move = self.move_velocity * movetime; _Movetype_PushEntity(move, true); - if(wasfreed(self)) + if (wasfreed(self)) return; - if(trace_startsolid) + if (trace_startsolid) { _Movetype_UnstickEntity(); _Movetype_PushEntity(move, false); - if(wasfreed(self)) + if (wasfreed(self)) return; } - if(trace_fraction == 1) + if (trace_fraction == 1) break; movetime *= 1 - min(1, trace_fraction); - if(self.move_movetype == MOVETYPE_BOUNCEMISSILE) + if (self.move_movetype == MOVETYPE_BOUNCEMISSILE) { self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 2.0); self.move_flags &= ~FL_ONGROUND; } - else if(self.move_movetype == MOVETYPE_BOUNCE) + else if (self.move_movetype == MOVETYPE_BOUNCE) { - float d, bouncefac, bouncestop; - - bouncefac = self.move_bounce_factor; if(!bouncefac) bouncefac = 0.5; - bouncestop = self.move_bounce_stopspeed; if(!bouncestop) bouncestop = 60 / 800; - if(self.gravity) - bouncestop *= self.gravity * PHYS_GRAVITY; - else - bouncestop *= PHYS_GRAVITY; + float bouncefac = self.move_bounce_factor; if (!bouncefac) bouncefac = 0.5; + float bouncestop = self.move_bounce_stopspeed; if (!bouncestop) bouncestop = 60 / 800; + bouncestop *= (self.gravity ? self.gravity : 1) * PHYS_GRAVITY; self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac); - d = trace_plane_normal * self.move_velocity; - if(trace_plane_normal_z > 0.7 && d < bouncestop && d > -bouncestop) + float d = trace_plane_normal * self.move_velocity; + if (trace_plane_normal.z > 0.7 && d < bouncestop && d > -bouncestop) { self.move_flags |= FL_ONGROUND; self.move_groundentity = trace_ent; @@ -90,42 +77,39 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss self.move_avelocity = '0 0 0'; } else + { self.move_flags &= ~FL_ONGROUND; + } } else { self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.0); - if(trace_plane_normal_z > 0.7) + if (trace_plane_normal.z > 0.7) { self.move_flags |= FL_ONGROUND; self.move_groundentity = trace_ent; - if(trace_ent.solid == SOLID_BSP) + if (trace_ent.solid == SOLID_BSP) self.move_suspendedinair = true; self.move_velocity = '0 0 0'; self.move_avelocity = '0 0 0'; } else + { self.move_flags &= ~FL_ONGROUND; + } } // DP revision 8905 (just, WHY...) - if(self.move_movetype == MOVETYPE_BOUNCEMISSILE) + if (self.move_movetype == MOVETYPE_BOUNCEMISSILE) break; // DP revision 8918 (WHY...) - if(self.move_flags & FL_ONGROUND) + if (self.move_flags & FL_ONGROUND) break; } - if(GRAVITY_UNAFFECTED_BY_TICRATE) - if(self.move_didgravity > 0) - if(!(self.move_flags & FL_ONGROUND)) - { - if(self.gravity) - self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY; - else - self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY; - } + if (GRAVITY_UNAFFECTED_BY_TICRATE && self.move_didgravity > 0 && !(self.move_flags & FL_ONGROUND)) + self.move_velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY; _Movetype_CheckWaterTransition(self); } diff --git a/qcsrc/common/movetypes/walk.qc b/qcsrc/common/movetypes/walk.qc new file mode 100644 index 000000000..cbcfc5b39 --- /dev/null +++ b/qcsrc/common/movetypes/walk.qc @@ -0,0 +1,167 @@ +void _Movetype_Physics_Walk(float dt) // SV_WalkMove +{ + vector stepnormal = '0 0 0'; + + // if frametime is 0 (due to client sending the same timestamp twice), don't move + if (dt <= 0) + return; + + if (GAMEPLAYFIX_UNSTICKPLAYERS) + _Movetype_UnstickEntity(); + + bool applygravity = (!_Movetype_CheckWater(self) && self.move_movetype == MOVETYPE_WALK && !(self.move_flags & FL_WATERJUMP)); + + _Movetype_CheckVelocity(); + + // do a regular slide move unless it looks like you ran into a step + bool oldonground = (self.move_flags & FL_ONGROUND); + + vector start_origin = self.move_origin; + vector start_velocity = self.move_velocity; + + int clip = _Movetype_FlyMove(dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0); + + if (GAMEPLAYFIX_DOWNTRACEONGROUND && !(clip & 1)) + { + // only try this if there was no floor in the way in the trace (no, + // this check seems to be not REALLY necessary, because if clip & 1, + // our trace will hit that thing too) + vector upmove = self.move_origin + '0 0 1'; + vector downmove = self.move_origin - '0 0 1'; + int type; + if (self.move_movetype == MOVETYPE_FLYMISSILE) type = MOVE_MISSILE; else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY) + type = MOVE_WORLDONLY; + else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT) + type = MOVE_NOMONSTERS; + else type = MOVE_NORMAL; + tracebox(upmove, self.mins, self.maxs, downmove, type, self); + if (trace_fraction < 1 && trace_plane_normal.z > 0.7) + clip |= 1; // but we HAVE found a floor + } + + // if the move did not hit the ground at any point, we're not on ground + if (!(clip & 1)) + self.move_flags &= ~FL_ONGROUND; + + _Movetype_CheckVelocity(); + _Movetype_LinkEdict(true); + + if (clip & 8) // teleport + return; + + if (self.move_flags & FL_WATERJUMP) + return; + + if (PHYS_NOSTEP) + return; + + vector originalmove_origin = self.move_origin; + vector originalmove_velocity = self.move_velocity; + // originalmove_clip = clip; + int originalmove_flags = self.move_flags; + entity originalmove_groundentity = self.move_groundentity; + + // if move didn't block on a step, return + if (clip & 2) + { + // if move was not trying to move into the step, return + if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125) + return; + + if (self.move_movetype != MOVETYPE_FLY) + { + // return if gibbed by a trigger + if (self.move_movetype != MOVETYPE_WALK) + return; + + // return if attempting to jump while airborn (unless sv_jumpstep) + if (!PHYS_JUMPSTEP) + if (!oldonground && self.move_waterlevel == 0) + return; + } + + // try moving up and forward to go up a step + // back to start pos + self.move_origin = start_origin; + self.move_velocity = start_velocity; + + // move up + vector upmove = '0 0 1' * PHYS_STEPHEIGHT; + if (!_Movetype_PushEntity(upmove, true)) + { + // we got teleported when upstepping... must abort the move + return; + } + + // move forward + self.move_velocity_z = 0; + clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0); + self.move_velocity_z += start_velocity.z; + if (clip & 8) + { + // we got teleported when upstepping... must abort the move + // note that z velocity handling may not be what QC expects here, but we cannot help it + return; + } + + _Movetype_CheckVelocity(); + _Movetype_LinkEdict(true); + + // check for stuckness, possibly due to the limited precision of floats + // in the clipping hulls + if (clip + && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125 + && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125) + { + // Con_Printf("wall\n"); + // stepping up didn't make any progress, revert to original move + self.move_origin = originalmove_origin; + self.move_velocity = originalmove_velocity; + // clip = originalmove_clip; + self.move_flags = originalmove_flags; + self.move_groundentity = originalmove_groundentity; + // now try to unstick if needed + // clip = SV_TryUnstick (ent, oldvel); + return; + } + + // Con_Printf("step - "); + + // extra friction based on view angle + if (clip & 2 && PHYS_WALLFRICTION) + _Movetype_WallFriction(stepnormal); + } + // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground + else if (!GAMEPLAYFIX_STEPDOWN || self.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (self.move_flags & FL_ONGROUND)) + { + return; + } + + // move down + vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt); + if (!_Movetype_PushEntity(downmove, true)) + { + // we got teleported when downstepping... must abort the move + return; + } + + if (trace_fraction < 1 && trace_plane_normal.z > 0.7) + { + // this has been disabled so that you can't jump when you are stepping + // up while already jumping (also known as the Quake2 double jump bug) + } + else + { + // Con_Printf("slope\n"); + // if the push down didn't end up on good ground, use the move without + // the step up. This happens near wall / slope combinations, and can + // cause the player to hop up higher on a slope too steep to climb + self.move_origin = originalmove_origin; + self.move_velocity = originalmove_velocity; + self.move_flags = originalmove_flags; + self.move_groundentity = originalmove_groundentity; + } + + _Movetype_CheckVelocity(); + _Movetype_LinkEdict(true); +} diff --git a/qcsrc/common/movetypes/walk.qh b/qcsrc/common/movetypes/walk.qh new file mode 100644 index 000000000..10493c96f --- /dev/null +++ b/qcsrc/common/movetypes/walk.qh @@ -0,0 +1,6 @@ +#ifndef MOVETYPE_WALK_H +#define MOVETYPE_WALK_H + +void _Movetype_Physics_Walk(float dt); + +#endif diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 728863ad4..01b9755b1 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -1751,6 +1751,9 @@ void CSQC_ClientMovement_PlayerMove_Frame(void) PM_Main(); #ifdef CSQC - self.pmove_flags = self.flags; // TODO + self.pmove_flags = + ((self.flags & FL_DUCKED) ? PMF_DUCKED : 0) | + (!(self.flags & FL_JUMPRELEASED) ? 0 : PMF_JUMP_HELD) | + ((self.flags & FL_ONGROUND) ? PMF_ONGROUND : 0); #endif } diff --git a/qcsrc/common/physics.qh b/qcsrc/common/physics.qh index 52a8e9a56..d5b8f14ac 100644 --- a/qcsrc/common/physics.qh +++ b/qcsrc/common/physics.qh @@ -72,6 +72,10 @@ bool IsFlying(entity a); #define GAMEPLAYFIX_NOGRAVITYONGROUND cvar("sv_gameplayfix_nogravityonground") #define GAMEPLAYFIX_Q2AIRACCELERATE cvar("sv_gameplayfix_q2airaccelerate") #define GAMEPLAYFIX_EASIERWATERJUMP getstati(STAT_GAMEPLAYFIX_EASIERWATERJUMP) + #define GAMEPLAYFIX_DOWNTRACEONGROUND getstati(STAT_GAMEPLAYFIX_DOWNTRACEONGROUND) + #define GAMEPLAYFIX_STEPMULTIPLETIMES getstati(STAT_GAMEPLAYFIX_STEPMULTIPLETIMES) + #define GAMEPLAYFIX_UNSTICKPLAYERS getstati(STAT_GAMEPLAYFIX_UNSTICKPLAYERS) + #define GAMEPLAYFIX_STEPDOWN getstati(STAT_GAMEPLAYFIX_STEPDOWN) #define IS_DUCKED(s) !!(s.flags & FL_DUCKED) #define SET_DUCKED(s) s.flags |= FL_DUCKED @@ -95,6 +99,22 @@ bool IsFlying(entity a); #define PHYS_DOUBLEJUMP getstati(STAT_DOUBLEJUMP) + #define PHYS_BUGRIGS getstati(STAT_BUGRIGS) + #define PHYS_BUGRIGS_ANGLE_SMOOTHING getstati(STAT_BUGRIGS_ANGLE_SMOOTHING) + #define PHYS_BUGRIGS_PLANAR_MOVEMENT getstati(STAT_BUGRIGS_PLANAR_MOVEMENT) + #define PHYS_BUGRIGS_REVERSE_SPEEDING getstati(STAT_BUGRIGS_REVERSE_SPEEDING) + #define PHYS_BUGRIGS_FRICTION_FLOOR getstatf(STAT_BUGRIGS_FRICTION_FLOOR) + #define PHYS_BUGRIGS_AIR_STEERING getstati(STAT_BUGRIGS_AIR_STEERING) + #define PHYS_BUGRIGS_FRICTION_BRAKE getstatf(STAT_BUGRIGS_FRICTION_BRAKE) + #define PHYS_BUGRIGS_ACCEL getstatf(STAT_BUGRIGS_ACCEL) + #define PHYS_BUGRIGS_SPEED_REF getstatf(STAT_BUGRIGS_SPEED_REF) + #define PHYS_BUGRIGS_SPEED_POW getstatf(STAT_BUGRIGS_SPEED_POW) + #define PHYS_BUGRIGS_STEER getstatf(STAT_BUGRIGS_STEER) + #define PHYS_BUGRIGS_FRICTION_AIR getstatf(STAT_BUGRIGS_FRICTION_AIR) + #define PHYS_BUGRIGS_CAR_JUMPING getstatf(STAT_BUGRIGS_CAR_JUMPING) + #define PHYS_BUGRIGS_REVERSE_SPINNING getstatf(STAT_BUGRIGS_REVERSE_SPINNING) + #define PHYS_BUGRIGS_REVERSE_STOPPING getstatf(STAT_BUGRIGS_REVERSE_STOPPING) + #define PHYS_JUMPSPEEDCAP_MIN getstatf(STAT_MOVEVARS_JUMPSPEEDCAP_MIN) #define PHYS_JUMPSPEEDCAP_MAX getstatf(STAT_MOVEVARS_JUMPSPEEDCAP_MAX) #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS getstati(STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS) @@ -130,6 +150,8 @@ bool IsFlying(entity a); #define PHYS_WARSOWBUNNY_TOPSPEED getstatf(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED) #define PHYS_WARSOWBUNNY_TURNACCEL getstatf(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL) + #define PHYS_WALLFRICTION getstati(STAT_MOVEVARS_WALLFRICTION) + #define PHYS_JETPACK_ACCEL_UP getstatf(STAT_JETPACK_ACCEL_UP) #define PHYS_JETPACK_ACCEL_SIDE getstatf(STAT_JETPACK_ACCEL_SIDE) #define PHYS_JETPACK_ANTIGRAVITY getstatf(STAT_JETPACK_ANTIGRAVITY) @@ -139,6 +161,9 @@ bool IsFlying(entity a); #define PHYS_DODGING_FROZEN getstati(STAT_DODGING_FROZEN) + #define PHYS_NOSTEP getstati(STAT_NOSTEP) + #define PHYS_JUMPSTEP getstati(STAT_MOVEVARS_JUMPSTEP) + #elif defined(SVQC) .float stat_sv_airaccel_qw; @@ -163,6 +188,29 @@ bool IsFlying(entity a); .float stat_jetpack_maxspeed_up; .float stat_jetpack_maxspeed_side; .float stat_gameplayfix_easierwaterjump; + .float stat_gameplayfix_downtracesupportsongroundflag; + .float stat_gameplayfix_stepmultipletimes; + .float stat_gameplayfix_unstickplayers; + .float stat_gameplayfix_stepdown; + + .float stat_bugrigs; + .float stat_bugrigs_angle_smoothing; + .float stat_bugrigs_planar_movement; + .float stat_bugrigs_reverse_speeding; + .float stat_bugrigs_friction_floor; + .float stat_bugrigs_air_steering; + .float stat_bugrigs_friction_brake; + .float stat_bugrigs_accel; + .float stat_bugrigs_speed_ref; + .float stat_bugrigs_speed_pow; + .float stat_bugrigs_steer; + .float stat_bugrigs_friction_air; + .float stat_bugrigs_car_jumping; + .float stat_bugrigs_reverse_spinning; + .float stat_bugrigs_reverse_stopping; + + .float stat_nostep; + .float stat_jumpstep; #define PHYS_INPUT_ANGLES(s) s.v_angle #define PHYS_WORLD_ANGLES(s) s.angles @@ -192,6 +240,10 @@ bool IsFlying(entity a); #define GAMEPLAYFIX_NOGRAVITYONGROUND cvar("sv_gameplayfix_nogravityonground") #define GAMEPLAYFIX_Q2AIRACCELERATE autocvar_sv_gameplayfix_q2airaccelerate #define GAMEPLAYFIX_EASIERWATERJUMP cvar("sv_gameplayfix_easierwaterjump") + #define GAMEPLAYFIX_DOWNTRACEONGROUND cvar("sv_gameplayfix_downtracesupportsongroundflag") + #define GAMEPLAYFIX_STEPMULTIPLETIMES cvar("sv_gameplayfix_stepmultipletimes") + #define GAMEPLAYFIX_UNSTICKPLAYERS cvar("sv_gameplayfix_unstickplayers") + #define GAMEPLAYFIX_STEPDOWN cvar("sv_gameplayfix_stepdown") #define IS_DUCKED(s) s.crouch #define SET_DUCKED(s) s.crouch = true @@ -215,6 +267,22 @@ bool IsFlying(entity a); #define PHYS_DOUBLEJUMP autocvar_sv_doublejump + #define PHYS_BUGRIGS g_bugrigs + #define PHYS_BUGRIGS_ANGLE_SMOOTHING g_bugrigs_angle_smoothing + #define PHYS_BUGRIGS_PLANAR_MOVEMENT g_bugrigs_planar_movement + #define PHYS_BUGRIGS_REVERSE_SPEEDING g_bugrigs_reverse_speeding + #define PHYS_BUGRIGS_FRICTION_FLOOR g_bugrigs_friction_floor + #define PHYS_BUGRIGS_AIR_STEERING g_bugrigs_air_steering + #define PHYS_BUGRIGS_FRICTION_BRAKE g_bugrigs_friction_brake + #define PHYS_BUGRIGS_ACCEL g_bugrigs_accel + #define PHYS_BUGRIGS_SPEED_REF g_bugrigs_speed_ref + #define PHYS_BUGRIGS_SPEED_POW g_bugrigs_speed_pow + #define PHYS_BUGRIGS_STEER g_bugrigs_steer + #define PHYS_BUGRIGS_FRICTION_AIR g_bugrigs_friction_air + #define PHYS_BUGRIGS_CAR_JUMPING g_bugrigs_planar_movement_car_jumping + #define PHYS_BUGRIGS_REVERSE_SPINNING g_bugrigs_reverse_spinning + #define PHYS_BUGRIGS_REVERSE_STOPPING g_bugrigs_reverse_stopping + #define PHYS_JUMPSPEEDCAP_MIN autocvar_sv_jumpspeedcap_min #define PHYS_JUMPSPEEDCAP_MAX autocvar_sv_jumpspeedcap_max #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS autocvar_sv_jumpspeedcap_max_disable_on_ramps @@ -250,6 +318,8 @@ bool IsFlying(entity a); #define PHYS_WARSOWBUNNY_TOPSPEED autocvar_sv_warsowbunny_topspeed #define PHYS_WARSOWBUNNY_TURNACCEL autocvar_sv_warsowbunny_turnaccel + #define PHYS_WALLFRICTION cvar("sv_wallfriction") + #define PHYS_JETPACK_ACCEL_UP autocvar_g_jetpack_acceleration_up #define PHYS_JETPACK_ACCEL_SIDE autocvar_g_jetpack_acceleration_side #define PHYS_JETPACK_ANTIGRAVITY autocvar_g_jetpack_antigravity @@ -259,5 +329,8 @@ bool IsFlying(entity a); #define PHYS_DODGING_FROZEN autocvar_sv_dodging_frozen + #define PHYS_NOSTEP cvar("sv_nostep") + #define PHYS_JUMPSTEP cvar("sv_jumpstep") + #endif #endif diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 0095c60a3..c3d67ca1a 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -204,28 +204,28 @@ const int STAT_REVIVE_PROGRESS = 106; // 166 empty? // 167 empty? // 168 empty? -// 169 empty? -// 170 empty? -// 171 empty? -// 172 empty? -// 173 empty? -// 174 empty? -// 175 empty? -// 176 empty? -// 177 empty? -// 178 empty? -// 179 empty? -// 180 empty? -// 181 empty? -// 182 empty? -// 183 empty? -// 184 empty? -// 185 empty? -// 186 empty? -// 187 empty? -// 188 empty? -// 189 empty? -const int STAT_GAMEPLAYFIX_EASIERWATERJUMP = 190; +const int STAT_BUGRIGS_REVERSE_STOPPING = 169; +const int STAT_BUGRIGS_REVERSE_SPINNING = 170; +const int STAT_BUGRIGS_CAR_JUMPING = 171; +const int STAT_BUGRIGS_FRICTION_AIR = 172; +const int STAT_BUGRIGS_STEER = 173; +const int STAT_BUGRIGS_SPEED_POW = 174; +const int STAT_BUGRIGS_SPEED_REF = 175; +const int STAT_BUGRIGS_ACCEL = 176; +const int STAT_BUGRIGS_FRICTION_BRAKE = 177; +const int STAT_BUGRIGS_AIR_STEERING = 178; +const int STAT_BUGRIGS_FRICTION_FLOOR = 179; +const int STAT_BUGRIGS_REVERSE_SPEEDING = 180; +const int STAT_BUGRIGS_PLANAR_MOVEMENT = 181; +const int STAT_BUGRIGS_ANGLE_SMOOTHING = 182; +const int STAT_BUGRIGS = 183; +const int STAT_GAMEPLAYFIX_STEPDOWN = 184; +const int STAT_MOVEVARS_JUMPSTEP = 185; +const int STAT_NOSTEP = 186; +const int STAT_GAMEPLAYFIX_UNSTICKPLAYERS = 187; +const int STAT_GAMEPLAYFIX_STEPMULTIPLETIMES = 188; +const int STAT_GAMEPLAYFIX_DOWNTRACEONGROUND = 189; +const int STAT_GAMEPLAYFIX_EASIERWATERJUMP = 190; const int STAT_MOVEVARS_FRICTION_SLICK = 191; const int STAT_MOVEVARS_FRICTION_ONLAND = 192; const int STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS = 193; diff --git a/qcsrc/common/triggers/trigger/impulse.qc b/qcsrc/common/triggers/trigger/impulse.qc index 601988539..89ca2e03d 100644 --- a/qcsrc/common/triggers/trigger/impulse.qc +++ b/qcsrc/common/triggers/trigger/impulse.qc @@ -35,10 +35,6 @@ void trigger_impulse_touch1() other.lastpushtime = time; if(!pushdeltatime) return; -#ifdef CSQC - print("Touchie!\n"); -#endif - other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime; other.flags &= ~FL_ONGROUND; #ifdef SVQC -- 2.39.2