Reduce hitlag when punting hazards etc

This commit is contained in:
Antonio Martinez 2025-09-25 04:33:35 -04:00
parent b7f8afd5ef
commit 22e7b5e8ad
8 changed files with 61 additions and 32 deletions

View file

@ -1071,8 +1071,6 @@ struct player_t
UINT16 wavedashboost; // The actual boost granted from wavedash.
fixed_t wavedashpower; // Is this a bullshit "tap" wavedash? Weaken lower-charge wavedashes while keeping long sliptides fully rewarding.
UINT16 speedpunt;
UINT16 trickcharge; // Landed normally from a trick panel? Get the benefits package!
UINT16 infinitether; // Generic infinitether time, used for infinitether leniency.

View file

@ -1289,8 +1289,15 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
auto doStumble = [](mobj_t *t1, mobj_t *t2)
{
K_StumblePlayer(t2->player);
K_SpawnAmps(t1->player, K_PvPAmpReward(20, t1->player, t2->player), t2);
if (gametyperules & GTR_BUMPERS)
{
K_StumblePlayer(t2->player);
K_SpawnAmps(t1->player, K_PvPAmpReward(20, t1->player, t2->player), t2);
}
else
{
P_DamageMobj(t2, t1, t1, 1, DMG_WHUMBLE);
}
};
if (forEither(shouldStumble, doStumble))

View file

