summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArchez <Archez@users.noreply.github.com>2024-12-09 21:17:26 -0500
committerGitHub <noreply@github.com>2024-12-09 19:17:26 -0700
commit6470522a0221e20d899331d8d4b9f8cd187e27a5 (patch)
tree792aa50be19fca5b18019c6d2a6f81ae5c3b302d
parentde6f5d8b65db2149eec50db7db158570a31f0cde (diff)
Fix temp flags transfering in dungeon chains and various issues with voidouts in mixed entrances (#4637)
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor.h3
-rw-r--r--soh/soh/Enhancements/randomizer/hook_handlers.cpp36
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_entrance.c7
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c6
4 files changed, 42 insertions, 10 deletions
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index 8aa37a580..f91e3491e 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -281,6 +281,9 @@ typedef enum {
VB_SPAWN_BLUE_WARP,
// Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF
VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE,
+ // Vanilla condition: SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2
+ // Opt: int (original next entrance index)
+ VB_SET_VOIDOUT_FROM_SURFACE,
// Vanilla condition: this->collider.base.acFlags & 2
VB_BG_BREAKWALL_BREAK,
// Vanilla condition: true
diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp
index 000081cec..fa313d763 100644
--- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp
+++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp
@@ -1558,6 +1558,40 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
*should = !Flags_GetInfTable(INFTABLE_145) || Flags_GetInfTable(INFTABLE_146);
break;
}
+ case VB_SET_VOIDOUT_FROM_SURFACE: {
+ // ENTRTODO: Move all entrance rando handling to a dedicated file
+ std::vector<s16> entrPersistTempFlags = {
+ ENTR_DEKU_TREE_BOSS_ENTRANCE, ENTR_DEKU_TREE_BOSS_DOOR, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE,
+ ENTR_DODONGOS_CAVERN_BOSS_DOOR, ENTR_JABU_JABU_BOSS_ENTRANCE, ENTR_JABU_JABU_BOSS_DOOR,
+ ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, ENTR_FOREST_TEMPLE_BOSS_DOOR, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE,
+ ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_WATER_TEMPLE_BOSS_ENTRANCE, ENTR_WATER_TEMPLE_BOSS_DOOR,
+ ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, ENTR_SPIRIT_TEMPLE_BOSS_DOOR, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE,
+ ENTR_SHADOW_TEMPLE_BOSS_DOOR, ENTR_SPIRIT_TEMPLE_ENTRANCE,
+ };
+
+ s16 originalEntrance = (s16)va_arg(args, int);
+
+ // In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen
+ if (*should == true && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
+ // Check for dungeon special entrances that are randomized to a new location
+ if (std::find(entrPersistTempFlags.begin(), entrPersistTempFlags.end(), originalEntrance) !=
+ entrPersistTempFlags.end() && originalEntrance != gPlayState->nextEntranceIndex) {
+ // Normally dungeons use a special voidout between scenes so that entering/exiting a boss room,
+ // or leaving via Spirit Hands and going back in persist temp flags across scenes.
+ // For ER, the temp flags should be wiped out so that they aren't transferred to the new location.
+ gPlayState->actorCtx.flags.tempSwch = 0;
+ gPlayState->actorCtx.flags.tempCollect = 0;
+
+ // If the respawnFlag is set for a grotto return, we don't want the void out to happen.
+ // Set the data flag to one to prevent the respawn point from being overriden by dungeon doors.
+ if (gSaveContext.respawnFlag == 2) {
+ gSaveContext.respawn[RESPAWN_MODE_DOWN].data = 1;
+ *should = false;
+ }
+ }
+ }
+ break;
+ }
case VB_FREEZE_ON_SKULL_TOKEN:
case VB_TRADE_TIMER_ODD_MUSHROOM:
case VB_TRADE_TIMER_FROG:
@@ -1623,6 +1657,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) {
CheckTracker::RecalculateAllAreaTotals();
}
+ // ENTRTODO: Move all entrance rando handling to a dedicated file
if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
// In ER, override roomNum to load based on scene and spawn during scene init
if (gSaveContext.respawnFlag <= 0) {
@@ -2336,6 +2371,7 @@ void RandomizerRegisterHooks() {
if (!IS_RANDO) return;
+ // ENTRTODO: Move all entrance rando handling to a dedicated file
// Setup the modified entrance table and entrance shuffle table for rando
Entrance_Init();
diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c
index 8f4a1668c..7a492fe9c 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c
+++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c
@@ -267,13 +267,6 @@ s16 Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex) {
}
s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) {
- // When entering Spirit Temple, clear temp flags so they don't carry over to the randomized dungeon
- if (nextEntranceIndex == ENTR_SPIRIT_TEMPLE_ENTRANCE && Entrance_GetOverride(nextEntranceIndex) != nextEntranceIndex &&
- gPlayState != NULL) {
- gPlayState->actorCtx.flags.tempSwch = 0;
- gPlayState->actorCtx.flags.tempCollect = 0;
- }
-
// Exiting through the crawl space from Hyrule Castle courtyard is the same exit as leaving Ganon's castle
// Don't override the entrance if we came from the Castle courtyard (day and night scenes)
if (gPlayState != NULL && (gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_DAY || gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_NIGHT) &&
diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c
index 16abaf568..ade67d576 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -5145,9 +5145,9 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol
Scene_SetTransitionForNextEntrance(play);
} else {
- // In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen
- if (SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 &&
- (!IS_RANDO || (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && gSaveContext.respawnFlag != 2))) {
+ if (GameInteractor_Should(VB_SET_VOIDOUT_FROM_SURFACE,
+ SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2,
+ play->setupExitList[exitIndex - 1])) {
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = play->nextEntranceIndex;
Play_TriggerVoidOut(play);
gSaveContext.respawnFlag = -2;