From 9e49f761b0a6be78348cc89936a72439ca00d08b Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 4 Nov 2023 13:32:08 +0000 Subject: [PATCH] Prison Egg polish: Spawn three Followers on hit - Selected from the mapheader's Audience list - Since most Prison Break maps don't have Audience lists set, you'll be seeing a lot of Flicky/Motobuddy/Chao for now - Yes, these will disappear in deathpits like in Sky Chase - Intentionally did not do this for the CD Special Stage UFO --- src/k_objects.h | 2 +- src/objects/audience.c | 27 ++++++++++++++------ src/p_inter.c | 56 ++++++++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 6 +++-- 4 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/k_objects.h b/src/k_objects.h index c88bf3320..bad973f62 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -136,7 +136,7 @@ void Obj_UpdateRingShooterFace(mobj_t *part); /* Follower Audience */ void Obj_AudienceInit(mobj_t * mobj, mapthing_t *mthing, INT32 followerpick); -void Obj_AudienceThink(mobj_t * mobj, boolean focusonplayer); +void Obj_AudienceThink(mobj_t * mobj, boolean focusonplayer, boolean checkdeathpit); /* Random Item Boxes */ void Obj_RandomItemVisuals(mobj_t *mobj); diff --git a/src/objects/audience.c b/src/objects/audience.c index b3d844184..b6d211132 100644 --- a/src/objects/audience.c +++ b/src/objects/audience.c @@ -202,8 +202,11 @@ Obj_AudienceInit void Obj_AudienceThink ( mobj_t * mobj, - boolean focusonplayer) + boolean focusonplayer, + boolean checkdeathpit) { + boolean landed = false; + if (audience_mainstate(mobj) == S_NULL) { // Uninitialised, don't do anything funny. @@ -328,15 +331,23 @@ Obj_AudienceThink } else if (mobj->flags2 & MF2_OBJECTFLIP) { - if (mobj->z + mobj->height >= mobj->ceilingz) - { - mobj->momz = -audience_bobamp(mobj); - P_SetMobjState(mobj, audience_mainstate(mobj)); - } + landed = (mobj->z + mobj->height >= mobj->ceilingz); } - else if (mobj->z <= mobj->floorz) + else { - mobj->momz = audience_bobamp(mobj); + landed = (mobj->z <= mobj->floorz); + } + + if (landed == true) + { + if (checkdeathpit && P_CheckDeathPitCollide(mobj)) + { + P_RemoveMobj(mobj); + return; + } + + mobj->momx = mobj->momy = 0; + mobj->momz = P_MobjFlip(mobj)*audience_bobamp(mobj); P_SetMobjState(mobj, audience_mainstate(mobj)); } } diff --git a/src/p_inter.c b/src/p_inter.c index 266cba2e2..f90848f66 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2103,6 +2103,62 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget cur = cur->hnext; } + // Spawn three Followers (if possible) + if (mapheaderinfo[gamemap-1]->numFollowers) + { + dir = FixedAngle(P_RandomKey(PR_RANDOMAUDIENCE, 360)*FRACUNIT); + + const fixed_t launchmomentum = 11 * mapobjectscale; + const fixed_t jaggedness = 4; + angle_t launchangle; + UINT8 i; + for (i = 0; i < 3; i++, dir += ANGLE_120) + { + cur = P_SpawnMobj( + target->x, target->y, + target->z + target->height/2, + MT_RANDOMAUDIENCE + ); + + // We check if you have some horrible Lua + if (P_MobjWasRemoved(cur)) + break; + + Obj_AudienceInit(cur, NULL, -1); + + // We check again if the list is invalid + if (P_MobjWasRemoved(cur)) + break; + + // For Followers, this makes them + // MF2_AMBUSH - try to always look at the nearest player + // MF2_DONTRESPAWN - Check for death pits + cur->flags2 |= (MF2_AMBUSH|MF2_DONTRESPAWN); + + cur->hitlag = target->hitlag; + + P_SetScale(cur, cur->destscale/TICRATE); + cur->scalespeed = cur->destscale/TICRATE; + cur->z -= cur->height/2; + + // flags are NOT from the target - just in case it's just been placed on the ceiling as a gimmick + cur->flags2 |= (source->flags2 & MF2_OBJECTFLIP); + cur->eflags |= (source->eflags & MFE_VERTICALFLIP); + + launchangle = FixedAngle(P_RandomRange(PR_RANDOMAUDIENCE, 60/jaggedness, 80/jaggedness) * jaggedness*FRACUNIT); + + cur->momz = P_MobjFlip(target) // THIS one uses target! + * P_ReturnThrustY(cur, launchangle, launchmomentum); + + cur->angle = dir; + + P_InstaThrust( + cur, cur->angle, + P_ReturnThrustX(cur, launchangle, launchmomentum) + ); + } + } + S_StartSound(target, sfx_mbs60); P_AddBrokenPrison(target, inflictor, source); diff --git a/src/p_mobj.c b/src/p_mobj.c index f58006a0d..839e37cfc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7270,7 +7270,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->flags2 & MF2_STRONGBOX) { - Obj_AudienceThink(mobj, true); + Obj_AudienceThink(mobj, true, false); if (P_MobjWasRemoved(mobj)) return false; } @@ -10808,7 +10808,9 @@ void P_SceneryThinker(mobj_t *mobj) if (mobj->type == MT_RANDOMAUDIENCE) { - Obj_AudienceThink(mobj, !!(mobj->flags2 & MF2_AMBUSH)); + Obj_AudienceThink(mobj, !!(mobj->flags2 & MF2_AMBUSH), !!(mobj->flags2 & MF2_DONTRESPAWN)); + if (P_MobjWasRemoved(mobj)) + return; } }