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_separation = {0, "sv_gameplayfix_nudgeoutofsolid_separation", "0.03125", "keep objects this distance apart to prevent collision issues on seams"};
+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_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"};
Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse);
Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse_allowsuspendeditems);
Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid);
- Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid_separation);
+ Cvar_RegisterVariable (&sv_gameplayfix_nudgeoutofsolid_bias);
Cvar_RegisterVariable (&sv_gameplayfix_q2airaccelerate);
Cvar_RegisterVariable (&sv_gameplayfix_nogravityonground);
Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
*/
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;
- 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);
+ VectorCopy(ent->fields.server->origin, original);
+ VectorAdd (ent->fields.server->origin, push, end);
- if (movetype == MOVETYPE_FLYMISSILE)
+ if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
type = MOVE_MISSILE;
- else if (solid == SOLID_TRIGGER || solid == SOLID_NOT)
+ else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
type = MOVE_NOMONSTERS; // only clip against bmodels
else
type = MOVE_NORMAL;
- *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
+ *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;
+ }
+ }
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);