Hardcode MT_SNEAKERPANELSPAWNER & adjust FF_GLOBALANIM behaviour

This commit is contained in:
Lach 2023-07-29 17:51:25 +10:00
parent 2d7ae88586
commit fd8ba4236d
9 changed files with 77 additions and 35 deletions

View file

@ -301,7 +301,7 @@ actionpointer_t actionpointers[] =
{{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"}, {{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"},
{{A_SpawnItemDebrisCloud}, "A_SPAWNITEMDEBRISCLOUD"}, {{A_SpawnItemDebrisCloud}, "A_SPAWNITEMDEBRISCLOUD"},
{{A_RingShooterFace}, "A_RINGSHOOTERFACE"}, {{A_RingShooterFace}, "A_RINGSHOOTERFACE"},
{{A_TextureAnimate}, "A_TEXTUREANIMATE"}, {{A_SpawnSneakerPanel}, "A_SPAWNSNEAKERPANEL"},
{{NULL}, "NONE"}, {{NULL}, "NONE"},
@ -4255,6 +4255,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_SNEAKERPANEL", "S_SNEAKERPANEL",
"S_SNEAKERPANEL_SMALL", "S_SNEAKERPANEL_SMALL",
"S_SNEAKERPANEL_TINY", "S_SNEAKERPANEL_TINY",
"S_SNEAKERPANELSPAWNER",
// Various plants // Various plants
"S_SONICBUSH", "S_SONICBUSH",
@ -5629,6 +5630,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
// Sneaker Panels // Sneaker Panels
"MT_SNEAKERPANEL", "MT_SNEAKERPANEL",
"MT_SNEAKERPANELSPAWNER",
// Various plants // Various plants
"MT_SONICBUSH", "MT_SONICBUSH",

View file

@ -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 {SPR_RAIR, FF_ADD|3, 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH1}, // S_DASHRING_VERTICAL_FLASH2
// Sneaker Panels // Sneaker Panels
{SPR_BSTP, FF_FLOORSPRITE|FF_FULLBRIGHT, 1, {A_TextureAnimate}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL {SPR_BSTP, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL
{SPR_BSTS, FF_FLOORSPRITE|FF_FULLBRIGHT, 1, {A_TextureAnimate}, 5, 2, S_SNEAKERPANEL_SMALL}, // S_SNEAKERPANEL_SMALL {SPR_BSTS, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 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_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 // Various plants
{SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH {SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH
@ -26834,6 +26835,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate 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, { // MT_SONICBUSH,
715, // doomednum 715, // doomednum
S_SONICBUSH, // spawnstate S_SONICBUSH, // spawnstate

View file

@ -294,7 +294,7 @@ enum actionnum
A_INVINCSPARKLEROTATE, A_INVINCSPARKLEROTATE,
A_SPAWNITEMDEBRISCLOUD, A_SPAWNITEMDEBRISCLOUD,
A_RINGSHOOTERFACE, A_RINGSHOOTERFACE,
A_TEXTUREANIMATE, A_SPAWNSNEAKERPANEL,
NUMACTIONS NUMACTIONS
}; };
@ -569,7 +569,7 @@ void A_FlameShieldPaper();
void A_InvincSparkleRotate(); void A_InvincSparkleRotate();
void A_SpawnItemDebrisCloud(); void A_SpawnItemDebrisCloud();
void A_RingShooterFace(); void A_RingShooterFace();
void A_TextureAnimate(); void A_SpawnSneakerPanel();
extern boolean actionsoverridden[NUMACTIONS]; extern boolean actionsoverridden[NUMACTIONS];
@ -5394,6 +5394,7 @@ typedef enum state
S_SNEAKERPANEL, S_SNEAKERPANEL,
S_SNEAKERPANEL_SMALL, S_SNEAKERPANEL_SMALL,
S_SNEAKERPANEL_TINY, S_SNEAKERPANEL_TINY,
S_SNEAKERPANELSPAWNER,
// Various plants // Various plants
S_SONICBUSH, S_SONICBUSH,
@ -6803,6 +6804,7 @@ typedef enum mobj_type
// Sneaker Panels // Sneaker Panels
MT_SNEAKERPANEL, MT_SNEAKERPANEL,
MT_SNEAKERPANELSPAWNER,
// Various plants // Various plants
MT_SONICBUSH, MT_SONICBUSH,

View file

@ -194,9 +194,9 @@ void Obj_DashRingPlayerThink(player_t *player);
boolean Obj_DashRingPlayerHasNoGravity(player_t *player); boolean Obj_DashRingPlayerHasNoGravity(player_t *player);
/* Sneaker Panels */ /* Sneaker Panels */
void Obj_SneakerPanelSpriteScale(mobj_t *mobj);
void Obj_SneakerPanelSpawn(mobj_t *mobj); void Obj_SneakerPanelSpawn(mobj_t *mobj);
void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing); void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing);
void Obj_SneakerPanelThink(mobj_t *mobj);
void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo); void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -5,7 +5,7 @@
#define SNEAKERPANEL_RADIUS (64*FRACUNIT) #define SNEAKERPANEL_RADIUS (64*FRACUNIT)
static void SneakerPanelSpriteScale(mobj_t *mobj) void Obj_SneakerPanelSpriteScale(mobj_t *mobj)
{ {
statenum_t newState; statenum_t newState;
fixed_t spriteScale; fixed_t spriteScale;
@ -41,7 +41,7 @@ static void SneakerPanelSpriteScale(mobj_t *mobj)
void Obj_SneakerPanelSpawn(mobj_t *mobj) void Obj_SneakerPanelSpawn(mobj_t *mobj)
{ {
mobj->renderflags |= RF_OBJECTSLOPESPLAT | RF_NOSPLATBILLBOARD; mobj->renderflags |= RF_OBJECTSLOPESPLAT | RF_NOSPLATBILLBOARD;
SneakerPanelSpriteScale(mobj); Obj_SneakerPanelSpriteScale(mobj);
} }
void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing) 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; mobj->flags2 |= MF2_OBJECTFLIP;
} }
P_TryMove(mobj, mobj->x, mobj->y, true, NULL); // sets standingslope P_TryMove(mobj, mobj->x, mobj->y, true, NULL); // sets standingslope
SneakerPanelSpriteScale(mobj); Obj_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);
} }
void Obj_SneakerPanelCollide(mobj_t *panel, mobj_t *mo) void Obj_SneakerPanelCollide(mobj_t *panel, mobj_t *mo)

