]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
modified droptofloor to try a downward trace from the bottom center of
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 4 Feb 2008 01:28:39 +0000 (01:28 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 4 Feb 2008 01:28:39 +0000 (01:28 +0000)
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

server.h
sv_main.c
sv_phys.c
svvm_cmds.c

index ac5e1edfd8ae41fe74f27d833af12049c9e9a7ed..4105076a1437920a10dc7b623b5286fd0d80e93e 100644 (file)
--- 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
index 72a9d326accf207e6c5af911c6a0bfa8bbf72f3c..aee839684f545fe84a8c5af8b2ed539cc3ef7d6a 100644 (file)
--- 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)
        {
index dd59d76eceec9b0ad23070f9cfc5130db4554965..aed6049af5acfaa3ed12dcb6263eb1163bfa2a7f 100644 (file)
--- 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;
 }
 
 
index 2d23a5dd4ea069c49ea4194808ab6d8e231b191f..fdd0293b1c982458c1f401eb5eccf41269b9f5a2 100644 (file)
@@ -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;
+               }
        }
 }