mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-21 23:58:51 -05:00
Fix grotto handling with the skip intro timesaver (#4252)
This commit is contained in:
parent
c68cecec71
commit
e66dada09d
@ -3,11 +3,11 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_grotto.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
void SkipIntro_Register() {
|
||||
@ -15,31 +15,33 @@ void SkipIntro_Register() {
|
||||
// If we're playing rando and if starting age is adult and/or overworld spawns are shuffled we need to skip
|
||||
// the cutscene regardless of the enhancement being on.
|
||||
bool adultStart = gSaveContext.linkAge == LINK_AGE_ADULT;
|
||||
bool shuffleOverworldSpawns = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_OVERWORLD_SPAWNS).Is(true);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), IS_RANDO) || (IS_RANDO && (adultStart || shuffleOverworldSpawns))) {
|
||||
// Calculate spawn location. Start with vanilla, Link's house.
|
||||
int32_t spawnEntrance = ENTR_LINKS_HOUSE_0;
|
||||
// If we're not in rando, we can skip all of the below.
|
||||
if (IS_RANDO) {
|
||||
// If starting age is shuffled, use vanilla adult spawn/prelude warp.
|
||||
bool shuffleOverworldSpawns =
|
||||
OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_OVERWORLD_SPAWNS).Is(true);
|
||||
if ((CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), IS_RANDO) ||
|
||||
(IS_RANDO && (adultStart || shuffleOverworldSpawns)) && gSaveContext.cutsceneIndex == 0xFFF1)) {
|
||||
// Calculate spawn location. Start with vanilla, Link's house.
|
||||
int32_t spawnEntrance = ENTR_LINKS_HOUSE_0;
|
||||
// If we're not in rando, we can skip all of the below.
|
||||
if (IS_RANDO) {
|
||||
// If starting age is shuffled, use vanilla adult spawn/prelude warp.
|
||||
if (adultStart) {
|
||||
spawnEntrance = ENTR_TEMPLE_OF_TIME_7;
|
||||
}
|
||||
// If we're shuffling overworld spawns we'll need to get the Entrance Override
|
||||
if (shuffleOverworldSpawns) {
|
||||
// If we're shuffling overworld spawns the adult spawn is ENTR_HYRULE_FIELD_10 instead of
|
||||
// ENTR_TEMPLE_OF_TIME_7, so that spawn and Prelude don't share an entrance.
|
||||
if (adultStart) {
|
||||
spawnEntrance = ENTR_TEMPLE_OF_TIME_7;
|
||||
}
|
||||
// If we're shuffling overworld spawns we'll need to get the Entrance Override
|
||||
if (shuffleOverworldSpawns) {
|
||||
// If we're shuffling overworld spawns the adult spawn is ENTR_HYRULE_FIELD_10 instead of
|
||||
// ENTR_TEMPLE_OF_TIME_7, so that spawn and Prelude don't share an entrance.
|
||||
if (adultStart){
|
||||
spawnEntrance = ENTR_HYRULE_FIELD_10;
|
||||
}
|
||||
spawnEntrance = Grotto_OverrideSpecialEntrance(Entrance_GetOverride(spawnEntrance));
|
||||
spawnEntrance = ENTR_HYRULE_FIELD_10;
|
||||
}
|
||||
spawnEntrance = Entrance_PeekNextIndexOverride(spawnEntrance);
|
||||
}
|
||||
// Skip the intro cutscene for whatever the spawnEntrance is calculated to be.
|
||||
if (gSaveContext.entranceIndex == spawnEntrance) {
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
// Skip the intro cutscene for whatever the spawnEntrance is calculated to be.
|
||||
if (gSaveContext.entranceIndex == spawnEntrance) {
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -260,6 +260,10 @@ s16 Entrance_GetOverride(s16 index) {
|
||||
return entranceOverrideTable[index];
|
||||
}
|
||||
|
||||
s16 Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex) {
|
||||
return Grotto_GetEntranceValueHandlingGrottoRando(Entrance_GetOverride(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_0 && Entrance_GetOverride(nextEntranceIndex) != nextEntranceIndex &&
|
||||
|
@ -81,6 +81,7 @@ void Entrance_ResetEntranceTable(void);
|
||||
uint8_t Entrance_EntranceIsNull(EntranceOverride* entranceOverride);
|
||||
int16_t Entrance_GetOverride(int16_t index);
|
||||
int16_t Entrance_OverrideNextIndex(int16_t nextEntranceIndex);
|
||||
int16_t Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex);
|
||||
int16_t Entrance_OverrideDynamicExit(int16_t dynamicExitIndex);
|
||||
uint32_t Entrance_SceneAndSpawnAre(uint8_t scene, uint8_t spawn);
|
||||
void Entrance_SetGameOverEntrance(void);
|
||||
|
@ -128,8 +128,49 @@ static void Grotto_SetupReturnInfo(GrottoReturnInfo grotto, RespawnMode respawnM
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next entrance value while handling conversion of grotto rando IDs to real entrance values.
|
||||
// This method doesn't change player respawn data, so only use this if you are querying an entrance index.
|
||||
s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) {
|
||||
// Don't change anything unless grotto shuffle has been enabled
|
||||
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) {
|
||||
return nextEntranceIndex;
|
||||
}
|
||||
|
||||
// If Link hits a grotto exit, load the entrance index from the grotto exit list
|
||||
// based on the current grotto ID
|
||||
if (nextEntranceIndex == ENTR_RETURN_GROTTO) {
|
||||
nextEntranceIndex = grottoExitList[grottoId];
|
||||
}
|
||||
|
||||
// Get the new grotto id from the next entrance
|
||||
grottoId = nextEntranceIndex & 0x00FF;
|
||||
|
||||
// Grotto Returns
|
||||
if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START + NUM_GROTTOS) {
|
||||
GrottoReturnInfo grotto = grottoReturnTable[grottoId];
|
||||
|
||||
// When the nextEntranceIndex is determined by a dynamic exit,
|
||||
// or set by Entrance_OverrideBlueWarp to mark a blue warp entrance,
|
||||
// we have to set the respawn information and nextEntranceIndex manually
|
||||
if (gPlayState != NULL && gPlayState->nextEntranceIndex != ENTR_LOAD_OPENING) {
|
||||
nextEntranceIndex = grotto.entranceIndex;
|
||||
} else if (gPlayState == NULL) { // Handle spawn position when loading from a save file
|
||||
nextEntranceIndex = grotto.entranceIndex;
|
||||
// Otherwise return 0x7FFF (ENTR_RETURN_GROTTO) and let the game handle it
|
||||
} else {
|
||||
nextEntranceIndex = ENTR_RETURN_GROTTO;
|
||||
}
|
||||
// Grotto Loads
|
||||
} else if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START) {
|
||||
GrottoLoadInfo grotto = grottoLoadTable[grottoId];
|
||||
nextEntranceIndex = grotto.entranceIndex;
|
||||
}
|
||||
|
||||
return nextEntranceIndex;
|
||||
}
|
||||
|
||||
// Translates and overrides the passed in entrance index if it corresponds to a
|
||||
// special grotto entrance (grotto load or returnpoint)
|
||||
// special grotto entrance (grotto load or returnpoint) and updates player respawn data correctly.
|
||||
s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) {
|
||||
|
||||
// Don't change anything unless grotto shuffle has been enabled
|
||||
|
@ -24,7 +24,8 @@ typedef struct {
|
||||
void Grotto_InitExitAndLoadLists(void);
|
||||
void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex);
|
||||
void Grotto_SetLoadOverride(s16 originalIndex, s16 overrideIndex);
|
||||
s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex);
|
||||
s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex);
|
||||
s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex);
|
||||
void Grotto_ForceGrottoReturnOnSpecialEntrance(void);
|
||||
void Grotto_ForceGrottoReturn(void);
|
||||
void Grotto_ForceRegularVoidOut(void);
|
||||
|
Loading…
Reference in New Issue
Block a user