View file

@ -13662,6 +13662,11 @@ A_SpawnItemDebrisCloud (mobj_t *actor)
fixed_t kartspeed; fixed_t kartspeed;
fixed_t fade; fixed_t fade;
if (LUA_CallAction(A_SPAWNITEMDEBRISCLOUD, (actor)))
{
return;
}
if (target == NULL || target->player == NULL) if (target == NULL || target->player == NULL)
{ {
return; return;
@ -13735,23 +13740,34 @@ void A_RingShooterFace(mobj_t *actor)
Obj_UpdateRingShooterFace(actor); Obj_UpdateRingShooterFace(actor);
} }
// Syncs the actor's frame with the animated texture ticker in P_UpdateSpecials // Function: A_SpawnSneakerPanel
// Call continuously to simulate an animated texture //
// var1 and var2 act like FF_ANIMATE, i.e.: // Description: Spawns a sneaker panel object relative to the location of the actor
// var1 = number of additional frames to cycle through //
// var2 = number of tics to display each frame // var1:
void A_TextureAnimate(mobj_t *actor) // 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 locvar1 = var1;
INT32 locvar2 = var2; INT32 locvar2 = var2;
if (LUA_CallAction(A_TEXTUREANIMATE, actor)) if (LUA_CallAction(A_SPAWNSNEAKERPANEL, actor))
{ {
return; return;
} }
if (actor->frame & FF_ANIMATE) // this doesn't work if you're animating on your own as well x = (INT16)(locvar1 >> 16);
return; 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);
} }

View file

@ -128,11 +128,10 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st)
if (st->frame & FF_GLOBALANIM) if (st->frame & FF_GLOBALANIM)
{ {
// Attempt to account for the pre-ticker for objects spawned on load mobj->anim_duration -= (leveltime % st->var2); // Duration synced to timer
if (!leveltime) return; 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 -= (leveltime + 2) % st->var2; // Duration synced to timer mobj->anim_duration++; // ...so increase the duration of their current frame by 1 to sync with objects spawned AFTER thinkers
mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account)
} }
else if (st->frame & FF_RANDOMANIM) else if (st->frame & FF_RANDOMANIM)
{ {
@ -9608,9 +9607,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
case MT_RAINBOWDASHRING: case MT_RAINBOWDASHRING:
Obj_RainbowDashRingThink(mobj); Obj_RainbowDashRingThink(mobj);
break; break;
case MT_SNEAKERPANEL:
Obj_SneakerPanelThink(mobj);
break;
default: default:
// check mobj against possible water content, before movement code // check mobj against possible water content, before movement code
P_MobjCheckWater(mobj); P_MobjCheckWater(mobj);

View file

@ -48,6 +48,7 @@
#endif #endif
tic_t leveltime; tic_t leveltime;
boolean thinkersCompleted;
INT32 P_AltFlip(INT32 n, tic_t tics) INT32 P_AltFlip(INT32 n, tic_t tics)
{ {
@ -685,6 +686,8 @@ void P_Ticker(boolean run)
quake_t *quake = NULL; quake_t *quake = NULL;
INT32 i; INT32 i;
thinkersCompleted = false;
// Increment jointime and quittime even if paused // Increment jointime and quittime even if paused
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
@ -794,6 +797,7 @@ void P_Ticker(boolean run)
ps_thinkertime = I_GetPreciseTime(); ps_thinkertime = I_GetPreciseTime();
P_RunThinkers(); P_RunThinkers();
ps_thinkertime = I_GetPreciseTime() - ps_thinkertime; ps_thinkertime = I_GetPreciseTime() - ps_thinkertime;
thinkersCompleted = true;
// Run any "after all the other thinkers" stuff // Run any "after all the other thinkers" stuff
{ {

View file

@ -25,6 +25,7 @@ extern "C" {
#endif #endif
extern tic_t leveltime; extern tic_t leveltime;
extern boolean thinkersCompleted;
// Called by G_Ticker. Carries out all thinking of enemies and players. // Called by G_Ticker. Carries out all thinking of enemies and players.
void Command_Numthinkers_f(void); void Command_Numthinkers_f(void);