From: havoc Date: Mon, 4 Feb 2008 01:28:39 +0000 (+0000) Subject: modified droptofloor to try a downward trace from the bottom center of X-Git-Tag: xonotic-v0.1.0preview~2447 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1e6375f21ca24d406643b6ab57ab8fa55eb917cf;p=xonotic%2Fdarkplaces.git modified droptofloor to try a downward trace from the bottom center of the object if it is stuck, this manages to 'correctly' place many badly placed entities in quake maps additionally modified droptofloor to first try unsticking the entity before dropping it (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8069 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/server.h b/server.h index ac5e1edf..4105076a 100644 --- a/server.h +++ b/server.h @@ -372,6 +372,7 @@ extern cvar_t sv_friction; extern cvar_t sv_gameplayfix_blowupfallenzombies; extern cvar_t sv_gameplayfix_delayprojectiles; extern cvar_t sv_gameplayfix_droptofloorstartsolid; +extern cvar_t sv_gameplayfix_droptofloorstartsolid_nudgetocorrect; extern cvar_t sv_gameplayfix_easierwaterjump; extern cvar_t sv_gameplayfix_findradiusdistancetobox; extern cvar_t sv_gameplayfix_grenadebouncedownslopes; @@ -467,6 +468,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean // if touchtriggers, calls prog functions for the intersected triggers void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers); +// move an entity that is stuck by small amounts in various directions to try to nudge it back into the collision hull +// returns true if it found a better place +qboolean SV_UnstickEntity (prvm_edict_t *ent); + // calculates hitsupercontentsmask for a generic qc entity int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict); // traces a box move against worldmodel and all entities in the specified area diff --git a/sv_main.c b/sv_main.c index 72a9d326..aee83968 100644 --- a/sv_main.c +++ b/sv_main.c @@ -79,6 +79,7 @@ cvar_t sv_friction = {CVAR_NOTIFY, "sv_friction","4", "how fast you slow down"}; cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzombies", "1", "causes findradius to detect SOLID_NOT entities such as zombies and corpses on the floor, allowing splash damage to apply to them"}; cvar_t sv_gameplayfix_delayprojectiles = {0, "sv_gameplayfix_delayprojectiles", "1", "causes entities to not move on the same frame they are spawned, meaning that projectiles wait until the next frame to perform their first move, giving proper interpolation and rocket trails, but making weapons harder to use at low framerates"}; cvar_t sv_gameplayfix_droptofloorstartsolid = {0, "sv_gameplayfix_droptofloorstartsolid", "1", "prevents items and monsters that start in a solid area from falling out of the level (makes droptofloor treat trace_startsolid as an acceptable outcome)"}; +cvar_t sv_gameplayfix_droptofloorstartsolid_nudgetocorrect = {0, "sv_gameplayfix_droptofloorstartsolid_nudgetocorrect", "1", "tries to nudge stuck items and monsters out of walls before droptofloor is performed"}; cvar_t sv_gameplayfix_easierwaterjump = {0, "sv_gameplayfix_easierwaterjump", "1", "changes water jumping to make it easier to get out of water (exactly like in QuakeWorld)"}; cvar_t sv_gameplayfix_findradiusdistancetobox = {0, "sv_gameplayfix_findradiusdistancetobox", "1", "causes findradius to check the distance to the corner of a box rather than the center of the box, makes findradius detect bmodels such as very large doors that would otherwise be unaffected by splash damage"}; cvar_t sv_gameplayfix_grenadebouncedownslopes = {0, "sv_gameplayfix_grenadebouncedownslopes", "1", "prevents MOVETYPE_BOUNCE (grenades) from getting stuck when fired down a downward sloping surface"}; @@ -349,6 +350,7 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies); Cvar_RegisterVariable (&sv_gameplayfix_delayprojectiles); Cvar_RegisterVariable (&sv_gameplayfix_droptofloorstartsolid); + Cvar_RegisterVariable (&sv_gameplayfix_droptofloorstartsolid_nudgetocorrect); Cvar_RegisterVariable (&sv_gameplayfix_easierwaterjump); Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox); Cvar_RegisterVariable (&sv_gameplayfix_grenadebouncedownslopes); @@ -430,6 +432,8 @@ void SV_Init (void) { // hipnotic mission pack has issues in their 'friendly monster' ai, which seem to attempt to attack themselves for some reason when findradius() returns non-solid entities. 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); } if (gamemode == GAME_ROGUE) { diff --git a/sv_phys.c b/sv_phys.c index dd59d76e..aed6049a 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -1374,21 +1374,37 @@ static float unstickoffsets[] = 1, 1, 0, 0, 0, -1, 0, 0, 1, + 0, 0, -2, 0, 0, 2, + 0, 0, -3, 0, 0, 3, + 0, 0, -4, 0, 0, 4, + 0, 0, -5, 0, 0, 5, + 0, 0, -6, 0, 0, 6, + 0, 0, -7, 0, 0, 7, + 0, 0, -8, 0, 0, 8, + 0, 0, -9, 0, 0, 9, + 0, 0, -10, 0, 0, 10, + 0, 0, -11, 0, 0, 11, + 0, 0, -12, 0, 0, 12, + 0, 0, -13, 0, 0, 13, + 0, 0, -14, 0, 0, 14, + 0, 0, -15, 0, 0, 15, + 0, 0, -16, 0, 0, 16, + 0, 0, -17, 0, 0, 17, }; @@ -1432,13 +1448,13 @@ void SV_CheckStuck (prvm_edict_t *ent) Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname)); } -static void SV_UnstickEntity (prvm_edict_t *ent) +qboolean SV_UnstickEntity (prvm_edict_t *ent) { int i; // if not stuck in a bmodel, just return if (!SV_TestEntityPosition(ent, vec3_origin)) - return; + return true; for (i = 0;i < (int)(sizeof(unstickoffsets) / sizeof(unstickoffsets[0]));i += 3) { @@ -1446,12 +1462,13 @@ static void SV_UnstickEntity (prvm_edict_t *ent) { Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname), unstickoffsets[i+0], unstickoffsets[i+1], unstickoffsets[i+2]); SV_LinkEdict (ent, true); - return; + return true; } } if (developer.integer >= 100) Con_Printf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname)); + return false; } diff --git a/svvm_cmds.c b/svvm_cmds.c index 2d23a5dd..fdd0293b 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -970,18 +970,52 @@ static void VM_SV_droptofloor (void) VectorCopy (ent->fields.server->origin, end); end[2] -= 256; - trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer) + SV_UnstickEntity(ent); - if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)) - { - if (trace.fraction < 1) + trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer) + { + vec3_t offset, org; + VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]); + VectorAdd(ent->fields.server->origin, offset, org); + trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + VectorSubtract(trace.endpos, offset, trace.endpos); + if (trace.startsolid) + { + Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); + SV_UnstickEntity(ent); + SV_LinkEdict (ent, false); + ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; + ent->fields.server->groundentity = 0; + PRVM_G_FLOAT(OFS_RETURN) = 1; + } + else if (trace.fraction < 1) + { + Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); VectorCopy (trace.endpos, ent->fields.server->origin); - SV_LinkEdict (ent, false); - ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; - ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); - PRVM_G_FLOAT(OFS_RETURN) = 1; - // if support is destroyed, keep suspended (gross hack for floating items in various maps) - ent->priv.server->suspendedinairflag = true; + SV_UnstickEntity(ent); + SV_LinkEdict (ent, false); + ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; + ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); + PRVM_G_FLOAT(OFS_RETURN) = 1; + // if support is destroyed, keep suspended (gross hack for floating items in various maps) + ent->priv.server->suspendedinairflag = true; + } + } + else + { + if (trace.fraction != 1) + { + if (trace.fraction < 1) + VectorCopy (trace.endpos, ent->fields.server->origin); + SV_LinkEdict (ent, false); + ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; + ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); + PRVM_G_FLOAT(OFS_RETURN) = 1; + // if support is destroyed, keep suspended (gross hack for floating items in various maps) + ent->priv.server->suspendedinairflag = true; + } } }