From 4265019923b96f36d642a4c0db6b88af6b28a27a Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Sat, 22 Jan 2022 14:07:55 -0800 Subject: [PATCH] Fix NON_STOP_STARS & bhvCelebrationStar related issues with Bowser keys (#299) Fix NON_STOP_STARS issues & bhvCelebrationStar related issues with Bowser keys --- include/config/config_game.h | 9 ++++----- include/config/config_graphics.h | 4 ++++ src/audio/external.c | 8 ++++++-- src/audio/external.h | 2 +- src/game/behaviors/celebration_star.inc.c | 13 +++++-------- src/game/interaction.c | 8 ++++++-- src/game/mario_actions_cutscene.c | 18 +++++++++++++++--- 7 files changed, 41 insertions(+), 21 deletions(-) diff --git a/include/config/config_game.h b/include/config/config_game.h index a1b3289c..5c9456eb 100644 --- a/include/config/config_game.h +++ b/include/config/config_game.h @@ -32,13 +32,12 @@ // Number of coins to spawn the "100 coin" star. If you remove the define altogether, then there won't be a 100 coin star at all. #define X_COIN_STAR 100 -/* - * Stars don't kick you out of the level (does not play nicely with vanilla) - * In v2.0 there are numerous issues with this define that can be seen here https://github.com/Reonu/HackerSM64/issues/258 - * Use at your own risk. -*/ +// Stars don't kick you out of the level (does not play nicely with vanilla). // #define NON_STOP_STARS +// Bowser keys always exit the level. Only has an effect if NON_STOP_STARS is enabled. +// #define KEYS_EXIT_LEVEL + // Uncomment this if you want global star IDs (useful for creating an open world hack ala MVC). // #define GLOBAL_STAR_IDS diff --git a/include/config/config_graphics.h b/include/config/config_graphics.h index 99743c80..1b210736 100644 --- a/include/config/config_graphics.h +++ b/include/config/config_graphics.h @@ -66,6 +66,10 @@ // Disables the fix to Koopa's unshelled model. #define KOOPA_KEEP_PINK_SHORTS +// Uses the star object's model in the star dance cutscene. +// This has a side effect of making the star dance star also transparent when Mario collects a transparent star. +// #define STAR_DANCE_USES_STARS_MODEL + // Lightweight directional lighting engine by Fazana. Intended for giving proximity and positional pointlights to small objects. // NOTE: Still breaks occasionally, and PUPPYLIGHT_NODE might not work in areas that aren't area 1. // #define PUPPYLIGHTS diff --git a/src/audio/external.c b/src/audio/external.c index 4aca7632..99bc5c73 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2401,8 +2401,12 @@ void func_803210D4(u16 fadeDuration) { /** * Called from threads: thread5_game_loop */ -void play_course_clear(void) { - seq_player_play_sequence(SEQ_PLAYER_ENV, SEQ_EVENT_CUTSCENE_COLLECT_STAR, 0); +void play_course_clear(s32 isKey) { + if (isKey) { + seq_player_play_sequence(SEQ_PLAYER_ENV, SEQ_EVENT_CUTSCENE_COLLECT_KEY, 0); + } else { + seq_player_play_sequence(SEQ_PLAYER_ENV, SEQ_EVENT_CUTSCENE_COLLECT_STAR, 0); + } sBackgroundMusicMaxTargetVolume = TARGET_VOLUME_IS_PRESENT_FLAG | 0; #if defined(VERSION_EU) || defined(VERSION_SH) D_EU_80300558 = 2; diff --git a/src/audio/external.h b/src/audio/external.h index 29d46374..6079f439 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -59,7 +59,7 @@ u32 get_current_background_music(void); void play_secondary_music(u8 seqId, u8 bgMusicVolume, u8 volume, u16 fadeTimer); void func_80321080(u16 fadeTimer); void func_803210D4(u16 fadeOutTime); -void play_course_clear(void); +void play_course_clear(s32 isKey); void play_peachs_jingle(void); void play_puzzle_jingle(void); void play_star_fanfare(void); diff --git a/src/game/behaviors/celebration_star.inc.c b/src/game/behaviors/celebration_star.inc.c index a4da1e04..a0af4308 100644 --- a/src/game/behaviors/celebration_star.inc.c +++ b/src/game/behaviors/celebration_star.inc.c @@ -6,18 +6,15 @@ void bhv_celebration_star_init(void) { o->oHomeZ = gMarioObject->header.gfx.pos[2]; o->oMoveAngleYaw = gMarioObject->header.gfx.angle[1] + 0x8000; o->oCelebStarDiameterOfRotation = 100; - if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2) { - o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_BOWSER_KEY]; - o->oFaceAnglePitch = 0; + o->oFaceAnglePitch = 0; + if (obj_has_model(gMarioState->interactObj, MODEL_BOWSER_KEY)) { o->oFaceAngleRoll = 0xC000; cur_obj_scale(0.1f); - o->oCelebStarIsBowserKey = 1; + o->oCelebStarIsBowserKey = TRUE; } else { - o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_STAR]; - o->oFaceAnglePitch = 0; o->oFaceAngleRoll = 0; cur_obj_scale(0.4f); - o->oCelebStarIsBowserKey = 0; + o->oCelebStarIsBowserKey = FALSE; } } @@ -42,7 +39,7 @@ void celeb_star_act_spin_around_mario(void) { void celeb_star_act_face_camera(void) { if (o->oTimer < 10) { - if (o->oCelebStarIsBowserKey == 0) { + if (o->oCelebStarIsBowserKey == FALSE) { cur_obj_scale((f32) o->oTimer / 10.0f); } else { cur_obj_scale((f32) o->oTimer / 30.0f); diff --git a/src/game/interaction.c b/src/game/interaction.c index f996b867..80b09f6e 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -764,10 +764,14 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O u32 starIndex; u32 starGrabAction = ACT_STAR_DANCE_EXIT; #ifdef NON_STOP_STARS + #ifdef KEYS_EXIT_LEVEL + u32 noExit = !obj_has_model(obj, MODEL_BOWSER_KEY); + #else u32 noExit = TRUE; -#else + #endif +#else // !NON_STOP_STARS u32 noExit = (obj->oInteractionSubtype & INT_SUBTYPE_NO_EXIT) != 0; -#endif +#endif // !NON_STOP_STARS u32 grandStar = (obj->oInteractionSubtype & INT_SUBTYPE_GRAND_STAR) != 0; if (m->health >= 0x100) { diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index b7408719..8a65acc6 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -582,15 +582,27 @@ s32 act_debug_free_move(struct MarioState *m) { } void general_star_dance_handler(struct MarioState *m, s32 isInWater) { + struct Object *celebStar = NULL; + if (m->actionState == ACT_STATE_STAR_DANCE_CUTSCENE) { switch (++m->actionTimer) { case 1: - spawn_object(m->marioObj, MODEL_STAR, bhvCelebrationStar); + celebStar = spawn_object(m->marioObj, MODEL_STAR, bhvCelebrationStar); +#ifdef STAR_DANCE_USES_STARS_MODEL + celebStar->header.gfx.sharedChild = m->interactObj->header.gfx.sharedChild; +#else + if (obj_has_model(m->interactObj, MODEL_BOWSER_KEY)) { + obj_set_model(celebStar, MODEL_BOWSER_KEY); + } +#endif disable_background_sound(); + //! TODO: Is this check necessary? Both seem to do the exact same thing. if (m->actionArg & 1) { - play_course_clear(); + // No exit + play_course_clear(obj_has_model(celebStar, MODEL_BOWSER_KEY)); } else { - if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2) { + // Exit + if (obj_has_model(celebStar, MODEL_BOWSER_KEY)) { play_music(SEQ_PLAYER_ENV, SEQUENCE_ARGS(15, SEQ_EVENT_CUTSCENE_COLLECT_KEY), 0); } else { play_music(SEQ_PLAYER_ENV, SEQUENCE_ARGS(15, SEQ_EVENT_CUTSCENE_COLLECT_STAR), 0);