clean up of FL_ONGROUND checks in MOVE_TOSS/FLY/FLYMISSILE/BOUNCE/BOUNCEMISSILE/STEP...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Jul 2006 00:02:30 +0000 (00:02 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Jul 2006 00:02:30 +0000 (00:02 +0000)
added sv_gameplayfix_upwardvelocityclearsongroundflag cvar to allow the upward velocity gameplay fix to be disabled if desired

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

server.h
sv_main.c
sv_phys.c

index 8371c75..e2db41c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -135,7 +135,7 @@ typedef struct client_s
 #endif
        // LordHavoc: can be used for prediction or whatever...
        float ping;
-       
+
        // this is used by sv_clmovement_minping code
        double clmovement_disabletimeout;
        // this is used by sv_clmvoement_waitforinput code
@@ -275,6 +275,7 @@ extern cvar_t sv_gameplayfix_setmodelrealbox;
 extern cvar_t sv_gameplayfix_blowupfallenzombies;
 extern cvar_t sv_gameplayfix_findradiusdistancetobox;
 extern cvar_t sv_gameplayfix_qwplayerphysics;
+extern cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag;
 
 extern cvar_t sys_ticrate;
 extern cvar_t sv_fixedframeratesingleplayer;
index 2e45d00..0552bb2 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -51,6 +51,7 @@ cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1
 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_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_qwplayerphysics = {0, "sv_gameplayfix_qwplayerphysics", "1", "changes water jumping to make it easier to get out of water, and prevents friction on landing when bunnyhopping"};
+cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {0, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
 
 cvar_t sv_progs = {0, "sv_progs", "progs.dat", "selects which quakec progs.dat file to run" };
 
@@ -110,6 +111,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies);
        Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
        Cvar_RegisterVariable (&sv_gameplayfix_qwplayerphysics);
+       Cvar_RegisterVariable (&sv_gameplayfix_upwardvelocityclearsongroundflag);
        Cvar_RegisterVariable (&sv_protocolname);
        Cvar_RegisterVariable (&sv_ratelimitlocalplayer);
        Cvar_RegisterVariable (&sv_maxrate);
index 725aa88..22c9101 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -734,15 +734,18 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                        continue;
 
                // if the entity is standing on the pusher, it will definitely be moved
-               if (!(((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher))
+               if (((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher)
                {
-                       // if the entity is not inside the pusher's final position, leave it alone
-                       if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
-                               continue;
                        // remove the onground flag for non-players
                        if (check->fields.server->movetype != MOVETYPE_WALK)
                                check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND;
                }
+               else
+               {
+                       // if the entity is not inside the pusher's final position, leave it alone
+                       if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+                               continue;
+               }
 
 
                if (forward[0] != 1 || left[1] != 1) // quick way to check if any rotation is used
@@ -1317,22 +1320,23 @@ void SV_Physics_Toss (prvm_edict_t *ent)
 // if onground, return without moving
        if ((int)ent->fields.server->flags & FL_ONGROUND)
        {
-               // don't stick to ground if onground and moving upward
-               if (ent->fields.server->velocity[2] >= (1.0 / 32.0))
+               if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer)
+               {
+                       // don't stick to ground if onground and moving upward
                        ent->fields.server->flags -= FL_ONGROUND;
-               else
+               }
+               else if (!ent->fields.server->groundentity || !sv_gameplayfix_noairborncorpse.integer)
+               {
+                       // we can trust FL_ONGROUND if groundentity is world because it never moves
+                       return;
+               }
+               else if (ent->priv.server->suspendedinairflag && PRVM_PROG_TO_EDICT(ent->fields.server->groundentity)->priv.server->free)
                {
-                       prvm_edict_t *ground = PRVM_PROG_TO_EDICT(ent->fields.server->groundentity);
-                       if (ground->fields.server->solid == SOLID_BSP || !sv_gameplayfix_noairborncorpse.integer)
-                               return;
                        // if ent was supported by a brush model on previous frame,
-                       // and groundentity is now freed, set groundentity to 0 (floating)
-                       if (ent->priv.server->suspendedinairflag && ground->priv.server->free)
-                       {
-                               // leave it suspended in the air
-                               ent->fields.server->groundentity = 0;
-                               return;
-                       }
+                       // and groundentity is now freed, set groundentity to 0 (world)
+                       // which leaves it suspended in the air
+                       ent->fields.server->groundentity = 0;
+                       return;
                }
        }
        ent->priv.server->suspendedinairflag = false;
@@ -1447,9 +1451,8 @@ void SV_Physics_Step (prvm_edict_t *ent)
                if (flags & FL_ONGROUND)
                {
                        // freefall if onground and moving upward
-                       // freefall if not standing on a world surface (it may be a lift)
-                       prvm_edict_t *ground = PRVM_PROG_TO_EDICT(ent->fields.server->groundentity);
-                       if (ent->fields.server->velocity[2] >= (1.0 / 32.0) || (ground->fields.server->solid != SOLID_BSP && sv_gameplayfix_noairborncorpse.integer))
+                       // freefall if not standing on a world surface (it may be a lift or trap door)
+                       if ((ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer) || ent->fields.server->groundentity)
                        {
                                ent->fields.server->flags -= FL_ONGROUND;
                                SV_AddGravity(ent);