@ -22,6 +22,26 @@
#include "s_sound.h"
#include "m_easing.h"
// Use for adding hitlag that should be mostly ignored by impervious players.
// (Currently only called in power clash, but in the future...?)
void K_AddHitLagFromCollision(mobj_t *mo, INT32 tics)
{
boolean doAnything = true;
if (mo->player == NULL || mo->type != MT_PLAYER)
doAnything = false;
else if (!K_PlayerCanPunt(mo->player))
doAnything = false;
if (!doAnything)
{
K_AddHitLag(mo, tics, false);
return;
}
K_AddHitLag(mo, min(tics, 2), false);
}
/*--------------------------------------------------
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)

View file

@ -26,6 +26,8 @@ extern "C" {
#define NUM_HITLAG_STATES (9)
#define NUM_HITLAG_SOUNDS (4)
void K_AddHitLagFromCollision(mobj_t *mo, INT32 tics);
/*--------------------------------------------------
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage);

View file

@ -4924,8 +4924,10 @@ void K_DoInstashield(player_t *player)
void K_DoPowerClash(mobj_t *t1, mobj_t *t2) {
mobj_t *clash;
UINT8 lag1 = 5;
UINT8 lag2 = 5;
UINT8 lag1 = 10; // Base value used for kartitem-to-player collision.
UINT8 lag2 = 10; // We want to preserve shooting invinc players to hinder them!
boolean slow1 = false; // If we _are_ hitting a kartitem, keep that value.
boolean slow2 = false; // Otherwise, route to K_AddHitLagFromCollision.
boolean stripbubble = (gametyperules & GTR_BUMPERS);
@ -4933,24 +4935,32 @@ void K_DoPowerClash(mobj_t *t1, mobj_t *t2) {
if (t1->player)
{
t1->player->instashield = 1;
t1->player->speedpunt += 20;
lag1 -= min(lag1, t1->player->speedpunt/10);
if (stripbubble && t1->player->curshield == KSHIELD_BUBBLE)
K_PopBubbleShield(t1->player);
if (P_IsKartFieldItem(t2->type))
slow1 = true;
}
if (t2->player)
{
t2->player->instashield = 1;
t2->player->speedpunt += 20;
lag2 -= min(lag1, t2->player->speedpunt/10);
if (stripbubble && t2->player->curshield == KSHIELD_BUBBLE)
K_PopBubbleShield(t2->player);
if (P_IsKartFieldItem(t1->type))
slow2 = true;
}
S_StartSound(t1, sfx_parry);
K_AddHitLag(t1, lag1+1, false);
K_AddHitLag(t2, lag2+1, false);
if (slow1)
K_AddHitLag(t1, lag1, false);
else
K_AddHitLagFromCollision(t1, lag1);
if (slow2)
K_AddHitLag(t2, lag2, false);
else
K_AddHitLagFromCollision(t2, lag2);
clash = P_SpawnMobj((t1->x/2) + (t2->x/2), (t1->y/2) + (t2->y/2), (t1->z/2) + (t2->z/2), MT_POWERCLASH);
@ -10665,13 +10675,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->wavedashpower = FRACUNIT; // Safety
}
if (player->speedpunt)
player->speedpunt--;
// This timer can get out of control fast, clamp to match player expectations about "new" hazards
if (player->speedpunt > TICRATE*4)
player->speedpunt = TICRATE*4;
if (player->trickcharge > 0 && onground == true)
{
player->trickcharge--;

View file

@ -405,8 +405,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->overdriveready);
else if (fastcmp(field,"overdrivelenient"))
lua_pushinteger(L, plr->overdrivelenient);
else if (fastcmp(field,"speedpunt"))
lua_pushinteger(L, plr->speedpunt);
else if (fastcmp(field,"trickcharge"))
lua_pushinteger(L, plr->trickcharge);
else if (fastcmp(field,"infinitether"))
@ -1070,8 +1068,6 @@ static int player_set(lua_State *L)
plr->overdriveready = luaL_checkinteger(L, 3);
else if (fastcmp(field,"overdrivelenient"))
plr->overdrivelenient = luaL_checkinteger(L, 3);
else if (fastcmp(field,"speedpunt"))
plr->speedpunt = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickcharge"))
plr->trickcharge = luaL_checkinteger(L, 3);
else if (fastcmp(field,"infinitether"))

View file

@ -3912,7 +3912,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!force)
{
boolean invincible = true;
boolean clash = false;
boolean clash = true; // This effect is cool and reads well, why not
sfxenum_t sfx = sfx_None;
if (!(gametyperules & GTR_BUMPERS))
@ -3938,12 +3938,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (K_PlayerGuard(player))
{
sfx = sfx_s3k3a;
clash = true;
}
else if (player->overshield &&
(type != DMG_EXPLODE || inflictor->type != MT_SPBEXPLOSION || !inflictor->movefactor))
{
clash = true;
;
}
else if (player->hyudorotimer > 0)
;
@ -3995,11 +3994,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
}
laglength = max(laglength / 2, 1);
K_SetHitLagForObjects(target, inflictor, source, laglength, false);
if (!clash) // Currently a no-op, damage floor hitlag kinda sucked ass
{
laglength = max(laglength / 2, 1);
K_SetHitLagForObjects(target, inflictor, source, laglength, false);
AddNullHitlag(player, oldHitlag);
AddNullHitlag(playerInflictor, oldHitlagInflictor);
AddNullHitlag(player, oldHitlag);
AddNullHitlag(playerInflictor, oldHitlagInflictor);
}
if (player->timeshit > player->timeshitprev)
{
@ -4460,6 +4462,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (truewhumble && (gametyperules & GTR_BUMPERS) && !battleprisons)
laglength /= 2;
if (target->type == MT_PLAYER && inflictor && !P_MobjWasRemoved(inflictor) && inflictor->type == MT_PLAYER)
laglength /= 3;
if (!(target->player && (damagetype & DMG_DEATHMASK)))
K_SetHitLagForObjects(target, inflictor, source, laglength, true);

View file

@ -653,7 +653,6 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEFIXED(save->p, players[i].overdrivepower);
WRITEUINT8(save->p, players[i].overdriveready);
WRITEUINT8(save->p, players[i].overdrivelenient);
WRITEUINT16(save->p, players[i].speedpunt);
WRITEUINT16(save->p, players[i].trickcharge);
WRITEUINT16(save->p, players[i].infinitether);
@ -1331,7 +1330,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].overdrivepower = READFIXED(save->p);
players[i].overdriveready = READUINT8(save->p);
players[i].overdrivelenient = READUINT8(save->p);
players[i].speedpunt = READUINT16(save->p);
players[i].trickcharge = READUINT16(save->p);
players[i].infinitether = READUINT16(save->p);