From 25c09ca585e81bf9eb236a339ae5dcd64f63b679 Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 28 May 2011 17:50:38 +0000 Subject: [PATCH] reworked sv_gameplayfix_nudgeoutofsolid, it now begins with an enlarged 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 | 2 +- sv_main.c | 4 ++-- sv_phys.c | 67 +++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/server.h b/server.h index a345d3be..ccadc9e2 100644 --- 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; diff --git a/sv_main.c b/sv_main.c index 05e6db00..a01eb9de 100644 --- 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); diff --git a/sv_phys.c b/sv_phys.c index 343b1dc9..61a5dc4e 100644 --- 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); -- 2.39.2