From c3112ea0c84754eaeb93ac0c0e31b39c2a3985ec Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 30 Mar 2024 16:15:35 +0000 Subject: [PATCH] K_PlayerIsEmptyHandedInSpecial Replaces the simple condition in K_HandleLapIncrement for successful player exit Essentially means you can get EMPTY HANDED? for crossing the finish line before the player with the emerald does --- src/k_specialstage.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/k_specialstage.h | 15 ++++++++++++++ src/p_spec.c | 2 +- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/k_specialstage.c b/src/k_specialstage.c index f40a65b86..9891a5ddd 100644 --- a/src/k_specialstage.c +++ b/src/k_specialstage.c @@ -161,6 +161,53 @@ mobj_t *K_GetPossibleSpecialTarget(void) return specialstageinfo.ufo; } +/*-------------------------------------------------- + boolean K_PlayerIsEmptyHandedInSpecial(void) + + See header file for description. +--------------------------------------------------*/ +boolean K_PlayerIsEmptyHandedInSpecial(player_t *player) +{ + if (specialstageinfo.valid == false) + return false; // Not Sealed Star + + if (!(specialstageinfo.ufo == NULL || P_MobjWasRemoved(specialstageinfo.ufo))) + return true; // UFO exists + + thinker_t *think; + mobj_t *thing; + player_t *orbitplayer = NULL; + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + thing = (mobj_t *)think; + if (thing->type != MT_EMERALD) + continue; + + // emerald_award(thing) + if (!thing->tracer || P_MobjWasRemoved(thing->tracer)) + continue; + if (thing->tracer->type != MT_PLAYER || !thing->tracer->player) + continue; + + orbitplayer = thing->tracer->player; + + if (orbitplayer->exiting && !(orbitplayer->pflags & PF_NOCONTEST)) + { + // Another player has successfully taken the emerald to the end + return false; + } + + // The emerald is being carried, but not by you + return (orbitplayer != player); + } + + // EMERALD DELETED!? + return true; +} + /*-------------------------------------------------- void K_FadeOutSpecialMusic(UINT32 distance) diff --git a/src/k_specialstage.h b/src/k_specialstage.h index cc26ca352..f0e194479 100644 --- a/src/k_specialstage.h +++ b/src/k_specialstage.h @@ -68,6 +68,21 @@ void K_TickSpecialStage(void); mobj_t *K_GetPossibleSpecialTarget(void); +/*-------------------------------------------------- + boolean K_PlayerIsEmptyHandedInSpecial(player_t *player) + + Gets whether the player has failed a Sealed + Star via finishing without an Emerald + + Input Arguments:- + player - Player to check for + + Return:- + Should player fail or not +--------------------------------------------------*/ + +boolean K_PlayerIsEmptyHandedInSpecial(player_t *player); + /*-------------------------------------------------- void K_FadeOutSpecialMusic(UINT32 distance) diff --git a/src/p_spec.c b/src/p_spec.c index 15865499e..7b49461a2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1997,7 +1997,7 @@ static void K_HandleLapIncrement(player_t *player) if (specialstageinfo.valid == true) { // Don't permit a win just by sneaking ahead of the UFO/emerald. - if (!(specialstageinfo.ufo == NULL || P_MobjWasRemoved(specialstageinfo.ufo))) + if (K_PlayerIsEmptyHandedInSpecial(player)) { applyflags |= PF_NOCONTEST;