From fd8ba4236dc2d90a288b04b5505259cd5900f1da Mon Sep 17 00:00:00 2001 From: Lach Date: Sat, 29 Jul 2023 17:51:25 +1000 Subject: [PATCH] Hardcode MT_SNEAKERPANELSPAWNER & adjust FF_GLOBALANIM behaviour --- src/deh_tables.c | 4 +++- src/info.c | 34 +++++++++++++++++++++++++++++++--- src/info.h | 6 ++++-- src/k_objects.h | 2 +- src/objects/sneaker-panel.c | 13 +++---------- src/p_enemy.c | 36 ++++++++++++++++++++++++++---------- src/p_mobj.c | 12 ++++-------- src/p_tick.c | 4 ++++ src/p_tick.h | 1 + 9 files changed, 77 insertions(+), 35 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 89b14223a..5568518dc 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -301,7 +301,7 @@ actionpointer_t actionpointers[] = {{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"}, {{A_SpawnItemDebrisCloud}, "A_SPAWNITEMDEBRISCLOUD"}, {{A_RingShooterFace}, "A_RINGSHOOTERFACE"}, - {{A_TextureAnimate}, "A_TEXTUREANIMATE"}, + {{A_SpawnSneakerPanel}, "A_SPAWNSNEAKERPANEL"}, {{NULL}, "NONE"}, @@ -4255,6 +4255,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SNEAKERPANEL", "S_SNEAKERPANEL_SMALL", "S_SNEAKERPANEL_TINY", + "S_SNEAKERPANELSPAWNER", // Various plants "S_SONICBUSH", @@ -5629,6 +5630,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t // Sneaker Panels "MT_SNEAKERPANEL", + "MT_SNEAKERPANELSPAWNER", // Various plants "MT_SONICBUSH", diff --git a/src/info.c b/src/info.c index 7309a520d..4aca66a8d 100644 --- a/src/info.c +++ b/src/info.c @@ -4941,9 +4941,10 @@ state_t states[NUMSTATES] = {SPR_RAIR, FF_ADD|3, 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH1}, // S_DASHRING_VERTICAL_FLASH2 // Sneaker Panels - {SPR_BSTP, FF_FLOORSPRITE|FF_FULLBRIGHT, 1, {A_TextureAnimate}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL - {SPR_BSTS, FF_FLOORSPRITE|FF_FULLBRIGHT, 1, {A_TextureAnimate}, 5, 2, S_SNEAKERPANEL_SMALL}, // S_SNEAKERPANEL_SMALL - {SPR_BSTT, FF_FLOORSPRITE|FF_FULLBRIGHT, 1, {A_TextureAnimate}, 5, 2, S_SNEAKERPANEL_TINY}, // S_SNEAKERPANEL_TINY + {SPR_BSTP, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL + {SPR_BSTS, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL_SMALL}, // S_SNEAKERPANEL_SMALL + {SPR_BSTT, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL_TINY}, // S_SNEAKERPANEL_TINY + {SPR_NULL, 0, 65, {A_SpawnSneakerPanel}, 0, 0, S_SNEAKERPANELSPAWNER}, // S_SNEAKERPANELSPAWNER // Various plants {SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH @@ -26834,6 +26835,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SNEAKERPANELSPAWNER + 511, // doomednum + S_SNEAKERPANELSPAWNER, // spawnstate + 0, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 32*FRACUNIT, // radius + 60*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPTHING, // flags + S_NULL // raisestate + }, + { // MT_SONICBUSH, 715, // doomednum S_SONICBUSH, // spawnstate diff --git a/src/info.h b/src/info.h index 5f816accc..75384566e 100644 --- a/src/info.h +++ b/src/info.h @@ -294,7 +294,7 @@ enum actionnum A_INVINCSPARKLEROTATE, A_SPAWNITEMDEBRISCLOUD, A_RINGSHOOTERFACE, - A_TEXTUREANIMATE, + A_SPAWNSNEAKERPANEL, NUMACTIONS }; @@ -569,7 +569,7 @@ void A_FlameShieldPaper(); void A_InvincSparkleRotate(); void A_SpawnItemDebrisCloud(); void A_RingShooterFace(); -void A_TextureAnimate(); +void A_SpawnSneakerPanel(); extern boolean actionsoverridden[NUMACTIONS]; @@ -5394,6 +5394,7 @@ typedef enum state S_SNEAKERPANEL, S_SNEAKERPANEL_SMALL, S_SNEAKERPANEL_TINY, + S_SNEAKERPANELSPAWNER, // Various plants S_SONICBUSH, @@ -6803,6 +6804,7 @@ typedef enum mobj_type // Sneaker Panels MT_SNEAKERPANEL, + MT_SNEAKERPANELSPAWNER, // Various plants MT_SONICBUSH, diff --git a/src/k_objects.h b/src/k_objects.h index f72ad1e20..26f6d14ac 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -194,9 +194,9 @@ void Obj_DashRingPlayerThink(player_t *player); boolean Obj_DashRingPlayerHasNoGravity(player_t *player); /* Sneaker Panels */ +void Obj_SneakerPanelSpriteScale(mobj_t *mobj); void Obj_SneakerPanelSpawn(mobj_t *mobj); void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing); -void Obj_SneakerPanelThink(mobj_t *mobj); void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo); #ifdef __cplusplus diff --git a/src/objects/sneaker-panel.c b/src/objects/sneaker-panel.c index 8d27503a8..aea6aad7b 100644 --- a/src/objects/sneaker-panel.c +++ b/src/objects/sneaker-panel.c @@ -5,7 +5,7 @@ #define SNEAKERPANEL_RADIUS (64*FRACUNIT) -static void SneakerPanelSpriteScale(mobj_t *mobj) +void Obj_SneakerPanelSpriteScale(mobj_t *mobj) { statenum_t newState; fixed_t spriteScale; @@ -41,7 +41,7 @@ static void SneakerPanelSpriteScale(mobj_t *mobj) void Obj_SneakerPanelSpawn(mobj_t *mobj) { mobj->renderflags |= RF_OBJECTSLOPESPLAT | RF_NOSPLATBILLBOARD; - SneakerPanelSpriteScale(mobj); + Obj_SneakerPanelSpriteScale(mobj); } void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing) @@ -52,14 +52,7 @@ void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing) mobj->flags2 |= MF2_OBJECTFLIP; } P_TryMove(mobj, mobj->x, mobj->y, true, NULL); // sets standingslope - SneakerPanelSpriteScale(mobj); -} - -void Obj_SneakerPanelThink(mobj_t *mobj) -{ - // ugh, this only has to exist because of the sneaker panel spawners... - // I think, when we hardcode those, it would be good to make a specialized A_TrapShot wrapper to re-scale their spawned panels and remove this thinker - SneakerPanelSpriteScale(mobj); + Obj_SneakerPanelSpriteScale(mobj); } void Obj_SneakerPanelCollide(mobj_t *panel, mobj_t *mo) diff --git a/src/p_enemy.c b/src/p_enemy.c index 01420801f..a1624f4cf 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13662,6 +13662,11 @@ A_SpawnItemDebrisCloud (mobj_t *actor) fixed_t kartspeed; fixed_t fade; + if (LUA_CallAction(A_SPAWNITEMDEBRISCLOUD, (actor))) + { + return; + } + if (target == NULL || target->player == NULL) { return; @@ -13735,23 +13740,34 @@ void A_RingShooterFace(mobj_t *actor) Obj_UpdateRingShooterFace(actor); } -// Syncs the actor's frame with the animated texture ticker in P_UpdateSpecials -// Call continuously to simulate an animated texture -// var1 and var2 act like FF_ANIMATE, i.e.: -// var1 = number of additional frames to cycle through -// var2 = number of tics to display each frame -void A_TextureAnimate(mobj_t *actor) +// Function: A_SpawnSneakerPanel +// +// Description: Spawns a sneaker panel object relative to the location of the actor +// +// var1: +// var1 >> 16 = x offset +// var1 & 65535 = y offset +// var2: +// var2 >> 16 = z +// var2 & 65535 = unused +// +void A_SpawnSneakerPanel(mobj_t *actor) { + INT16 x, y, z; + mobj_t *mo; INT32 locvar1 = var1; INT32 locvar2 = var2; - if (LUA_CallAction(A_TEXTUREANIMATE, actor)) + if (LUA_CallAction(A_SPAWNSNEAKERPANEL, actor)) { return; } - if (actor->frame & FF_ANIMATE) // this doesn't work if you're animating on your own as well - return; + x = (INT16)(locvar1 >> 16); + y = (INT16)(locvar1 & 65535); + z = (INT16)(locvar2 >> 16); - actor->frame += ((leveltime / locvar2) % (locvar1 + 1)); + mo = P_SpawnMobjFromMobj(actor, x << FRACBITS, y << FRACBITS, z << FRACBITS, MT_SNEAKERPANEL); + mo->angle = actor->angle; + Obj_SneakerPanelSpriteScale(mo); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 171dbb056..e5addca93 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -128,11 +128,10 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st) if (st->frame & FF_GLOBALANIM) { - // Attempt to account for the pre-ticker for objects spawned on load - if (!leveltime) return; - - mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer - mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account) + mobj->anim_duration -= (leveltime % st->var2); // Duration synced to timer + mobj->frame += (leveltime / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account) + if (!thinkersCompleted) // objects spawned BEFORE (or during) thinkers will think during this tic... + mobj->anim_duration++; // ...so increase the duration of their current frame by 1 to sync with objects spawned AFTER thinkers } else if (st->frame & FF_RANDOMANIM) { @@ -9608,9 +9607,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_RAINBOWDASHRING: Obj_RainbowDashRingThink(mobj); break; - case MT_SNEAKERPANEL: - Obj_SneakerPanelThink(mobj); - break; default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); diff --git a/src/p_tick.c b/src/p_tick.c index 1c756a8e5..74250931c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -48,6 +48,7 @@ #endif tic_t leveltime; +boolean thinkersCompleted; INT32 P_AltFlip(INT32 n, tic_t tics) { @@ -685,6 +686,8 @@ void P_Ticker(boolean run) quake_t *quake = NULL; INT32 i; + thinkersCompleted = false; + // Increment jointime and quittime even if paused for (i = 0; i < MAXPLAYERS; i++) { @@ -794,6 +797,7 @@ void P_Ticker(boolean run) ps_thinkertime = I_GetPreciseTime(); P_RunThinkers(); ps_thinkertime = I_GetPreciseTime() - ps_thinkertime; + thinkersCompleted = true; // Run any "after all the other thinkers" stuff { diff --git a/src/p_tick.h b/src/p_tick.h index a17a5358c..d05813c1c 100644 --- a/src/p_tick.h +++ b/src/p_tick.h @@ -25,6 +25,7 @@ extern "C" { #endif extern tic_t leveltime; +extern boolean thinkersCompleted; // Called by G_Ticker. Carries out all thinking of enemies and players. void Command_Numthinkers_f(void);