From: havoc Date: Mon, 3 Jul 2006 00:02:30 +0000 (+0000) Subject: clean up of FL_ONGROUND checks in MOVE_TOSS/FLY/FLYMISSILE/BOUNCE/BOUNCEMISSILE/STEP... X-Git-Tag: xonotic-v0.1.0preview~3886 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=d80b44a3ad2fe4a2211b2e810069b59cf04729ff;p=xonotic%2Fdarkplaces.git clean up of FL_ONGROUND checks in MOVE_TOSS/FLY/FLYMISSILE/BOUNCE/BOUNCEMISSILE/STEP code, this fixes items and monsters sometimes being left floating in the air after a trap door opens or when riding a func_train (most notably in the lava room of r1m5 of mission pack 2) 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 --- diff --git a/server.h b/server.h index 8371c750..e2db41c6 100644 --- 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; diff --git a/sv_main.c b/sv_main.c index 2e45d00f..0552bb2c 100644 --- 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); diff --git a/sv_phys.c b/sv_phys.c index 725aa884..22c91013 100644 --- 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);