Fix temp flags transfering in dungeon chains and various issues with voidouts in mixed entrances (#4637)

This commit is contained in:
Archez 2024-12-09 21:17:26 -05:00 committed by GitHub
parent de6f5d8b65
commit 6470522a02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 10 deletions

View File

@ -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

View File

@ -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();

View File

@ -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) &&

View File

@ -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;