From 2d7ae88586311b7867e3d289c75baf88cfb68764 Mon Sep 17 00:00:00 2001 From: Lach Date: Fri, 21 Jul 2023 19:19:28 +1000 Subject: [PATCH] Hardcode MT_BOOSTPAD as MT_SNEAKERPANEL --- src/deh_tables.c | 12 ++-- src/info.c | 18 ++--- src/info.h | 14 ++-- src/k_objects.h | 6 ++ src/objects/CMakeLists.txt | 1 + src/objects/sneaker-panel.c | 129 ++++++++++++++++++++++++++++++++++++ src/p_enemy.c | 3 +- src/p_map.c | 11 +++ src/p_mobj.c | 13 +++- 9 files changed, 182 insertions(+), 25 deletions(-) create mode 100644 src/objects/sneaker-panel.c diff --git a/src/deh_tables.c b/src/deh_tables.c index da72e26ec..89b14223a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4251,10 +4251,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DASHRING_VERTICAL_FLASH1", "S_DASHRING_VERTICAL_FLASH2", - // Boost pads - "S_BOOSTPAD", - "S_BOOSTPAD_SMALL", - "S_BOOSTPAD_TINY", + // Sneaker Panels + "S_SNEAKERPANEL", + "S_SNEAKERPANEL_SMALL", + "S_SNEAKERPANEL_TINY", // Various plants "S_SONICBUSH", @@ -5627,8 +5627,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DASHRING", "MT_RAINBOWDASHRING", - // Boost pads - "MT_BOOSTPAD", + // Sneaker Panels + "MT_SNEAKERPANEL", // Various plants "MT_SONICBUSH", diff --git a/src/info.c b/src/info.c index 8aabe2828..7309a520d 100644 --- a/src/info.c +++ b/src/info.c @@ -720,7 +720,7 @@ char sprnames[NUMSPRITES + 1][5] = // Dash Rings "RAIR", - // Boost pads + // Sneaker Panels "BSTP", "BSTS", "BSTT", @@ -4940,10 +4940,10 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH2}, // S_DASHRING_VERTICAL_FLASH1 {SPR_RAIR, FF_ADD|3, 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH1}, // S_DASHRING_VERTICAL_FLASH2 - // Boost pads - {SPR_BSTP, FF_FLOORSPRITE, 1, {A_TextureAnimate}, 5, 2, S_BOOSTPAD}, // S_BOOSTPAD - {SPR_BSTS, FF_FLOORSPRITE, 1, {A_TextureAnimate}, 5, 2, S_BOOSTPAD_SMALL}, // S_BOOSTPAD_SMALL - {SPR_BSTT, FF_FLOORSPRITE, 1, {A_TextureAnimate}, 5, 2, S_BOOSTPAD_TINY}, // S_BOOSTPAD_TINY + // 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 // Various plants {SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH @@ -26807,10 +26807,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BOOSTPAD + { // MT_SNEAKERPANEL 510, // doomednum - S_BOOSTPAD, // spawnstate - 1, // spawnhealth + S_SNEAKERPANEL, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 0, // reactiontime @@ -26830,7 +26830,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_ENEMY|MF_SPECIAL, // flags + MF_SPECIAL|MF_ENEMY, // flags -- NOTE: IIRC MF_ENEMY was added by mappers to make conveyor belt setups more convenient S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index ea8b21b2b..5f816accc 100644 --- a/src/info.h +++ b/src/info.h @@ -1273,7 +1273,7 @@ typedef enum sprite // Dash Rings SPR_RAIR, - // Boost pads + // Sneaker Panels SPR_BSTP, SPR_BSTS, SPR_BSTT, @@ -5390,10 +5390,10 @@ typedef enum state S_DASHRING_VERTICAL_FLASH1, S_DASHRING_VERTICAL_FLASH2, - // Boost pads - S_BOOSTPAD, - S_BOOSTPAD_SMALL, - S_BOOSTPAD_TINY, + // Sneaker Panels + S_SNEAKERPANEL, + S_SNEAKERPANEL_SMALL, + S_SNEAKERPANEL_TINY, // Various plants S_SONICBUSH, @@ -6801,8 +6801,8 @@ typedef enum mobj_type MT_DASHRING, MT_RAINBOWDASHRING, - // Boost pads - MT_BOOSTPAD, + // Sneaker Panels + MT_SNEAKERPANEL, // Various plants MT_SONICBUSH, diff --git a/src/k_objects.h b/src/k_objects.h index ab4d259e6..f72ad1e20 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -193,6 +193,12 @@ void Obj_DashRingTouch(mobj_t *mobj, player_t *player); void Obj_DashRingPlayerThink(player_t *player); boolean Obj_DashRingPlayerHasNoGravity(player_t *player); +/* Sneaker Panels */ +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 } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 2e0f65913..4eaa1d2f5 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -26,4 +26,5 @@ target_sources(SRB2SDL2 PRIVATE powerup-aura.cpp symbol.c dash-rings.c + sneaker-panel.c ) diff --git a/src/objects/sneaker-panel.c b/src/objects/sneaker-panel.c new file mode 100644 index 000000000..8d27503a8 --- /dev/null +++ b/src/objects/sneaker-panel.c @@ -0,0 +1,129 @@ +#include "../r_main.h" +#include "../p_slopes.h" +#include "../p_local.h" +#include "../k_kart.h" + +#define SNEAKERPANEL_RADIUS (64*FRACUNIT) + +static void SneakerPanelSpriteScale(mobj_t *mobj) +{ + statenum_t newState; + fixed_t spriteScale; + + if (mobj->scale == mobj->movefactor) + return; + + mobj->movefactor = mobj->scale; + + if (mobj->scale > FRACUNIT >> 1) + { + newState = S_SNEAKERPANEL; + spriteScale = FRACUNIT; + } + else if (mobj->scale > FRACUNIT >> 2) + { + newState = S_SNEAKERPANEL_SMALL; + spriteScale = FRACUNIT << 1; + } + else + { + newState = S_SNEAKERPANEL_TINY; + spriteScale = FRACUNIT << 2; + } + + if ((mobj->state - states) != newState) + { + P_SetMobjState(mobj, newState); + mobj->spritexscale = mobj->spriteyscale = spriteScale; + } +} + +void Obj_SneakerPanelSpawn(mobj_t *mobj) +{ + mobj->renderflags |= RF_OBJECTSLOPESPLAT | RF_NOSPLATBILLBOARD; + SneakerPanelSpriteScale(mobj); +} + +void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing) +{ + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + 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); +} + +void Obj_SneakerPanelCollide(mobj_t *panel, mobj_t *mo) +{ + pslope_t *slope = panel->standingslope; + player_t *player = mo->player; + fixed_t playerTop = mo->z + mo->height, playerBottom = mo->z; + fixed_t panelTop, panelBottom, dist, x, y, radius; + angle_t angle; + + // only players can boost! + if (player == NULL) + return; + + // these aren't aerial boosters, so you do need to be on the ground + if (!P_IsObjectOnGround(mo)) + return; + + // player needs to have the same gravflip status as the panel + if ((panel->eflags & MFE_VERTICALFLIP) != (mo->eflags & MFE_VERTICALFLIP)) + return; + + // find the x and y coordinates of the player relative to the booster's angle + dist = R_PointToDist2(panel->x, panel->y, mo->x, mo->y); + angle = R_PointToAngle2(panel->x, panel->y, mo->x, mo->y) - panel->angle; + x = P_ReturnThrustX(NULL, angle, dist); + y = P_ReturnThrustY(NULL, angle, dist); + + // check that these coordinates fall within the square panel + radius = FixedMul(SNEAKERPANEL_RADIUS, panel->scale); + + if (x < -radius || x > radius || y < -radius || y > radius) + return; // out of bounds + + // check that the player is within reasonable vertical bounds + if (slope == NULL) + { + panelTop = panel->z + panel->height; + panelBottom = panel->z; + } + else + { + x = P_ReturnThrustX(NULL, slope->xydirection, panel->radius); + y = P_ReturnThrustY(NULL, slope->xydirection, panel->radius); + panelTop = P_GetSlopeZAt(slope, panel->x + x, panel->y + y); + panelBottom = P_GetSlopeZAt(slope, panel->x - x, panel->y - y); + + if (panelTop < panelBottom) + { + // variable swap + panelTop = panelTop + panelBottom; + panelBottom = panelTop - panelBottom; + panelTop = panelTop - panelBottom; + } + } + + if ((playerBottom > panelTop) || (playerTop < panelBottom)) + return; + + // boost! + if (player->floorboost == 0) + player->floorboost = 3; + else + player->floorboost = 2; + + K_DoSneaker(player, 0); +} diff --git a/src/p_enemy.c b/src/p_enemy.c index bf4165281..01420801f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13744,7 +13744,6 @@ void A_TextureAnimate(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - state_t *state = actor->state; if (LUA_CallAction(A_TEXTUREANIMATE, actor)) { @@ -13754,5 +13753,5 @@ void A_TextureAnimate(mobj_t *actor) if (actor->frame & FF_ANIMATE) // this doesn't work if you're animating on your own as well return; - actor->frame = (actor->frame & ~FF_FRAMEMASK) | ((state->frame & FF_FRAMEMASK) + ((leveltime / state->var2) % (state->var1 + 1))) + actor->frame += ((leveltime / locvar2) % (locvar1 + 1)); } diff --git a/src/p_map.c b/src/p_map.c index 2d00b808e..6c6f47e80 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1152,6 +1152,17 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return K_FallingRockCollide(thing, tm.thing) ? BMIT_CONTINUE : BMIT_ABORT; } + if (thing->type == MT_SNEAKERPANEL) + { + Obj_SneakerPanelCollide(thing, tm.thing); + return BMIT_CONTINUE; + } + else if (tm.thing->type == MT_SNEAKERPANEL) + { + Obj_SneakerPanelCollide(tm.thing, thing); + return BMIT_CONTINUE; + } + //} if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 diff --git a/src/p_mobj.c b/src/p_mobj.c index acc48e89a..171dbb056 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9608,6 +9608,9 @@ 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); @@ -10446,7 +10449,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_DRIFTCLIP: thing->shadowscale = FRACUNIT/3; break; - case MT_BOOSTPAD: + case MT_SNEAKERPANEL: thing->shadowscale = 0; break; default: @@ -11005,6 +11008,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_RAINBOWDASHRING: Obj_RainbowDashRingSpawn(mobj); break; + case MT_SNEAKERPANEL: + Obj_SneakerPanelSpawn(mobj); + break; default: break; } @@ -13535,6 +13541,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj) Obj_DashRingSetup(mobj, mthing); break; } + case MT_SNEAKERPANEL: + { + Obj_SneakerPanelSetup(mobj, mthing); + break; + } default: break; }