Skip to content

Commit

Permalink
Added sv_fastpushmove CVAR (default = 0, archived) to control optimiz…
Browse files Browse the repository at this point in the history
…ed SV_PushMove processing
  • Loading branch information
vsonnier committed Sep 8, 2024
1 parent 94b34f5 commit ff970d1
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 26 deletions.
2 changes: 2 additions & 0 deletions Quake/sv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,7 @@ void SV_Init (void)
extern cvar_t sv_gameplayfix_spawnbeforethinks;
extern cvar_t sv_gameplayfix_bouncedownslopes;
extern cvar_t sv_gameplayfix_elevators;
extern cvar_t sv_fastpushmove;
extern cvar_t sv_friction;
extern cvar_t sv_edgefriction;
extern cvar_t sv_stopspeed;
Expand All @@ -1162,6 +1163,7 @@ void SV_Init (void)
Cvar_RegisterVariable (&sv_gameplayfix_spawnbeforethinks);
Cvar_RegisterVariable (&sv_gameplayfix_bouncedownslopes);
Cvar_RegisterVariable (&sv_gameplayfix_elevators);
Cvar_RegisterVariable (&sv_fastpushmove);
Cvar_RegisterVariable (&pr_checkextension);
Cvar_RegisterVariable (&sv_altnoclip); // johnfitz
Cvar_RegisterVariable (&sv_netsort);
Expand Down
104 changes: 78 additions & 26 deletions Quake/sv_phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ cvar_t sv_nostep = {"sv_nostep", "0", CVAR_NONE};
cvar_t sv_freezenonclients = {"sv_freezenonclients", "0", CVAR_NONE};
cvar_t sv_gameplayfix_spawnbeforethinks = {"sv_gameplayfix_spawnbeforethinks", "0", CVAR_NONE};
cvar_t sv_gameplayfix_bouncedownslopes = {"sv_gameplayfix_bouncedownslopes", "1", CVAR_NONE}; // fixes grenades making horrible noises on slopes.
cvar_t sv_fastpushmove = {"sv_fastpushmove", "0", CVAR_ARCHIVE}; // 0=old SV_PushMove processing; 1= faster SV_PushMove, with bugs ?

#define MOVE_EPSILON 0.01

Expand Down Expand Up @@ -486,34 +487,66 @@ static void SV_PushMove (edict_t *pusher, float movetime)
// see if any solid entities are inside the final position
num_moved = 0;

for (e = 0; e < num_pushable_ent_cache; e++)
{
check = pushable_ent_cache[e];
const bool fast_pushers = (sv_fastpushmove.value > 0.f);

qboolean riding = false;
// beware, we skip entity 0:
const int effective_num_edicts = (fast_pushers ? num_pushable_ent_cache : qcvm->num_edicts - 1);
check = NEXT_EDICT (qcvm->edicts);

for (e = 0; e < effective_num_edicts; e++)
{
if (fast_pushers)
{
check = pushable_ent_cache[e];
}

if (check->free)
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
continue;
}

if (!fast_pushers)
{
if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
{
check = NEXT_EDICT (check);
continue;
}
}

qboolean riding = false;

// if the entity is standing on the pusher, it will definately be moved
if (!(((int)check->v.flags & FL_ONGROUND) && PROG_TO_EDICT (check->v.groundentity) == pusher))
{
if (check->v.absmin[0] >= maxs[0] || check->v.absmin[1] >= maxs[1] || check->v.absmin[2] >= maxs[2] || check->v.absmax[0] <= mins[0] ||
check->v.absmax[1] <= mins[1] || check->v.absmax[2] <= mins[2])
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}

// see if the ent's bbox is inside the pusher's final position
if (pusher->v.skin < 0)
{ // a more precise check...
if (!SV_ClipMoveToEntity (pusher, check->v.origin, check->v.mins, check->v.maxs, check->v.origin, CONTENTMASK_ANYSOLID).startsolid)
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}
}
else
{
if (!SV_TestEntityPosition (check))
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}

riding = false;
}
Expand Down Expand Up @@ -557,20 +590,32 @@ static void SV_PushMove (edict_t *pusher, float movetime)
if (block)
{ // fail the move
if (check->v.mins[0] == check->v.maxs[0])
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}
if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
{ // corpse
check->v.mins[0] = check->v.mins[1] = 0;
VectorCopy (check->v.mins, check->v.maxs);
continue;
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}
}

// try moving the entity up a bit if it's blocked by the pusher while also standing on it
if (riding && block == pusher && (sv_gameplayfix_elevators.value >= 2.f || (sv_gameplayfix_elevators.value && e <= svs.maxclients)))
{
check->v.origin[2] += DIST_EPSILON;
if (!SV_TestEntityPosition (check))
{
if (!fast_pushers)
check = NEXT_EDICT (check);
continue;
}
}

VectorCopy (entorig, check->v.origin);
Expand All @@ -597,7 +642,9 @@ static void SV_PushMove (edict_t *pusher, float movetime)
}
break;
} // end if block
} // foreach pushable entities
if (!fast_pushers)
check = NEXT_EDICT (check);
} // foreach pushable entities
}

/*
Expand Down Expand Up @@ -1282,25 +1329,28 @@ void SV_Physics (void)
else
entity_cap = qcvm->num_edicts;

// fill the pushable entities cache
num_pushable_ent_cache = 0;
// backup the previous callback before iterating:
ed_allocation_callback_t previous_callback = ED_GetAllocCallback ();

edict_t *check = NEXT_EDICT (qcvm->edicts);
for (int e = 1; e < qcvm->num_edicts; e++, check = NEXT_EDICT (check))
// fill the pushable entities cache
if (sv_fastpushmove.value > 0.f)
{
if (check->free)
continue;
if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
continue;

pushable_ent_cache[num_pushable_ent_cache++] = check;
}
num_pushable_ent_cache = 0;
// beware, we skip entity 0 here:
edict_t *check = NEXT_EDICT (qcvm->edicts);
for (int e = 1; e < qcvm->num_edicts; e++, check = NEXT_EDICT (check))
{
if (check->free)
continue;
if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
continue;

// backup the previous callback before iterating:
ed_allocation_callback_t previous_callback = ED_GetAllocCallback ();
pushable_ent_cache[num_pushable_ent_cache++] = check;
}

// plug ours:
ED_SetAllocCallback (intercept_allocs_in_pr_execute_program);
// plug ours:
ED_SetAllocCallback (intercept_allocs_in_pr_execute_program);
}

// for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
for (i = 0; i < entity_cap; i++, ent = NEXT_EDICT (ent))
Expand Down Expand Up @@ -1343,9 +1393,11 @@ void SV_Physics (void)
}
// johnfitz
}

// restore previous callback:
ED_SetAllocCallback (previous_callback);
if (sv_fastpushmove.value > 0.f)
{
// restore previous callback:
ED_SetAllocCallback (previous_callback);
}

if (pr_global_struct->force_retouch)
pr_global_struct->force_retouch--;
Expand Down

0 comments on commit ff970d1

Please sign in to comment.