]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
allow multiple steps in one move
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 31 Jan 2010 00:26:30 +0000 (00:26 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 31 Jan 2010 00:26:30 +0000 (00:26 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9896 d7cf8633-e32d-0410-b094-e92efae38249

server.h
sv_main.c
sv_phys.c

index 94a53cf505a03db4d2e0a2ce60c7da158d48f596..62d11f0d21669cd686975499313ae59c75b96411 100644 (file)
--- a/server.h
+++ b/server.h
@@ -434,6 +434,7 @@ extern cvar_t sv_gameplayfix_setmodelrealbox;
 extern cvar_t sv_gameplayfix_slidemoveprojectiles;
 extern cvar_t sv_gameplayfix_stepdown;
 extern cvar_t sv_gameplayfix_stepwhilejumping;
+extern cvar_t sv_gameplayfix_stepmultipletimes;
 extern cvar_t sv_gameplayfix_swiminbmodels;
 extern cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag;
 extern cvar_t sv_gameplayfix_downtracesupportsongroundflag;
@@ -445,7 +446,6 @@ extern cvar_t sv_maxairspeed;
 extern cvar_t sv_maxrate;
 extern cvar_t sv_maxspeed;
 extern cvar_t sv_maxvelocity;
-extern cvar_t sv_newflymove;
 extern cvar_t sv_nostep;
 extern cvar_t sv_playerphysicsqc;
 extern cvar_t sv_progs;
index 6c65024388e224be23ca84b215c9bfa98bf6aa6c..c264371961086318096a72bca25b4c449607243c 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -104,6 +104,7 @@ cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1
 cvar_t sv_gameplayfix_slidemoveprojectiles = {0, "sv_gameplayfix_slidemoveprojectiles", "1", "allows MOVETYPE_FLY/FLYMISSILE/TOSS/BOUNCE/BOUNCEMISSILE entities to finish their move in a frame even if they hit something, fixes 'gravity accumulation' bug for grenades on steep slopes"};
 cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "0", "attempts to step down stairs, not just up them (prevents the familiar thud..thud..thud.. when running down stairs and slopes)"};
 cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping", "1", "applies step-up onto a ledge even while airborn, useful if you would otherwise just-miss the floor when running across small areas with gaps (for instance running across the moving platforms in dm2, or jumping to the megahealth and red armor in dm2 rather than using the bridge)"};
+cvar_t sv_gameplayfix_stepmultipletimes = {0, "sv_gameplayfix_stepmultipletimes", "1", "applies step-up onto a ledge more than once in a single frame, when running quickly up stairs"};
 cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1", "causes pointcontents (used to determine if you are in a liquid) to check bmodel entities as well as the world model, so you can swim around in (possibly moving) water bmodel entities"};
 cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {0, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
 cvar_t sv_gameplayfix_downtracesupportsongroundflag = {0, "sv_gameplayfix_downtracesupportsongroundflag", "1", "prevents very short moves from clearing onground (which may make the player stick to the floor at high netfps)"};
@@ -115,7 +116,6 @@ cvar_t sv_maxairspeed = {0, "sv_maxairspeed", "30", "maximum speed a player can
 cvar_t sv_maxrate = {CVAR_SAVE | CVAR_NOTIFY, "sv_maxrate", "1000000", "upper limit on client rate cvar, should reflect your network connection quality"};
 cvar_t sv_maxspeed = {CVAR_NOTIFY, "sv_maxspeed", "320", "maximum speed a player can accelerate to when on ground (can be exceeded by tricks)"};
 cvar_t sv_maxvelocity = {CVAR_NOTIFY, "sv_maxvelocity","2000", "universal speed limit on all entities"};
-cvar_t sv_newflymove = {CVAR_NOTIFY, "sv_newflymove", "0", "enables simpler/buggier player physics (not recommended)"};
 cvar_t sv_nostep = {CVAR_NOTIFY, "sv_nostep","0", "prevents MOVETYPE_STEP entities (monsters) from moving"};
 cvar_t sv_playerphysicsqc = {CVAR_NOTIFY, "sv_playerphysicsqc", "1", "enables QuakeC function to override player physics"};
 cvar_t sv_progs = {0, "sv_progs", "progs.dat", "selects which quakec progs.dat file to run" };
@@ -416,6 +416,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_slidemoveprojectiles);
        Cvar_RegisterVariable (&sv_gameplayfix_stepdown);
        Cvar_RegisterVariable (&sv_gameplayfix_stepwhilejumping);
+       Cvar_RegisterVariable (&sv_gameplayfix_stepmultipletimes);
        Cvar_RegisterVariable (&sv_gameplayfix_swiminbmodels);
        Cvar_RegisterVariable (&sv_gameplayfix_upwardvelocityclearsongroundflag);
        Cvar_RegisterVariable (&sv_gameplayfix_downtracesupportsongroundflag);
@@ -427,7 +428,6 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_maxrate);
        Cvar_RegisterVariable (&sv_maxspeed);
        Cvar_RegisterVariable (&sv_maxvelocity);
-       Cvar_RegisterVariable (&sv_newflymove);
        Cvar_RegisterVariable (&sv_nostep);
        Cvar_RegisterVariable (&sv_playerphysicsqc);
        Cvar_RegisterVariable (&sv_progs);
@@ -507,8 +507,8 @@ void SV_Init (void)
                Cvar_SetValueQuick (&sv_gameplayfix_blowupfallenzombies, 0);
                // hipnotic mission pack has issues with bobbing water entities 'jittering' between different heights on alternate frames at the default 0.0138889 ticrate, 0.02 avoids this issue
                Cvar_SetValueQuick (&sys_ticrate, 0.02);
-               // hipnotic mission pack has issues in their proximity mine sticking code, which causes them to bounce off.                                                                                     
-               Cvar_SetValueQuick (&sv_gameplayfix_slidemoveprojectiles, 0);                                                                                                                                   
+               // hipnotic mission pack has issues in their proximity mine sticking code, which causes them to bounce off.
+               Cvar_SetValueQuick (&sv_gameplayfix_slidemoveprojectiles, 0);
        }
        if (gamemode == GAME_ROGUE)
        {
index b62de11953fd02ba6afecc467c53c16d0d58b638..5c0919776639cbfe96a98fb1fd89f7c1c127eafd 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -1223,7 +1223,7 @@ If stepnormal is not NULL, the plane normal of any vertical wall hit will be sto
 static float SV_Gravity (prvm_edict_t *ent);
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink);
 #define MAX_CLIP_PLANES 5
