#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
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;
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" };
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);
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
// 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;
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);