Track player Flybot767 spawns using a mobj pointer instead of a flag in the stunned timer

This commit is contained in:
Lach 2025-06-19 21:46:56 +10:00 committed by AJ Martinez
parent 6177ca0dcc
commit 9ee69ec1db
8 changed files with 65 additions and 14 deletions

View file

@ -741,6 +741,7 @@ struct player_t
UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu
UINT16 stunned; // Number of tics during which rings cannot be picked up
UINT8 stunnedCombo; // Number of hits sustained while stunned, reduces consecutive stun penalties
mobj_t *flybot; // One Flybot767 circling the player while stunned
UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input
boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting.

View file

@ -9738,23 +9738,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
&& P_IsObjectOnGround(player->mo)
)
{
// MEGA FUCKING HACK BECAUSE P_SAVEG MOBJS ARE FULL
// Would updating player_saveflags to 32 bits have any negative consequences?
// For now, player->stunned 16th bit is a flag to determine whether the flybots were spawned
// timer counts down at triple speed while spindashing
player->stunned = (player->stunned & 0x8000) | max(0, (player->stunned & 0x7FFF) - (player->spindash ? 3 : 1));
player->stunned = max(0, player->stunned - (player->spindash ? 3 : 1));
// when timer reaches 0, reset the flag and stun combo counter
if ((player->stunned & 0x7FFF) == 0)
// when timer reaches 0, reset the stun combo counter
if (player->stunned == 0)
{
player->stunned = 0;
player->stunnedCombo = 0;
}
// otherwise if the flybots aren't spawned, spawn them now!
else if ((player->stunned & 0x8000) == 0)
else if (P_MobjWasRemoved(player->flybot))
{
player->stunned |= 0x8000;
Obj_SpawnFlybotsForPlayer(player);
}
}

View file

@ -440,6 +440,7 @@ void Obj_DestroyedKartParticleLanding(mobj_t *part);
void Obj_SpawnFlybotsForPlayer(player_t *player);
void Obj_FlybotThink(mobj_t *flybot);
void Obj_FlybotDeath(mobj_t *flybot);
void Obj_FlybotRemoved(mobj_t *flybot);
/* Pulley */
void Obj_PulleyThink(mobj_t *root);

View file

@ -264,6 +264,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->stunned);
else if (fastcmp(field,"stunnedcombo"))
lua_pushinteger(L, plr->stunnedCombo);
else if (fastcmp(field,"flybot"))
LUA_PushUserdata(L, plr->flybot, META_MOBJ);
else if (fastcmp(field,"justdi"))
lua_pushinteger(L, plr->justDI);
else if (fastcmp(field,"flipdi"))
@ -898,6 +900,13 @@ static int player_set(lua_State *L)
plr->stunned = luaL_checkinteger(L, 3);
else if (fastcmp(field,"stunnedcombo"))
plr->stunnedCombo = luaL_checkinteger(L, 3);
else if (fastcmp(field,"flybot"))
{
mobj_t *mo = NULL;
if (!lua_isnil(L, 3))
mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_SetTarget(&plr->flybot, mo);
}
else if (fastcmp(field,"justdi"))
plr->justDI = luaL_checkinteger(L, 3);
else if (fastcmp(field,"flipdi"))

View file

