From c34b5f603470b395dc17a050c56ba1f87e254ada Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 8 Dec 2023 22:24:38 +0000 Subject: [PATCH] SPB Capsule improvements - Destroy all SPB Capsules in the stage when an SPB becomes relevant - When an SPB is put in a player's roulette - When an SPB is thrown - Automatically happens when SPB Capsule is touched - Don't respawn a popped SPB Capsule while an SPB is out --- src/k_kart.c | 2 +- src/k_objects.h | 2 ++ src/k_roulette.c | 3 +++ src/objects/spb.c | 30 ++++++++++++++++++++++++++++++ src/p_mobj.c | 8 ++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index c84d89f14..546df2958 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5060,7 +5060,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I Obj_JawzThrown(th, finalspeed, dir); break; case MT_SPB: - th->movefactor = finalspeed; + Obj_SPBThrown(th, finalspeed); break; case MT_BUBBLESHIELDTRAP: P_SetScale(th, ((5*th->destscale)>>2)*4); diff --git a/src/k_objects.h b/src/k_objects.h index c564cc2a9..5ee821c39 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -41,9 +41,11 @@ void Obj_ItemDebrisThink(mobj_t *debris); fixed_t Obj_ItemDebrisBounce(mobj_t *debris, fixed_t momz); /* SPB */ +void Obj_SPBThrown(mobj_t *spb, fixed_t finalspeed); void Obj_SPBThink(mobj_t *spb); void Obj_SPBExplode(mobj_t *spb); void Obj_SPBTouch(mobj_t *spb, mobj_t *toucher); +void Obj_SPBEradicateCapsules(void); /* SPB Juicebox Rings */ void Obj_MantaRingThink(mobj_t *manta); diff --git a/src/k_roulette.c b/src/k_roulette.c index b66754c25..53a6d20ba 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -1577,6 +1577,9 @@ static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) player->itemtype = K_ItemResultToType(getitem); player->itemamount = K_ItemResultToAmount(getitem); + + if (player->itemtype == KITEM_SPB) + Obj_SPBEradicateCapsules(); } /*-------------------------------------------------- diff --git a/src/objects/spb.c b/src/objects/spb.c index b90da6789..077e25173 100644 --- a/src/objects/spb.c +++ b/src/objects/spb.c @@ -74,6 +74,36 @@ enum #define spb_owner(o) ((o)->target) #define spb_chase(o) ((o)->tracer) +void Obj_SPBEradicateCapsules(void) +{ + thinker_t *think; + mobj_t *mo; + + // Expensive operation :D? + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)think; + + if (mo->type != MT_ITEMCAPSULE) + continue; + + if (!mo->health || mo->fuse) + continue; + + P_KillMobj(mo, NULL, NULL, DMG_NORMAL); + } +} + +void Obj_SPBThrown(mobj_t *spb, fixed_t finalspeed) +{ + spb_speed(spb) = finalspeed; + + Obj_SPBEradicateCapsules(); +} + static void SPBMantaRings(mobj_t *spb) { fixed_t vScale = INT32_MAX; diff --git a/src/p_mobj.c b/src/p_mobj.c index 76d2daa6d..28b4a3f61 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10435,6 +10435,14 @@ static boolean P_FuseThink(mobj_t *mobj) return false; case MT_ITEMCAPSULE: + + if (mobj->threshold == KITEM_SPB && K_IsSPBInGame()) + { + // SPB is in play. Try again in a short bit. + mobj->fuse += TICRATE/2; + return true; + } + if (mobj->spawnpoint) P_SpawnMapThing(mobj->spawnpoint); else