-static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask)
+static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
 {
        int blocked, bumpcount;
        int i, j, numplanes;
@@ -1260,9 +1260,6 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
                        break;
 
                VectorScale(ent->fields.server->velocity, time_left, push);
-#if 0
-               VectorAdd(ent->fields.server->origin, push, end);
-#endif
                if(!SV_PushEntity(&trace, ent, push, false, false))
                {
                        // we got teleported by a touch function
@@ -1271,64 +1268,6 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
                        break;
                }
 
-#if 0
-               //if (trace.fraction < 0.002)
-               {
-#if 1
-                       vec3_t start;
-                       trace_t testtrace;
-                       VectorCopy(ent->fields.server->origin, start);
-                       start[2] += 3;//0.03125;
-                       VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
-                       end[2] += 3;//0.03125;
-                       testtrace = SV_TraceBox(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
-                       if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->fields.server->velocity) < DotProduct(testtrace.plane.normal, ent->fields.server->velocity)))
-                       {
-                               Con_Printf("got further (new %f > old %f)\n", testtrace.fraction, trace.fraction);
-                               trace = testtrace;
-                       }
-#endif
-#if 0
-                       //j = -1;
-                       for (i = 0;i < numplanes;i++)
-                       {
-                               VectorCopy(ent->fields.server->origin, start);
-                               VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
-                               VectorMA(start, 3, planes[i], start);
-                               VectorMA(end, 3, planes[i], end);
-                               testtrace = SV_TraceBox(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
-                               if (trace.fraction < testtrace.fraction)
-                               {
-                                       trace = testtrace;
-                                       VectorCopy(start, ent->fields.server->origin);
-                                       //j = i;
-                               }
-                       }
-                       //if (j >= 0)
-                       //      VectorAdd(ent->fields.server->origin, planes[j], start);
-#endif
-               }
-#endif
-
-#if 0
-               Con_Printf("entity %i bump %i: velocity %f %f %f trace %f", ent - prog->edicts, bumpcount, ent->fields.server->velocity[0], ent->fields.server->velocity[1], ent->fields.server->velocity[2], trace.fraction);
-               if (trace.fraction < 1)
-                       Con_Printf(" : %f %f %f", trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
-               Con_Print("\n");
-#endif
-
-#if 0
-               if (trace.bmodelstartsolid)
-               {
-                       // LordHavoc: note: this code is what makes entities stick in place
-                       // if embedded in world only (you can walk through other objects if
-                       // stuck)
-                       // entity is trapped in another solid
-                       VectorClear(ent->fields.server->velocity);
-                       return 3;
-               }
-#endif
-
                if (trace.fraction == 1)
                        break;
                if (trace.plane.normal[2])
@@ -1348,9 +1287,43 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
                                ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
                        }
                }
