mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-25 02:42:18 -05:00
Fix Bluewarp handling with entrance rando (#4517)
* force bluewarp skips on when entrance rando is enabled * Fix second visits and other issues with lingering bluewarp state
This commit is contained in:
parent
20ac33d380
commit
d8f8b6e6b9
@ -3,35 +3,43 @@
|
|||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||||
#include "z64save.h"
|
#include "z64save.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()
|
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()
|
||||||
|
|
||||||
|
static bool sEnteredBlueWarp = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
|
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
|
||||||
* set the entrance index to where you would normally end up after the blue warp cutscene. This
|
* set the entrance index to where you would normally end up after the blue warp cutscene. This
|
||||||
* should also account for the difference between your first and following visits to the blue warp.
|
* should also account for the difference between your first and following visits to the blue warp.
|
||||||
*/
|
*/
|
||||||
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
||||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
bool overrideBlueWarpDestinations =
|
||||||
uint8_t isBlueWarpCutscene = 0;
|
IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
|
||||||
|
RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
|
||||||
|
|
||||||
|
// Force blue warp skip on when ER needs to place Link somewhere else.
|
||||||
|
// This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after.
|
||||||
|
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) {
|
||||||
|
bool isBlueWarpCutscene = false;
|
||||||
// Deku Tree Blue warp
|
// Deku Tree Blue warp
|
||||||
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Dodongo's Cavern Blue warp
|
// Dodongo's Cavern Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) {
|
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Jabu Jabu's Blue warp
|
// Jabu Jabu's Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) {
|
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) {
|
||||||
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Forest Temple Blue warp
|
// Forest Temple Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
|
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
|
||||||
// Normally set in the blue warp cutscene
|
// Normally set in the blue warp cutscene
|
||||||
@ -43,14 +51,14 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
|||||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
|
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
|
||||||
}
|
}
|
||||||
|
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Fire Temple Blue warp
|
// Fire Temple Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) {
|
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) {
|
||||||
// Normally set in the blue warp cutscene
|
// Normally set in the blue warp cutscene
|
||||||
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
|
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
|
||||||
|
|
||||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Water Temple Blue warp
|
// Water Temple Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
|
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
|
||||||
// Normally set in the blue warp cutscene
|
// Normally set in the blue warp cutscene
|
||||||
@ -58,15 +66,15 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
|||||||
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
||||||
|
|
||||||
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Spirit Temple Blue warp
|
// Spirit Temple Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
|
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
|
||||||
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
// Shadow Temple Blue warp
|
// Shadow Temple Blue warp
|
||||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
|
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
|
||||||
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
|
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
|
||||||
isBlueWarpCutscene = 1;
|
isBlueWarpCutscene = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBlueWarpCutscene) {
|
if (isBlueWarpCutscene) {
|
||||||
@ -80,10 +88,20 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is outside the above condition because we want to handle both first and following visits to the blue warp
|
// This is outside the above condition because we want to handle both first and following visits to the blue warp
|
||||||
if (IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
|
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
|
||||||
Entrance_OverrideBlueWarp();
|
Entrance_OverrideBlueWarp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sEnteredBlueWarp = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using this hook to simply observe that Link has entered a bluewarp
|
||||||
|
* This way we know to allow entrance rando overrides to be processed on the next tranisition hook
|
||||||
|
*/
|
||||||
|
void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
||||||
|
sEnteredBlueWarp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,6 +161,7 @@ void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _,
|
|||||||
void SkipBlueWarp_Register() {
|
void SkipBlueWarp_Register() {
|
||||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate);
|
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate);
|
||||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
|
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
|
||||||
|
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS);
|
||||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
|
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
|
||||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem);
|
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ void Entrance_Init(void) {
|
|||||||
bossSceneSaveDeathWarps[bossScene - SCENE_DEKU_TREE_BOSS] = saveWarpEntrance;
|
bossSceneSaveDeathWarps[bossScene - SCENE_DEKU_TREE_BOSS] = saveWarpEntrance;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Overwrite grotto related indices
|
// Overwrite grotto related indices
|
||||||
if (originalIndex >= ENTRANCE_GROTTO_EXIT_START) {
|
if (originalIndex >= ENTRANCE_GROTTO_EXIT_START) {
|
||||||
Grotto_SetExitOverride(originalIndex, overrideIndex);
|
Grotto_SetExitOverride(originalIndex, overrideIndex);
|
||||||
continue;
|
continue;
|
||||||
@ -226,7 +226,7 @@ void Entrance_Init(void) {
|
|||||||
|
|
||||||
s16 indicesToSilenceBackgroundMusic[2] = {
|
s16 indicesToSilenceBackgroundMusic[2] = {
|
||||||
// The lost woods music playing near the GC Woods Warp keeps playing
|
// The lost woods music playing near the GC Woods Warp keeps playing
|
||||||
// in the next area if the bvackground music is allowed to keep playing
|
// in the next area if the background music is allowed to keep playing
|
||||||
entranceOverrideTable[ENTR_LOST_WOODS_TUNNEL_SHORTCUT], // Goron City -> Lost Woods override
|
entranceOverrideTable[ENTR_LOST_WOODS_TUNNEL_SHORTCUT], // Goron City -> Lost Woods override
|
||||||
|
|
||||||
// If Malon is singing at night, then her singing will be transferred
|
// If Malon is singing at night, then her singing will be transferred
|
||||||
@ -452,7 +452,19 @@ void Entrance_SetWarpSongEntrance(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Entrance_OverrideBlueWarp(void) {
|
void Entrance_OverrideBlueWarp(void) {
|
||||||
// Handles first time entering bluewarp (with item give)
|
// Remap child 2nd visits in adult dungeons for warp pad -> bluewarp
|
||||||
|
if (gSaveContext.entranceIndex == ENTR_SACRED_FOREST_MEADOW_WARP_PAD) {
|
||||||
|
gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP;
|
||||||
|
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD) {
|
||||||
|
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
|
||||||
|
} else if (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD) {
|
||||||
|
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
|
||||||
|
} else if (gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_WARP_PAD) {
|
||||||
|
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
|
||||||
|
} else if (gSaveContext.entranceIndex == ENTR_GRAVEYARD_WARP_PAD) {
|
||||||
|
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
|
||||||
|
}
|
||||||
|
|
||||||
switch (gSaveContext.entranceIndex) {
|
switch (gSaveContext.entranceIndex) {
|
||||||
case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp
|
case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp
|
||||||
case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp
|
case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp
|
||||||
@ -465,20 +477,6 @@ void Entrance_OverrideBlueWarp(void) {
|
|||||||
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
|
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles second+ times entering bluewarp
|
|
||||||
switch (gPlayState->nextEntranceIndex) {
|
|
||||||
case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp
|
|
||||||
case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp
|
|
||||||
case ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP: // Barinade blue warp
|
|
||||||
case ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP: // Phantom Ganon blue warp
|
|
||||||
case ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP: // Volvagia blue warp
|
|
||||||
case ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP: // Morpha blue warp
|
|
||||||
case ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP: // Bongo-Bongo blue warp
|
|
||||||
case ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP: // Twinrova blue warp
|
|
||||||
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(gPlayState->nextEntranceIndex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entrance_EnableFW(void) {
|
void Entrance_EnableFW(void) {
|
||||||
|
@ -99,6 +99,10 @@ void Grotto_InitExitAndLoadLists(void) {
|
|||||||
grottoLoadList[i] = ENTRANCE_GROTTO_LOAD_START + i;
|
grottoLoadList[i] = ENTRANCE_GROTTO_LOAD_START + i;
|
||||||
grottoExitList[i] = ENTRANCE_GROTTO_EXIT_START + i;
|
grottoExitList[i] = ENTRANCE_GROTTO_EXIT_START + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grottoId = 0xFF;
|
||||||
|
lastEntranceType = NOT_GROTTO;
|
||||||
|
overridingNextEntrance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex) {
|
void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex) {
|
||||||
|
Loading…
Reference in New Issue
Block a user