@ -43,6 +43,7 @@ void Obj_SpawnFlybotsForPlayer(player_t *player)
{
UINT8 i;
mobj_t *mo = player->mo;
mobj_t *hprev = mo;
fixed_t radius = mo->radius;
for (i = 0; i < FLYBOT_QUANTITY; i++)
@ -61,6 +62,17 @@ void Obj_SpawnFlybotsForPlayer(player_t *player)
flybot->movedir = flybot->old_angle = flybot->angle = angle + ANGLE_90;
flybot->old_z = SetFlybotZ(flybot);
flybot->renderflags |= (i * RF_DONTDRAW);
if (hprev->player)
{
P_SetTarget(&player->flybot, flybot);
}
else
{
P_SetTarget(&hprev->hnext, flybot);
P_SetTarget(&flybot->hprev, hprev);
}
hprev = flybot;
}
}
@ -80,7 +92,7 @@ void Obj_FlybotThink(mobj_t *flybot)
if (mo->player)
{
if (((stunned = mo->player->stunned & 0x7FFF) == 0) || (mo->player->playerstate == PST_DEAD))
if (((stunned = mo->player->stunned) == 0) || (mo->player->playerstate == PST_DEAD))
{
P_KillMobj(flybot, NULL, NULL, 0);
return;
@ -120,6 +132,11 @@ void Obj_FlybotDeath(mobj_t *flybot)
if (!P_MobjWasRemoved(mo))
{
if (mo->player && (flybot == mo->player->flybot))
{
P_SetTarget(&mo->player->flybot, NULL);
}
mom.x = mo->momx;
mom.y = mo->momy;
mom.z = mo->momz;
@ -140,3 +157,12 @@ void Obj_FlybotDeath(mobj_t *flybot)
angle += ANGLE_90;
}
}
void Obj_FlybotRemoved(mobj_t *flybot)
{
mobj_t *mo = flybot->target;
if (!P_MobjWasRemoved(mo) && mo->player && (flybot == mo->player->flybot))
{
P_SetTarget(&mo->player->flybot, NULL);
}
}

View file

@ -3504,7 +3504,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{
player->stunnedCombo++;
}
player->stunned = (player->stunned & 0x8000) | min(0x7FFF, (player->stunned & 0x7FFF) + stunTics);
stunTics = min(player->stunned + stunTics, UINT16_MAX);
player->stunned = stunTics;
#undef MIN_STUNTICS
#undef MAX_STUNTICS

View file

@ -11855,6 +11855,11 @@ void P_RemoveMobj(mobj_t *mobj)
Obj_UnlinkRocks(mobj);
break;
}
case MT_FLYBOT767:
{
Obj_FlybotRemoved(mobj);
break;
}
default:
{
break;

View file

@ -72,8 +72,7 @@ static savebuffer_t *current_savebuffer;
#define ARCHIVEBLOCK_WAYPOINTS 0x7F46498F
#define ARCHIVEBLOCK_RNG 0x7FAAB5BD
// Note: This cannot be bigger
// than an UINT16 (for now)
// Note: This cannot have more than 32 entries
typedef enum
{
AWAYVIEW = 0x0001,
@ -93,6 +92,7 @@ typedef enum
BARRIER = 0x4000,
BALLHOGRETICULE = 0x8000,
STONESHOE = 0x10000,
FLYBOT = 0x20000,
} player_saveflags;
static inline void P_ArchivePlayer(savebuffer_t *save)
@ -368,6 +368,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
if (players[i].stoneShoe)
flags |= STONESHOE;
if (players[i].flybot)
flags |= FLYBOT;
WRITEUINT32(save->p, flags);
if (flags & SKYBOXVIEW)
@ -418,6 +421,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
if (flags & STONESHOE)
WRITEUINT32(save->p, players[i].stoneShoe->mobjnum);
if (flags & FLYBOT)
WRITEUINT32(save->p, players[i].flybot->mobjnum);
WRITEUINT32(save->p, (UINT32)players[i].followitem);
WRITEUINT32(save->p, players[i].charflags);
@ -1073,6 +1079,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
if (flags & STONESHOE)
players[i].stoneShoe = (mobj_t *)(size_t)READUINT32(save->p);
if (flags & FLYBOT)
players[i].flybot = (mobj_t *)(size_t)READUINT32(save->p);
players[i].followitem = (mobjtype_t)READUINT32(save->p);
//SetPlayerSkinByNum(i, players[i].skin);
@ -6232,6 +6241,11 @@ static void P_RelinkPointers(void)
if (!RelinkMobj(&players[i].stoneShoe))
CONS_Debug(DBG_GAMELOGIC, "stoneShoe not found on player %d\n", i);
}
if (players[i].flybot)
{
if (!RelinkMobj(&players[i].flybot))
CONS_Debug(DBG_GAMELOGIC, "flybot not found on player %d\n", i);
}
}
}