+               else if (stepheight)
+               {
+                       // step - handle it immediately
+                       vec3_t org;
+                       vec3_t steppush;
+                       trace_t steptrace;
+                       trace_t steptrace2;
+                       trace_t steptrace3;
+                       //Con_Printf("step %f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+                       VectorSet(steppush, 0, 0, stepheight);
+                       VectorCopy(ent->fields.server->origin, org);
+                       SV_PushEntity(&steptrace, ent, steppush, false, false);
+                       //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+                       SV_PushEntity(&steptrace2, ent, push, false, false);
+                       //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+                       VectorSet(steppush, 0, 0, org[2] - ent->fields.server->origin[2]);
+                       SV_PushEntity(&steptrace3, ent, steppush, false, false);
+                       //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+                       // accept the new position if it made some progress...
+                       if (fabs(ent->fields.server->origin[0] - org[0]) >= 0.03125 || fabs(ent->fields.server->origin[1] - org[1]) >= 0.03125)
+                       {
+                               //Con_Printf("accepted (delta %f %f %f)\n", ent->fields.server->origin[0] - org[0], ent->fields.server->origin[1] - org[1], ent->fields.server->origin[2] - org[2]);
+                               trace = steptrace2;
+                               VectorCopy(ent->fields.server->origin, trace.endpos);
+                               time_left *= 1 - trace.fraction;
+                               numplanes = 0;
+                               continue;
+                       }
+                       else
+                       {
+                               //Con_Printf("REJECTED (delta %f %f %f)\n", ent->fields.server->origin[0] - org[0], ent->fields.server->origin[1] - org[1], ent->fields.server->origin[2] - org[2]);
+                               VectorCopy(org, ent->fields.server->origin);
+                       }
+               }
                else
                {
-                       // step
+                       // step - return it to caller
                        blocked |= 2;
                        // save the trace for player extrafriction
                        if (stepnormal)
@@ -1388,47 +1361,42 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
                VectorCopy(trace.plane.normal, planes[numplanes]);
                numplanes++;
 
-               if (sv_newflymove.integer)
-                       ClipVelocity(ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1);
-               else
+               // modify original_velocity so it parallels all of the clip planes
+               for (i = 0;i < numplanes;i++)
                {
-                       // modify original_velocity so it parallels all of the clip planes
-                       for (i = 0;i < numplanes;i++)
+                       ClipVelocity(original_velocity, planes[i], new_velocity, 1);
+                       for (j = 0;j < numplanes;j++)
                        {
-                               ClipVelocity(original_velocity, planes[i], new_velocity, 1);
-                               for (j = 0;j < numplanes;j++)
+                               if (j != i)
                                {
-                                       if (j != i)
-                                       {
-                                               // not ok
-                                               if (DotProduct(new_velocity, planes[j]) < 0)
-                                                       break;
-                                       }
+                                       // not ok
+                                       if (DotProduct(new_velocity, planes[j]) < 0)
+                                               break;
                                }
-                               if (j == numplanes)
-                                       break;
                        }
+                       if (j == numplanes)
+                               break;
+               }
 
-                       if (i != numplanes)
-                       {
-                               // go along this plane
-                               VectorCopy(new_velocity, ent->fields.server->velocity);
-                       }
-                       else
+               if (i != numplanes)
+               {
+                       // go along this plane
+                       VectorCopy(new_velocity, ent->fields.server->velocity);
+               }
+               else
+               {
+                       // go along the crease
+                       if (numplanes != 2)
                        {
-                               // go along the crease
-                               if (numplanes != 2)
-                               {
-                                       VectorClear(ent->fields.server->velocity);
-                                       blocked = 7;
-                                       break;
-                               }
-                               CrossProduct(planes[0], planes[1], dir);
-                               // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
-                               VectorNormalize(dir);
-                               d = DotProduct(dir, ent->fields.server->velocity);
-                               VectorScale(dir, d, ent->fields.server->velocity);
+                               VectorClear(ent->fields.server->velocity);
+                               blocked = 7;
+                               break;
                        }
+                       CrossProduct(planes[0], planes[1], dir);
+                       // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
+                       VectorNormalize(dir);
+                       d = DotProduct(dir, ent->fields.server->velocity);
+                       VectorScale(dir, d, ent->fields.server->velocity);
                }
 
                // if current velocity is against the original velocity,
@@ -2198,7 +2166,7 @@ void SV_WalkMove (prvm_edict_t *ent)
        VectorCopy (ent->fields.server->origin, start_origin);
        VectorCopy (ent->fields.server->velocity, start_velocity);
 
-       clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask);
+       clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0);
 
        if(sv_gameplayfix_downtracesupportsongroundflag.integer)
        if(!(clip & 1))
@@ -2277,7 +2245,7 @@ void SV_WalkMove (prvm_edict_t *ent)
 
                // move forward
                ent->fields.server->velocity[2] = 0;
-               clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask);
+               clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, 0);
                ent->fields.server->velocity[2] += start_velocity[2];
                if(clip & 8)
                {
@@ -2653,7 +2621,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                        {
                                ent->fields.server->flags -= FL_ONGROUND;
                                SV_CheckVelocity(ent);
-                               SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent));
+                               SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
                                SV_LinkEdict(ent);
                                SV_LinkEdict_TouchAreaGrid(ent);
                                ent->priv.server->waterposition_forceupdate = true;
@@ -2665,7 +2633,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                        int hitsound = ent->fields.server->velocity[2] < sv_gravity.value * -0.1;
 
                        SV_CheckVelocity(ent);
-                       SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent));
+                       SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
                        SV_LinkEdict(ent);
                        SV_LinkEdict_TouchAreaGrid(ent);