From ec4ea384c30ee4bfeb60100953f320d46864530b Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 4 Nov 2023 13:28:21 +0000 Subject: [PATCH 1/3] Obj_AudienceInit: Clean up handling - Don't require a mapthing to select a random Follower from the Audience list - Don't print an error message if the mapheader Audience list is empty. This is probably intentional. --- src/objects/audience.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/objects/audience.c b/src/objects/audience.c index f1c1a0131..b3d844184 100644 --- a/src/objects/audience.c +++ b/src/objects/audience.c @@ -29,6 +29,7 @@ Obj_AudienceInit mapthing_t *mthing, INT32 followerpick) { + const boolean ourchoiceofvisuals = (followerpick < 0 || followerpick > numfollowers); INT16 *reflist = NULL; INT16 tempreflist[MAXHEADERFOLLOWERS]; UINT8 numref = 0; @@ -36,9 +37,9 @@ Obj_AudienceInit audience_mainstate(mobj) = S_NULL; // Pick follower - if (mthing != NULL) + if (ourchoiceofvisuals == true) { - if (mthing->thing_stringargs[0] != NULL) + if (mthing != NULL && mthing->thing_stringargs[0] != NULL) { // From mapthing char *stringcopy = Z_StrDup(mthing->thing_stringargs[0]); @@ -56,11 +57,23 @@ Obj_AudienceInit *c = ' '; } - if ((tempreflist[numref++] = K_FollowerAvailable(tok)) == -1) + if ((tempreflist[numref] = K_FollowerAvailable(tok)) == -1) + { CONS_Alert(CONS_WARNING, "Mapthing %s: Follower \"%s\" is invalid!\n", sizeu1(mthing-mapthings), tok); + } + else + numref++; + tok = strtok(NULL, " ,"); } + if (!numref) + { + // This is the one thing a user should definitely be told about. + CONS_Alert(CONS_WARNING, "Mapthing %s: Follower audience has no valid followers to pick from!\n", sizeu1(mthing-mapthings)); + // DO NOT RETURN HERE + } + Z_Free(stringcopy); reflist = tempreflist; @@ -81,8 +94,8 @@ Obj_AudienceInit if (!numref || !reflist) { - // This is the one thing a user should definitely be told about. - CONS_Alert(CONS_WARNING, "Mapthing %s: Follower audience has no valid followers to pick from!\n", sizeu1(mthing-mapthings)); + // Clean up after ourselves. + P_RemoveMobj(mobj); return; } @@ -137,11 +150,11 @@ Obj_AudienceInit } // Handle colors - if (mthing != NULL) + if (ourchoiceofvisuals == true) { UINT16 colorpick = SKINCOLOR_NONE; - if (mthing->thing_stringargs[1] != NULL) + if (mthing != NULL && mthing->thing_stringargs[1] != NULL) { if (!stricmp("Random", mthing->thing_stringargs[1])) { From 9e49f761b0a6be78348cc89936a72439ca00d08b Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 4 Nov 2023 13:32:08 +0000 Subject: [PATCH 2/3] 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; } } From 3805a4d5f0c4425f24c865105a2880cfbf994a7e Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 23:51:44 +0000 Subject: [PATCH 3/3] Adjust Prison followers based on feedback... - Exist for 1.5 seconds before disappearing - Flickers away in the last half second - Twice as many spawned, at half the size - Different arc - Severely reduced gravity - Don't jump if they hypothetically touch the floor --- src/objects/audience.c | 6 ++++++ src/p_inter.c | 21 +++++++++++++-------- src/p_mobj.c | 4 ++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/objects/audience.c b/src/objects/audience.c index b6d211132..b5814ae16 100644 --- a/src/objects/audience.c +++ b/src/objects/audience.c @@ -207,6 +207,12 @@ Obj_AudienceThink { boolean landed = false; + if (mobj->fuse && mobj->fuse < (TICRATE/2)) + { + mobj->renderflags ^= RF_DONTDRAW; + return; // no jumping when you hit the floor, your gravity is weird + } + if (audience_mainstate(mobj) == S_NULL) { // Uninitialised, don't do anything funny. diff --git a/src/p_inter.c b/src/p_inter.c index f90848f66..f510cf2fa 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2108,11 +2108,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { dir = FixedAngle(P_RandomKey(PR_RANDOMAUDIENCE, 360)*FRACUNIT); - const fixed_t launchmomentum = 11 * mapobjectscale; + const fixed_t launchmomentum = 7 * mapobjectscale; const fixed_t jaggedness = 4; angle_t launchangle; UINT8 i; - for (i = 0; i < 3; i++, dir += ANGLE_120) + for (i = 0; i < 6; i++, dir += ANG60) { cur = P_SpawnMobj( target->x, target->y, @@ -2130,13 +2130,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget 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; + cur->destscale /= 2; P_SetScale(cur, cur->destscale/TICRATE); cur->scalespeed = cur->destscale/TICRATE; cur->z -= cur->height/2; @@ -2145,7 +2141,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget cur->flags2 |= (source->flags2 & MF2_OBJECTFLIP); cur->eflags |= (source->eflags & MFE_VERTICALFLIP); - launchangle = FixedAngle(P_RandomRange(PR_RANDOMAUDIENCE, 60/jaggedness, 80/jaggedness) * jaggedness*FRACUNIT); + launchangle = FixedAngle( + ( + ( + P_RandomRange(PR_RANDOMAUDIENCE, 12/jaggedness, 24/jaggedness) * jaggedness + ) + (i & 1)*16 + ) * FRACUNIT + ); cur->momz = P_MobjFlip(target) // THIS one uses target! * P_ReturnThrustY(cur, launchangle, launchmomentum); @@ -2156,6 +2158,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget cur, cur->angle, P_ReturnThrustX(cur, launchangle, launchmomentum) ); + + cur->fuse = (3*TICRATE)/2; + cur->flags |= MF_NOCLIPHEIGHT; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 839e37cfc..da1b58d8e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1278,6 +1278,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) } break; } + case MT_RANDOMAUDIENCE: + if (mo->fuse) + gravityadd /= 10; + break; default: break; }