From 64182c848a1f12d913ce414367d095e4ba30fbd5 Mon Sep 17 00:00:00 2001 From: Spoike Date: Fri, 19 Nov 2004 17:43:55 +0000 Subject: [PATCH] An attempt at more stable NQ physics.... Still doesn't seem right. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@476 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/server/sv_phys.c | 179 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-) diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 2083dc412..9a6d87eff 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -120,7 +120,7 @@ void SV_CheckVelocity (edict_t *ent) if (Length(ent->v.velocity) > sv_maxvelocity.value) { - Con_DPrintf("Slowing %s\n", PR_GetString(svprogfuncs, ent->v.classname)); +// Con_DPrintf("Slowing %s\n", PR_GetString(svprogfuncs, ent->v.classname)); VectorScale (ent->v.velocity, sv_maxvelocity.value/Length(ent->v.velocity), ent->v.velocity); } } @@ -207,7 +207,6 @@ void SV_Impact (edict_t *e1, edict_t *e2) ClipVelocity Slide off of the impacting object -returns the blocked flags (1 = floor, 2 = step / wall) ================== */ #define STOP_EPSILON 0.1 @@ -253,6 +252,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) vec3_t end; float time_left; int blocked; + vec3_t diff; numbumps = 4; @@ -319,6 +319,8 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen VectorCopy (vec3_origin, ent->v.velocity); + if (steptrace) + *steptrace = trace; // save for player extrafriction return 3; } @@ -329,6 +331,10 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) } else { + VectorSubtract(planes[0], trace.plane.normal, diff); + if (Length(diff) < 0.01) + continue; //hit this plane already + VectorCopy (trace.plane.normal, planes[numplanes]); numplanes++; @@ -347,23 +353,29 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (j == numplanes) break; } - + if (i != numplanes) { // go along this plane +// Con_Printf ("%5.1f %5.1f %5.1f ",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); VectorCopy (new_velocity, ent->v.velocity); +// Con_Printf ("%5.1f %5.1f %5.1f\n",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); } else { // go along the crease if (numplanes != 2) { // Con_Printf ("clip velocity, numplanes == %i\n",numplanes); +// Con_Printf ("%5.1f %5.1f %5.1f ",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); VectorCopy (vec3_origin, ent->v.velocity); +// Con_Printf ("%5.1f %5.1f %5.1f\n",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); return 7; } +// Con_Printf ("%5.1f %5.1f %5.1f ",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); CrossProduct (planes[0], planes[1], dir); VectorNormalize(dir); //fixes slow falling in corners d = DotProduct (dir, ent->v.velocity); VectorScale (dir, d, ent->v.velocity); +// Con_Printf ("%5.1f %5.1f %5.1f\n",ent->v.velocity[0], ent->v.velocity[1], ent->v.velocity[2]); } } @@ -1318,6 +1330,7 @@ SV_WalkMove Only used by players ====================== */ +/* #define SMSTEPSIZE 4 void SV_WalkMove (edict_t *ent) { @@ -1474,6 +1487,158 @@ void SV_WalkMove (edict_t *ent) // Con_Printf("down not good\n"); } } +*/ + + +int SV_SetOnGround (edict_t *ent) +{ + vec3_t end; + trace_t trace; + if ((int)ent->v.flags & FL_ONGROUND) + return 1; + end[0] = ent->v.origin[0]; + end[1] = ent->v.origin[1]; + end[2] = ent->v.origin[2] - 1; + trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); + if (trace.fraction < 1 && trace.plane.normal[2] >= 0.7) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent); + return 1; + } + return 0; +} +void SV_WalkMove (edict_t *ent) +{ + int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity; + vec3_t upmove, downmove, start_origin, start_velocity, originalmove_origin, originalmove_velocity; + trace_t downtrace, steptrace; + + SV_CheckVelocity(ent); + + // do a regular slide move unless it looks like you ran into a step + oldonground = (int)ent->v.flags & FL_ONGROUND; + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + + VectorCopy (ent->v.origin, start_origin); + VectorCopy (ent->v.velocity, start_velocity); + + clip = SV_FlyMove (ent, host_frametime, NULL); + + SV_SetOnGround (ent); + SV_CheckVelocity(ent); + + VectorCopy(ent->v.origin, originalmove_origin); + VectorCopy(ent->v.velocity, originalmove_velocity); + originalmove_clip = clip; + originalmove_flags = (int)ent->v.flags; + originalmove_groundentity = ent->v.groundentity; + + if ((int)ent->v.flags & FL_WATERJUMP) + return; + +// if (sv_nostep.value) +// return; + + // 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[0]) < 0.03125 && fabs(start_velocity[1]) < 0.03125) + return; + + if (ent->v.movetype != MOVETYPE_FLY) + { + // return if gibbed by a trigger + if (ent->v.movetype != MOVETYPE_WALK) + return; + + // only step up while jumping if that is enabled +// if (!(sv_jumpstep.value && sv_gameplayfix_stepwhilejumping.value)) + if (!oldonground && ent->v.waterlevel == 0) + return; + } + + // try moving up and forward to go up a step + // back to start pos + VectorCopy (start_origin, ent->v.origin); + VectorCopy (start_velocity, ent->v.velocity); + + // move up + VectorClear (upmove); + upmove[2] = pm_stepheight; + // FIXME: don't link? + SV_PushEntity(ent, upmove); + + // move forward + ent->v.velocity[2] = 0; + clip = SV_FlyMove (ent, host_frametime, &steptrace); + ent->v.velocity[2] += start_velocity[2]; + + SV_CheckVelocity(ent); + + // check for stuckness, possibly due to the limited precision of floats + // in the clipping hulls + if (clip + && fabs(originalmove_origin[1] - ent->v.origin[1]) < 0.03125 + && fabs(originalmove_origin[0] - ent->v.origin[0]) < 0.03125) + { +// Con_Printf("wall\n"); + // stepping up didn't make any progress, revert to original move + VectorCopy(originalmove_origin, ent->v.origin); + VectorCopy(originalmove_velocity, ent->v.velocity); + //clip = originalmove_clip; + ent->v.flags = originalmove_flags; + ent->v.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)// && sv_wallfriction.value) + { +// Con_Printf("wall\n"); + SV_WallFriction (ent, &steptrace); + } + } + else if (/*!sv_gameplayfix_stepdown.integer || */!oldonground || start_velocity[2] > 0 || ((int)ent->v.flags & FL_ONGROUND) || ent->v.waterlevel >= 2) + return; + + // move down + VectorClear (downmove); + downmove[2] = -pm_stepheight + start_velocity[2]*host_frametime; + // FIXME: don't link? + downtrace = SV_PushEntity (ent, downmove); + + if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7) + { + // LordHavoc: disabled this check so you can walk on monsters/players + //if (ent->v->solid == SOLID_BSP) + { + //Con_Printf("onground\n"); + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(svprogfuncs, downtrace.ent); + } + } + 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 + VectorCopy(originalmove_origin, ent->v.origin); + VectorCopy(originalmove_velocity, ent->v.velocity); + //clip = originalmove_clip; + ent->v.flags = originalmove_flags; + ent->v.groundentity = originalmove_groundentity; + } + + SV_SetOnGround (ent); + SV_CheckVelocity(ent); +} @@ -1538,6 +1703,9 @@ void SV_Physics_Client (edict_t *ent, int num) // if (fabs(oldvel - ent->v.velocity[0])> 100) // Con_Printf("grav: %f -> %f\n", oldvel, ent->v.velocity[0]); +// if (SV_TestEntityPosition(ent)) +// Con_Printf("Player starts stuck\n"); + SV_CheckStuck (ent); // if (fabs(oldvel - ent->v.velocity[0])> 100) @@ -1545,6 +1713,9 @@ void SV_Physics_Client (edict_t *ent, int num) SV_WalkMove (ent); +// if (SV_TestEntityPosition(ent)) +// Con_Printf("Player ends stuck\n"); + // if (fabs(oldvel - ent->v.velocity[0])> 100) // Con_Printf("walk: %f -> %f\n", oldvel, ent->v.velocity[0]); @@ -1788,6 +1959,8 @@ qboolean SV_Physics (void) // don't bother running a frame if sys_ticrate seconds haven't passed host_frametime = realtime - old_time; + if (host_frametime < -1) + old_time = 0; if (host_frametime < sv_mintic.value) return false; if (host_frametime > sv_maxtic.value)