From a419ea48c6d3ef64a99f56ee4ec4f3e7af0a4ce7 Mon Sep 17 00:00:00 2001 From: Lach Date: Fri, 8 Mar 2024 10:38:33 +1100 Subject: [PATCH 1/3] Hardcode Adventure Air Booster & Dimension Disaster objects --- src/deh_tables.c | 26 ++++ src/info.c | 159 ++++++++++++++++++++ src/info.h | 33 +++++ src/k_objects.h | 5 + src/objects/CMakeLists.txt | 1 + src/objects/adventure-air-booster.c | 217 ++++++++++++++++++++++++++++ src/p_inter.c | 4 + src/p_mobj.c | 10 ++ 8 files changed, 455 insertions(+) create mode 100644 src/objects/adventure-air-booster.c diff --git a/src/deh_tables.c b/src/deh_tables.c index 5bd5700f9..10ad7ccc5 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -2437,6 +2437,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DASHRING_VERTICAL_FLASH1", "S_DASHRING_VERTICAL_FLASH2", + // Adventure Air Booster + "S_ADVENTUREAIRBOOSTER", + "S_ADVENTUREAIRBOOSTER_EXHAUST1", + "S_ADVENTUREAIRBOOSTER_EXHAUST2", + "S_ADVENTUREAIRBOOSTER_PART", + // Sneaker Panels "S_SNEAKERPANEL", "S_SNEAKERPANEL_SMALL", @@ -2523,6 +2529,17 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_KANNA", "S_OGAMI", + // Dimension Disaster + "S_DVDTRUMPET", + "S_DVDSHINE1", + "S_DVDSHINE2", + "S_DVDSHINE3", + "S_DVDSHINE4", + "S_DVDSHINE5", + "S_DVDSPARK1", + "S_DVDSPARK2", + "S_DVDSPARK3", + "S_SUNBEAMPALM_STEM", "S_SUNBEAMPALM_LEAF", @@ -3638,6 +3655,11 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DASHRING", "MT_RAINBOWDASHRING", + // Adventure Air Booster + "MT_ADVENTUREAIRBOOSTER", + "MT_ADVENTUREAIRBOOSTER_HITBOX", + "MT_ADVENTUREAIRBOOSTER_PART", + // Sneaker Panels "MT_SNEAKERPANEL", "MT_SNEAKERPANELSPAWNER", @@ -3698,6 +3720,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_HANAGUMIHALL_STEAM", "MT_HANAGUMIHALL_NPC", + // Dimension Disaster + "MT_DVDTRUMPET", + "MT_DVDPARTICLE", + "MT_SUNBEAMPALM_STEM", "MT_SUNBEAMPALM_LEAF", diff --git a/src/info.c b/src/info.c index 6aa10a510..5495820dc 100644 --- a/src/info.c +++ b/src/info.c @@ -501,6 +501,9 @@ char sprnames[NUMSPRITES + 1][5] = // Dash Rings "RAIR", + // Adventure Air Booster + "ADVR", + // Sneaker Panels "BSTP", "BSTS", @@ -549,6 +552,10 @@ char sprnames[NUMSPRITES + 1][5] = "HGCF", "HGCG", + // Dimension Disaster + "DVDD", + "SPRC", + "TUST", "TULE", @@ -2929,6 +2936,12 @@ 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 + // Adventure Air Booster + {SPR_ADVR, 17|FF_FULLBRIGHT|FF_ADD, 1, {A_RollAngle}, 8, 0, S_ADVENTUREAIRBOOSTER}, // S_ADVENTUREAIRBOOSTER + {SPR_ADVR, 5|FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 4, 2, S_NULL}, // S_ADVENTUREAIRBOOSTER_EXHAUST1 + {SPR_ADVR, 11|FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 4, 2, S_NULL}, // S_ADVENTUREAIRBOOSTER_EXHAUST2 + {SPR_ADVR, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ADVENTUREAIRBOOSTER_PART + // Sneaker Panels {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 @@ -3019,6 +3032,17 @@ state_t states[NUMSTATES] = {SPR_HGCF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KANNA {SPR_HGCG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OGAMI + // Dimension Disaster + {SPR_DVDD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_DVDTRUMPET + {SPR_SPRC, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE2}, // S_DVDSHINE1 + {SPR_SPRC, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE3}, // S_DVDSHINE2 + {SPR_SPRC, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE4}, // S_DVDSHINE3 + {SPR_SPRC, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE5}, // S_DVDSHINE4 + {SPR_SPRC, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE1}, // S_DVDSHINE5 + {SPR_SPRC, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_DVDSPARK2}, // S_DVDSPARK1 + {SPR_SPRC, FF_TRANS20|FF_FULLBRIGHT|7, 3, {NULL}, 0, 0, S_DVDSPARK3}, // S_DVDSPARK2 + {SPR_SPRC, FF_TRANS40|FF_FULLBRIGHT|8, 3, {NULL}, 0, 0, S_NULL}, // S_DVDSPARK3 + {SPR_TUST, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_STEM {SPR_TULE, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_LEAF @@ -16807,6 +16831,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_ADVENTUREAIRBOOSTER + 3500, // doomednum + S_ADVENTUREAIRBOOSTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_spdpad, // 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 + 50*FRACUNIT, // radius + 100*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_supert, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_ADVENTUREAIRBOOSTER_HITBOX + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // 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 + 127*FRACUNIT, // radius + 256*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_SPECIAL|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_ADVENTUREAIRBOOSTER_PART + -1, // doomednum + S_ADVENTUREAIRBOOSTER_PART, // spawnstate + 1000, // 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 + 64*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_SNEAKERPANEL 510, // doomednum S_SNEAKERPANEL, // spawnstate @@ -17752,6 +17857,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_DVDTRUMPET + 3181, // doomednum + S_DVDTRUMPET, // spawnstate + 1000, // 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 + 8*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_DVDPARTICLE + -1, // doomednum + S_DVDSPARK1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // dispoffset + 100, // mass + 62*FRACUNIT, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + { // MT_SUNBEAMPALM_STEM 2697, // doomednum S_SUNBEAMPALM_STEM, // spawnstate diff --git a/src/info.h b/src/info.h index 3b26cfefc..ed6c8b5d9 100644 --- a/src/info.h +++ b/src/info.h @@ -1040,6 +1040,9 @@ typedef enum sprite // Dash Rings SPR_RAIR, + // Adventure Air Booster + SPR_ADVR, + // Sneaker Panels SPR_BSTP, SPR_BSTS, @@ -1088,6 +1091,10 @@ typedef enum sprite SPR_HGCF, SPR_HGCG, + // Dimension Disaster + SPR_DVDD, + SPR_SPRC, + SPR_TUST, SPR_TULE, @@ -3430,6 +3437,12 @@ typedef enum state S_DASHRING_VERTICAL_FLASH1, S_DASHRING_VERTICAL_FLASH2, + // Adventure Air Booster + S_ADVENTUREAIRBOOSTER, + S_ADVENTUREAIRBOOSTER_EXHAUST1, + S_ADVENTUREAIRBOOSTER_EXHAUST2, + S_ADVENTUREAIRBOOSTER_PART, + // Sneaker Panels S_SNEAKERPANEL, S_SNEAKERPANEL_SMALL, @@ -3516,6 +3529,17 @@ typedef enum state S_KANNA, S_OGAMI, + // Dimension Disaster + S_DVDTRUMPET, + S_DVDSHINE1, + S_DVDSHINE2, + S_DVDSHINE3, + S_DVDSHINE4, + S_DVDSHINE5, + S_DVDSPARK1, + S_DVDSPARK2, + S_DVDSPARK3, + S_SUNBEAMPALM_STEM, S_SUNBEAMPALM_LEAF, @@ -4658,6 +4682,11 @@ typedef enum mobj_type MT_DASHRING, MT_RAINBOWDASHRING, + // Adventure Air Booster + MT_ADVENTUREAIRBOOSTER, + MT_ADVENTUREAIRBOOSTER_HITBOX, + MT_ADVENTUREAIRBOOSTER_PART, + // Sneaker Panels MT_SNEAKERPANEL, MT_SNEAKERPANELSPAWNER, @@ -4718,6 +4747,10 @@ typedef enum mobj_type MT_HANAGUMIHALL_STEAM, MT_HANAGUMIHALL_NPC, + // Dimension Disaster + MT_DVDTRUMPET, + MT_DVDPARTICLE, + MT_SUNBEAMPALM_STEM, MT_SUNBEAMPALM_LEAF, diff --git a/src/k_objects.h b/src/k_objects.h index 93e6692d0..195e82a7b 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -398,6 +398,11 @@ void Obj_TalkPointInit(mobj_t* mo); void Obj_TalkPointThink(mobj_t* mo); void Obj_TalkPointOrbThink(mobj_t* mo); +/* Adventure Dash Ring */ +void Obj_AdventureAirBoosterSetup(mobj_t *mobj, mapthing_t *mthing); +void Obj_AdventureAirBoosterHitboxTouch(mobj_t *hitbox, player_t *player); +void Obj_AdventureAirBoosterFuse(mobj_t *mobj); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index fce16395a..aeab70b99 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -54,6 +54,7 @@ target_sources(SRB2SDL2 PRIVATE waterfall-particle.c sealed-star.c talk-point.cpp + adventure-air-booster.c ) add_subdirectory(versus) diff --git a/src/objects/adventure-air-booster.c b/src/objects/adventure-air-booster.c new file mode 100644 index 000000000..23fcd8192 --- /dev/null +++ b/src/objects/adventure-air-booster.c @@ -0,0 +1,217 @@ +#include "../p_local.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../s_sound.h" +#include "../m_random.h" +#include "../r_main.h" + +// Hardcoder note: I renamed anything using "Adventure Dash Ring"/"ADR" to "Adventure Air Booster"/"AAB" for consistency with the HVR config +// Hardcoder note: AAB_DIST used to be 64, but it was halved everywhere it was used, so I just halved the base value instead of during calculations +// Hardcoder note: AAB_STRENGTH_ADD used to be 75 to be multiplied with AAB_STRENGTH/100 at runtime, I just baked that calculation into it instead + +#define AAB_DIST (32*FRACUNIT) // distance between the back and front of the booster +#define AAB_FRONTBACKSPACE (8*FRACUNIT) // distance between the 2 sides of the front & back part of the booster +#define AAB_RADIUS (225*FRACUNIT) // radius (width) of the booster (in pixels). Used to determine where to spawn the 2 arrows on the sides +#define AAB_STRENGTH (55*FRACUNIT) // default speed for the booster +static const fixed_t AAB_STRENGTH_ADD = (75*AAB_STRENGTH/100); // each time the booster is used, add AAB_STRENGTH_ADD speed to the next player +#define AAB_DASHRINGPUSHTICS (3*TICRATE/2) +#define AAB_SPRINGSTARSTICS (TICRATE/2) + +static const skincolornum_t AAB_COLORS[] = { + SKINCOLOR_YELLOW, + SKINCOLOR_GREEN, + SKINCOLOR_RED, + SKINCOLOR_BLUE, +}; +static const UINT8 AAB_NUM_COLORS = sizeof(AAB_COLORS) / sizeof(skincolornum_t); + +static void AdventureAirBoosterUpdateColor(mobj_t *mobj) +{ + mobj_t *part = mobj->hnext; + + mobj->color = AAB_COLORS[mobj->extravalue1]; + + while (!P_MobjWasRemoved(part)) + { + part->color = mobj->color; + part = part->hnext; + } +} + +void Obj_AdventureAirBoosterSetup(mobj_t *mobj, mapthing_t *mthing) +{ + mobj_t *prev = mobj; + mobj_t *part; + angle_t positionAngle = mobj->angle; + fixed_t oldHeight = mobj->height; + fixed_t baseScale = mobj->scale; + fixed_t xPos, yPos; + SINT8 i; + + // arg1: double scale (pre-dates UDMF) + if (mthing->thing_args[0]) + { + baseScale *= 2; + } + + // set scale and flip + P_SetScale(mobj, mobj->movefactor = mobj->old_scale = mobj->destscale = baseScale); + mobj->scalespeed = mobj->scale >> 2; + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + mobj->old_z = mobj->z -= (mobj->height - oldHeight); + } + +#define SpawnPart()\ +{\ + part = P_SpawnMobjFromMobj(mobj, xPos, yPos, 0, MT_ADVENTUREAIRBOOSTER_PART);\ + P_SetTarget(&part->target, mobj);\ + P_SetTarget(&prev->hnext, part);\ + P_SetTarget(&part->hprev, prev);\ + prev = part;\ +} + + // Spawn the back rings + for (i = 0; i < 2; i++) + { + xPos = -P_ReturnThrustX(NULL, positionAngle, (AAB_FRONTBACKSPACE * i) + AAB_DIST); + yPos = -P_ReturnThrustY(NULL, positionAngle, (AAB_FRONTBACKSPACE * i) + AAB_DIST); + // with this order of operations, the first part to spawn is the front, then the back. + SpawnPart(); + part->frame |= (1 - i); + part->old_angle = part->angle = mobj->angle + ANGLE_90; // put it sideways + } + + // Now the front ring + for (i = 0; i < 2; i++) + { + xPos = P_ReturnThrustX(NULL, positionAngle, -(AAB_FRONTBACKSPACE * i) + AAB_DIST); + yPos = P_ReturnThrustY(NULL, positionAngle, -(AAB_FRONTBACKSPACE * i) + AAB_DIST); + // with this order of operations, the first part to spawn is the front, then the back. + SpawnPart(); + part->frame |= (3 - i); + part->old_angle = part->angle = mobj->angle + ANGLE_90; // put it sideways + } + + // and now the 2 arrows + positionAngle = mobj->angle + ANGLE_90; // put the angle to the side! + for (i = -1; i < 2; i += 2) + { + xPos = P_ReturnThrustX(NULL, positionAngle, AAB_RADIUS * i) / 2; + yPos = P_ReturnThrustY(NULL, positionAngle, AAB_RADIUS * i) / 2; + // with this order of operations, the first arrow we spawn is the right one, then the left one. Angle them accordingly. + SpawnPart(); + part->frame |= 4; + part->old_angle = part->angle = mobj->angle - (ANGLE_45 * i); + } +#undef SpawnPart + + part = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ADVENTUREAIRBOOSTER_HITBOX); + part->old_angle = part->angle = mobj->angle; + part->old_z = part->z -= P_MobjFlip(part) * (part->height >> 1); + P_SetTarget(&part->target, mobj); + P_SetTarget(&mobj->tracer, part); // Hardcoder note: Since the hitbox doesn't need to be colored, I decided not to tack it on the end of the hnext chain; tracer is more easily accessible to scripters + + mobj->extravalue1 = 1; // default to green + AdventureAirBoosterUpdateColor(mobj); +} + +void Obj_AdventureAirBoosterHitboxTouch(mobj_t *hitbox, player_t *player) +{ + mobj_t *mo = player->mo; + mobj_t *booster = hitbox->target; + mobj_t *part; + angle_t finalAngle = hitbox->angle; + angle_t playerAngle; + fixed_t finalSpeed, playerSpeed, xPos, yPos; + SINT8 i; + + if (player->carry != CR_NONE || P_MobjWasRemoved(booster)) + { + return; + } + + // reflect angles like springs + finalSpeed = FixedMul(AAB_STRENGTH + (booster->extravalue1 * AAB_STRENGTH_ADD), mapobjectscale); + playerSpeed = FixedHypot(mo->momx, mo->momy); + if (playerSpeed > 0) + { + playerAngle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + } + else + { + playerAngle = mo->angle; + } + + finalAngle = K_ReflectAngle(playerAngle, finalAngle, playerSpeed, finalSpeed); + + mo->momz = 0; + P_InstaThrust(mo, finalAngle, finalSpeed); + + P_SetTarget(&mo->tracer, booster); + player->carry = CR_DASHRING; + player->dashRingPullTics = 0; + player->dashRingPushTics = AAB_DASHRINGPUSHTICS; + player->springstars = AAB_SPRINGSTARSTICS; + player->springcolor = booster->color; + player->turbine = 0; + player->flashing = 0; + player->fastfall = 0; + K_TumbleInterrupt(player); + + S_StartSound(mo, booster->info->seesound); + + // before we change the colour, spawn a buncha sparkles + for (i = 0; i < 12; i++) + { + part = P_SpawnMobjFromMobj( + hitbox, + FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS, + FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS, + FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS, + MT_DVDPARTICLE + ); + part->color = booster->color; + P_SetMobjState(part, S_DVDSHINE1); + P_SetScale(part, part->old_scale = hitbox->scale * P_RandomRange(PR_DECORATION, 2, 4)); + part->tics = P_RandomRange(PR_DECORATION, 1, 8); + part->fuse = TICRATE >> 1; + part->destscale = 1; + part->scalespeed = part->scale / part->fuse; + P_InstaThrust(part, finalAngle, FixedMul(finalSpeed, P_RandomRange(PR_DECORATION, FRACUNIT*80/100, FRACUNIT*120/100))); + } + + // visuals + booster->fuse = TICRATE >> 1; + booster->destscale = 1; + + // spawn the 3 layers + for (i = -1; i < 2; i++) + { + xPos = P_ReturnThrustX(NULL, booster->angle + ANGLE_90, (AAB_RADIUS >> 1) * i) + P_ReturnThrustX(NULL, booster->angle, AAB_RADIUS); + yPos = P_ReturnThrustY(NULL, booster->angle + ANGLE_90, (AAB_RADIUS >> 1) * i) + P_ReturnThrustY(NULL, booster->angle, AAB_RADIUS); + + part = P_SpawnMobjFromMobj(hitbox, xPos, yPos, hitbox->info->height >> 1, MT_PARTICLE); + part->old_angle = part->angle = booster->angle; + part->color = booster->color; + P_SetMobjState(part, i == 0 ? S_ADVENTUREAIRBOOSTER_EXHAUST2 : S_ADVENTUREAIRBOOSTER_EXHAUST1); + } + + if (++booster->extravalue1 >= AAB_NUM_COLORS) + { + booster->extravalue1 = 0; + // we just went through a blue booster, play sparkle sfx + S_StartSound(mo, booster->info->activesound); + } + AdventureAirBoosterUpdateColor(booster); +} + +void Obj_AdventureAirBoosterFuse(mobj_t *mobj) +{ + mobj_t *ghost = P_SpawnGhostMobj(mobj); + mobj->destscale = mobj->movefactor; + ghost->destscale = mobj->movefactor * 8; + ghost->scalespeed = mobj->movefactor; +} diff --git a/src/p_inter.c b/src/p_inter.c index 048034486..80b6d9959 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -938,6 +938,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) Obj_DashRingTouch(special, player); return; + case MT_ADVENTUREAIRBOOSTER_HITBOX: + Obj_AdventureAirBoosterHitboxTouch(special, player); + return; + case MT_DLZ_ROCKET: Obj_DLZRocketSpecial(special, player); return; diff --git a/src/p_mobj.c b/src/p_mobj.c index ce279a0d4..341128e08 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10048,6 +10048,11 @@ static boolean P_FuseThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } + case MT_ADVENTUREAIRBOOSTER: + { + Obj_AdventureAirBoosterFuse(mobj); + break; + } case MT_SNEAKERPANELSPAWNER: { Obj_SneakerPanelSpawnerFuse(mobj); @@ -13799,6 +13804,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj) Obj_DashRingSetup(mobj, mthing); break; } + case MT_ADVENTUREAIRBOOSTER: + { + Obj_AdventureAirBoosterSetup(mobj, mthing); + break; + } case MT_SNEAKERPANEL: { Obj_SneakerPanelSetup(mobj, mthing); From 99908c0700302e5043e0560afa157ecc48b9e919 Mon Sep 17 00:00:00 2001 From: Lach Date: Sat, 9 Mar 2024 15:44:02 +1100 Subject: [PATCH 2/3] Allow Adventure Air Boosters to be chained with each other or dash rings --- src/k_objects.h | 1 + src/objects/adventure-air-booster.c | 2 +- src/objects/dash-rings.c | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/k_objects.h b/src/k_objects.h index 3fd6776b8..746bccb0b 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -208,6 +208,7 @@ void Obj_RainbowDashRingThink(mobj_t *mobj); void Obj_DashRingTouch(mobj_t *mobj, player_t *player); void Obj_DashRingPlayerThink(player_t *player); boolean Obj_DashRingPlayerHasNoGravity(player_t *player); +boolean Obj_DashRingIsUsableByPlayer(mobj_t *mobj, player_t *player); /* Adventure Dash Ring */ void Obj_AdventureAirBoosterSetup(mobj_t *mobj, mapthing_t *mthing); diff --git a/src/objects/adventure-air-booster.c b/src/objects/adventure-air-booster.c index 23fcd8192..268de0835 100644 --- a/src/objects/adventure-air-booster.c +++ b/src/objects/adventure-air-booster.c @@ -128,7 +128,7 @@ void Obj_AdventureAirBoosterHitboxTouch(mobj_t *hitbox, player_t *player) fixed_t finalSpeed, playerSpeed, xPos, yPos; SINT8 i; - if (player->carry != CR_NONE || P_MobjWasRemoved(booster)) + if (P_MobjWasRemoved(booster) || !Obj_DashRingIsUsableByPlayer(booster, player)) { return; } diff --git a/src/objects/dash-rings.c b/src/objects/dash-rings.c index 5d1c68501..77abc44d8 100644 --- a/src/objects/dash-rings.c +++ b/src/objects/dash-rings.c @@ -120,18 +120,27 @@ static boolean DashRingsAreTooClose(mobj_t *ring1, mobj_t *ring2) return false; } -void Obj_DashRingTouch(mobj_t *ring, player_t *player) +boolean Obj_DashRingIsUsableByPlayer(mobj_t *ring, player_t *player) { if (player->carry != CR_NONE) { if (player->carry != CR_DASHRING) // being carried by something else - return; + return false; if (player->dashRingPullTics > 0) // being pulled into a dash ring already - return; + return false; if (player->dashRingPushTics > 0 && !P_MobjWasRemoved(player->mo->tracer) && DashRingsAreTooClose(player->mo->tracer, ring)) // dash ring is too close to recently used dash ring - return; + return false; + } + return true; +} + +void Obj_DashRingTouch(mobj_t *ring, player_t *player) +{ + if (!Obj_DashRingIsUsableByPlayer(ring, player)) + { + return; } P_SetTarget(&player->mo->tracer, ring); From 5e70a5b8e777447829a9a5b88e42fc56007914c4 Mon Sep 17 00:00:00 2001 From: Lach Date: Sat, 9 Mar 2024 16:52:30 +1100 Subject: [PATCH 3/3] Scale Adventure Air Booster centerpiece from its center --- src/info.c | 2 +- src/objects/adventure-air-booster.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 8482354cd..683822adb 100644 --- a/src/info.c +++ b/src/info.c @@ -16876,7 +16876,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 50*FRACUNIT, // radius - 100*FRACUNIT, // height + 2*FRACUNIT, // height 0, // dispoffset 0, // mass 0, // damage diff --git a/src/objects/adventure-air-booster.c b/src/objects/adventure-air-booster.c index 268de0835..884a8431a 100644 --- a/src/objects/adventure-air-booster.c +++ b/src/objects/adventure-air-booster.c @@ -214,4 +214,5 @@ void Obj_AdventureAirBoosterFuse(mobj_t *mobj) mobj->destscale = mobj->movefactor; ghost->destscale = mobj->movefactor * 8; ghost->scalespeed = mobj->movefactor; + ghost->height = mobj->height; }