reworked sv_gameplayfix_nudgeoutofsolid, it now begins with an enlarged
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 28 May 2011 17:50:38 +0000 (17:50 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 28 May 2011 17:50:38 +0000 (17:50 +0000)
start position test and nudges out of solids, then does the move, this
should reduce collision issues with triangle mesh brushes in steelstorm,
renamed sv_gameplayfix_nudgeoutofsolid_bias to
sv_gameplayfix_nudgeoutofsolid_separation with 0.03125 as default

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11169 d7cf8633-e32d-0410-b094-e92efae38249

server.h
sv_main.c
sv_phys.c

index a345d3b..ccadc9e 100644 (file)
--- a/server.h
+++ b/server.h
@@ -437,7 +437,7 @@ extern cvar_t sv_gameplayfix_multiplethinksperframe;
 extern cvar_t sv_gameplayfix_noairborncorpse;
 extern cvar_t sv_gameplayfix_noairborncorpse_allowsuspendeditems;
 extern cvar_t sv_gameplayfix_nudgeoutofsolid;
-extern cvar_t sv_gameplayfix_nudgeoutofsolid_bias;
+extern cvar_t sv_gameplayfix_nudgeoutofsolid_separation;
 extern cvar_t sv_gameplayfix_setmodelrealbox;
 extern cvar_t sv_gameplayfix_slidemoveprojectiles;
 extern cvar_t sv_gameplayfix_stepdown;
index 05e6db0..a01eb9d 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -108,7 +108,7 @@ cvar_t sv_gameplayfix_multiplethinksperframe = {0, "sv_gameplayfix_multiplethink
 cvar_t sv_gameplayfix_noairborncorpse = {0, "sv_gameplayfix_noairborncorpse", "1", "causes entities (corpses, items, etc) sitting ontop of moving entities (players) to fall when the moving entity (player) is no longer supporting them"};
 cvar_t sv_gameplayfix_noairborncorpse_allowsuspendeditems = {0, "sv_gameplayfix_noairborncorpse_allowsuspendeditems", "1", "causes entities sitting ontop of objects that are instantaneously remove to float in midair (special hack to allow a common level design trick for floating items)"};
 cvar_t sv_gameplayfix_nudgeoutofsolid = {0, "sv_gameplayfix_nudgeoutofsolid", "1", "attempts to fix physics errors (where an object ended up in solid for some reason)"};
-cvar_t sv_gameplayfix_nudgeoutofsolid_bias = {0, "sv_gameplayfix_nudgeoutofsolid_bias", "0", "over-correction on nudgeoutofsolid logic, to prevent constant contact"};
+cvar_t sv_gameplayfix_nudgeoutofsolid_separation = {0, "sv_gameplayfix_nudgeoutofsolid_separation", "0.03125", "keep objects this distance apart to prevent collision issues on seams"};
 cvar_t sv_gameplayfix_q2airaccelerate = {0, "sv_gameplayfix_q2airaccelerate", "0", "Quake2-style air acceleration"};
 cvar_t sv_gameplayfix_nogravityonground = {0, "sv_gameplayfix_nogravityonground", "0", "turn off gravity when on ground (to get rid of sliding)"};
 cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1", "fixes a bug in Quake that made setmodel always set the entity box to ('-16 -16 -16', '16 16 16') rather than properly checking the model box, breaks some poorly coded mods"};
@@ -509,7 +509,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse);
        Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse_allowsuspendeditems);
        Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid);
-       Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid_bias);
+       Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid_separation);
        Cvar_RegisterVariable (&sv_gameplayfix_q2airaccelerate);
        Cvar_RegisterVariable (&sv_gameplayfix_nogravityonground);
        Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
index 343b1dc..61a5dc4 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -1460,39 +1460,68 @@ Returns true if the push did not result in the entity being teleported by QC cod
 */
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
 {
+       int solid;
+       int movetype;
        int type;
        int bump;
+       vec3_t mins, maxs;
        vec3_t original, original_velocity;
+       vec3_t start;
        vec3_t end;
 
-       VectorCopy(ent->fields.server->origin, original);
-       VectorAdd (ent->fields.server->origin, push, end);
+       solid = (int)ent->fields.server->solid;
+       movetype = (int)ent->fields.server->movetype;
+       VectorCopy(ent->fields.server->mins, mins);
+       VectorCopy(ent->fields.server->maxs, maxs);
+
+       // move start position out of solids
+       if (sv_gameplayfix_nudgeoutofsolid.integer && sv_gameplayfix_nudgeoutofsolid_separation.value >= 0)
+       {
+               trace_t stucktrace;
+               vec3_t stuckorigin;
+               vec3_t stuckmins, stuckmaxs;
+               vec_t nudge;
+               vec_t separation = sv_gameplayfix_nudgeoutofsolid_separation.value;
+               if (sv.worldmodel && sv.worldmodel->brushq1.numclipnodes)
+                       separation = 0.0f; // when using hulls, it can not be enlarged
+               VectorCopy(ent->fields.server->origin, stuckorigin);
+               VectorCopy(mins, stuckmins);
+               VectorCopy(maxs, stuckmaxs);
+               stuckmins[0] -= separation;
+               stuckmins[1] -= separation;
+               stuckmins[2] -= separation;
+               stuckmaxs[0] += separation;
+               stuckmaxs[1] += separation;
+               stuckmaxs[2] += separation;
+               for (bump = 0;bump < 10;bump++)
+               {
+                       stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
+                       if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
+                       {
+                               // found a good location, use it
+                               VectorCopy(stuckorigin, ent->fields.server->origin);
+                               break;
+                       }
+                       nudge = -stucktrace.startdepth;
+                       VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin);
+               }
+       }
+
+       VectorCopy(ent->fields.server->origin, start);
+       VectorAdd(start, push, end);
 
-       if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
+       if (movetype == MOVETYPE_FLYMISSILE)
                type = MOVE_MISSILE;
-       else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
+       else if (solid == SOLID_TRIGGER || solid == SOLID_NOT)
                type = MOVE_NOMONSTERS; // only clip against bmodels
        else
                type = MOVE_NORMAL;
 
-       *trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
-       bump = 0;
-       while (trace->bmodelstartsolid && sv_gameplayfix_nudgeoutofsolid.integer)
-       {
-               vec_t nudge = -trace->startdepth + sv_gameplayfix_nudgeoutofsolid_bias.value;
-               VectorMA(ent->fields.server->origin, nudge, trace->startdepthnormal, ent->fields.server->origin);
-               *trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
-               bump++;
-               if (bump > 10)
-               {
-                       VectorCopy(original, ent->fields.server->origin);
-                       break;
-               }
-       }
+       *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
        if (trace->bmodelstartsolid && failonbmodelstartsolid)
                return true;
 
-       VectorCopy (trace->endpos, ent->fields.server->origin);
+       VectorCopy(trace->endpos, ent->fields.server->origin);
 
        VectorCopy(ent->fields.server->origin, original);
        VectorCopy(ent->fields.server->velocity, original_velocity);