Merge branch 'attenuating-spikes' into 'master'

Less spike softlock (resolves ring-racers#65)

Closes ring-racers#65

See merge request kart-krew-dev/ring-racers-internal!2953
This commit is contained in:
Eidolon 2025-10-20 18:15:22 -05:00
commit 3244e42177
6 changed files with 57 additions and 6 deletions

View file

@ -769,6 +769,7 @@ struct player_t
UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out
UINT8 justbumped; // Prevent players from endlessly bumping into each other
UINT8 noEbrakeMagnet; // Briefly disable 2.2 responsive ebrake if you're bumped by another player.
UINT8 wallSpikeDampen; // 2.4 wallspikes can softlock in closed quarters... attenuate their violence
UINT8 tumbleBounces;
UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu
UINT16 stunned; // Number of tics during which rings cannot be picked up

View file

@ -1275,12 +1275,50 @@ boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj)
if (solidMobj->type == MT_WALLSPIKE)
{
if (bounceMobj->hitlag)
{
bounceMobj->player->justbumped = bumptime;
return false;
}
//CONS_Printf("%sattenuation is %d\n", (leveltime & 1 ? "" : " "), bounceMobj->player->wallSpikeDampen);
// Always thrust out towards the tip
// (...don't try to roll our own bad calculations,
// just make this behave like a wallspring...)
P_DoSpringEx(bounceMobj, mapobjectscale, 0, solidMobj->info->damage,
solidMobj->angle, SKINCOLOR_NONE);
fixed_t spikeforce = solidMobj->info->damage;
fixed_t deflection = 0;
if (bounceMobj->player && !G_CompatLevel(0x0011))
{
// Okay no we need to use bad calculations just to
// prevent softlocks -- repeated touches attenuate
UINT8 atten = bounceMobj->player->wallSpikeDampen;
deflection = atten * FRACUNIT;
if (bounceMobj->angle - solidMobj->angle >= ANGLE_180)
deflection = -deflection;
K_StumblePlayer(bounceMobj->player);
bounceMobj->player->tumbleBounces = TUMBLEBOUNCES; // Only one
atten++;
while (atten)
{
// We want a power relationship - towards zero but not quite reaching it.
spikeforce = (2 * spikeforce) / 3;
atten--;
}
if (bounceMobj->player->wallSpikeDampen < UINT8_MAX
&& bounceMobj->player->justbumped < bumptime-2)
bounceMobj->player->wallSpikeDampen++;
}
P_DoSpringEx(bounceMobj, mapobjectscale, 0, spikeforce,
solidMobj->angle + R_PointToAngle2(0, 0, spikeforce, deflection),
SKINCOLOR_NONE);
K_PlayerJustBumped(bounceMobj->player);

View file

@ -255,6 +255,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->justbumped);
else if (fastcmp(field,"noebrakemagnet"))
lua_pushinteger(L, plr->noEbrakeMagnet);
else if (fastcmp(field,"wallspikedampen"))
lua_pushinteger(L, plr->wallSpikeDampen);
else if (fastcmp(field,"tumblebounces"))
lua_pushinteger(L, plr->tumbleBounces);
else if (fastcmp(field,"tumbleheight"))
@ -1033,6 +1035,8 @@ static int player_set(lua_State *L)
plr->justbumped = luaL_checkinteger(L, 3);
else if (fastcmp(field,"noebrakemagnet"))
plr->noEbrakeMagnet = luaL_checkinteger(L, 3);
else if (fastcmp(field,"wallspikedampen"))
plr->wallSpikeDampen = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tumblebounces"))
plr->tumbleBounces = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tumbleheight"))

View file

@ -1378,12 +1378,12 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if (g_tm.thing->z + g_tm.thing->height < thing->z)
return BMIT_CONTINUE; // underneath
if (g_tm.thing->player && g_tm.thing->player && g_tm.thing->player->tumbleBounces > 0)
if (g_tm.thing->player && g_tm.thing->player->tumbleBounces)
{
if (thing->type == MT_SPIKE || G_CompatLevel(0x0011))
return BMIT_CONTINUE;
}
if (!P_IsObjectOnGround(g_tm.thing) && g_tm.thing->momz * P_MobjFlip(g_tm.thing) < 0) // fell into it
else if (!P_IsObjectOnGround(g_tm.thing) && g_tm.thing->momz * P_MobjFlip(g_tm.thing) < 0) // fell into it
{
P_DamageMobj(g_tm.thing, thing, thing, 1, DMG_TUMBLE);
@ -1398,6 +1398,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
{
if (
thing->type == MT_WALLSPIKE
&& G_CompatLevel(0x0011)
&& g_tm.thing->health
&& g_tm.thing->player
&& (g_tm.thing->player->justbumped < bumptime-2)

View file

@ -479,6 +479,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].wipeoutslow);
WRITEUINT8(save->p, players[i].justbumped);
WRITEUINT8(save->p, players[i].noEbrakeMagnet);
WRITEUINT8(save->p, players[i].wallSpikeDampen);
WRITEUINT8(save->p, players[i].tumbleBounces);
WRITEUINT16(save->p, players[i].tumbleHeight);
WRITEUINT16(save->p, players[i].stunned);
@ -1164,6 +1165,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].wipeoutslow = READUINT8(save->p);
players[i].justbumped = READUINT8(save->p);
players[i].noEbrakeMagnet = READUINT8(save->p);
players[i].wallSpikeDampen = READUINT8(save->p);
players[i].tumbleBounces = READUINT8(save->p);
players[i].tumbleHeight = READUINT16(save->p);
players[i].stunned = READUINT16(save->p);

View file

@ -4647,6 +4647,11 @@ void P_PlayerThink(player_t *player)
player->flashing--;
}
if (!player->flashing && !P_PlayerInPain(player))
{
player->wallSpikeDampen = 0;
}
if (player->nocontrol && player->nocontrol < UINT16_MAX)
{
player->nocontrol--;