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"};
cvar_t sv_gameplayfix_multiplethinksperframe = {0, "sv_gameplayfix_multiplethinksperframe", "1", "allows entities to think more often than the server framerate, primarily useful for very high fire rate weapons"};
+cvar_t sv_gameplayfix_slidemoveprojectiles = {0, "sv_gameplayfix_slidemoveprojectiles", "1", "allows MOVETYPE_FLY/FLYMISSILE/TOSS/BOUNCE/BOUNCEMISSILE entities to finish their move in a frame even if they hit something, fixes 'gravity accumulation' bug for grenades on steep slopes"};
cvar_t sv_gameplayfix_noairborncorpse = {0, "sv_gameplayfix_noairborncorpse", "1", "causes entities (corpses) sitting ontop of moving entities (players) to fall when the moving entity (player) is no longer supporting them"};
cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1", "fixes a bug in Quake that made setmodel always set the entity box to ('-16 -16 -16', '16 16 16') rather than properly checking the model box, breaks some poorly coded mods"};
cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "0", "attempts to step down stairs, not just up them (prevents the familiar thud..thud..thud.. when running down stairs and slopes)"};
Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
Cvar_RegisterVariable (&sv_gameplayfix_grenadebouncedownslopes);
Cvar_RegisterVariable (&sv_gameplayfix_multiplethinksperframe);
+ Cvar_RegisterVariable (&sv_gameplayfix_slidemoveprojectiles);
Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse);
Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
Cvar_RegisterVariable (&sv_gameplayfix_stepdown);
{
trace_t trace;
vec3_t move;
+ vec_t movetime;
+ int bump;
// if onground, return without moving
if ((int)ent->fields.server->flags & FL_ONGROUND)
// move angles
VectorMA (ent->fields.server->angles, sv.frametime, ent->fields.server->avelocity, ent->fields.server->angles);
-// move origin
- VectorScale (ent->fields.server->velocity, sv.frametime, move);
- trace = SV_PushEntity (ent, move, true);
- if (ent->priv.server->free)
- return;
- if (trace.bmodelstartsolid)
+ movetime = sv.frametime;
+ for (bump = 0;bump < MAX_CLIP_PLANES && movetime > 0;bump++)
{
- // try to unstick the entity
- SV_UnstickEntity(ent);
- trace = SV_PushEntity (ent, move, false);
+ // move origin
+ VectorScale (ent->fields.server->velocity, movetime, move);
+ trace = SV_PushEntity (ent, move, true);
if (ent->priv.server->free)
return;
- }
-
- if (trace.fraction < 1)
- {
+ if (trace.bmodelstartsolid)
+ {
+ // try to unstick the entity
+ SV_UnstickEntity(ent);
+ trace = SV_PushEntity (ent, move, false);
+ if (ent->priv.server->free)
+ return;
+ }
+ if (trace.fraction == 1)
+ break;
+ movetime *= 1 - min(1, trace.fraction);
if (ent->fields.server->movetype == MOVETYPE_BOUNCEMISSILE)
{
ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 2.0);
if (sv_gameplayfix_grenadebouncedownslopes.integer)
{
d = DotProduct(trace.plane.normal, ent->fields.server->velocity);
- if (trace.plane.normal[2] > 0.7 && fabs(d) < 60)
+ if (trace.plane.normal[2] > 0.7 && fabs(d) < sv_gravity.value * (60.0 / 800.0))
{
ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
}
else
{
- if (trace.plane.normal[2] > 0.7 && ent->fields.server->velocity[2] < 60)
+ if (trace.plane.normal[2] > 0.7 && ent->fields.server->velocity[2] < sv_gravity.value * (60.0 / 800.0))
{
ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
else
ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
}
+ if (!sv_gameplayfix_slidemoveprojectiles.integer)
+ break;
}
// check for in water