Rando: Boss Entrance Shuffle (#2194)

* sync 3ds upstream logic changes for boss rooms

* add boss shuffle settings and handling to 3ds code

* add boss shuffle handling to game code

* repair authentically bugged entrances for boss shuffle

* add boss entrances to the entrance tracker

* unset hint area for boss rooms to fix altar hint

* update boss reward hints to not mention dungeons

* one more boss heart container hint fix

* reorder entrance rando funcs

* support closed forest with boss shuffle and simple boss room entrance pairs in shuffle table

* fix death warp in boss rooms without saving; fix KD boss room in tracker

* remove boss shuffle check from dungeon open checks and some cleanups

* add boss shuffle to preset clear

* remove dungeon entry exit connection from boss rooms

* another no hint fix for boss shuffle

* undo change for exact location hints

* clarify comments
This commit is contained in:
Adam Bird
2023-01-20 01:00:12 -05:00
committed by GitHub
parent 7964bde063
commit 261db2c3e1
33 changed files with 919 additions and 881 deletions

View File

@@ -1,5 +1,6 @@
#include "global.h"
#include "vt.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
void func_80095AB4(PlayState* play, Room* room, u32 flags);
void func_80095D04(PlayState* play, Room* room, u32 flags);
@@ -575,6 +576,12 @@ u32 func_80096FE8(PlayState* play, RoomContext* roomCtx) {
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum) {
size_t size;
// In ER, override roomNum to load based on scene and spawn
if (gSaveContext.n64ddFlag && gSaveContext.respawnFlag <= 0 &&
Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
roomNum = Entrance_OverrideSpawnSceneRoom(play->sceneNum, play->curSpawn, roomNum);
}
return OTRfunc_8009728C(play, roomCtx, roomNum);
if (roomCtx->status == 0) {

View File

@@ -49,8 +49,9 @@ void BgSpot01Idosoko_Init(Actor* thisx, PlayState* play) {
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
// If dungeon entrance randomizer is on, remove the well stone as adult Link when
// child Link has drained the water to the well
if (!LINK_IS_ADULT || gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
Flags_GetEventChkInf(0x67)) {
if (!LINK_IS_ADULT || (gSaveContext.n64ddFlag &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
Flags_GetEventChkInf(0x67))) {
Actor_Kill(&this->dyna.actor);
} else {
BgSpot01Idosoko_SetupAction(this, func_808ABF54);

View File

@@ -60,7 +60,7 @@ void BgSpot12Saku_Init(Actor* thisx, PlayState* play) {
// If ER is on, force the gate to always use its permanent flag
// (which it only uses in Child Gerudo Fortress in the vanilla game)
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) {
thisx->params = 0x0002;
}
@@ -132,7 +132,7 @@ void BgSpot12Saku_Update(Actor* thisx, PlayState* play) {
BgSpot12Saku* this = (BgSpot12Saku*)thisx;
// If ER is on, when the guard opens the GtG gate its permanent flag will be set.
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
Flags_GetSwitch(play, 0x3A)) {
Flags_SetSwitch(play, 0x2);
}

View File

@@ -73,8 +73,10 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) {
if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) {
BgTreemouth_SetupAction(this, func_808BC8B8);
// If dungeon entrance randomizer is on, keep the tree mouth open when link is adult and sword & shield have been shown to mido
} else if ((LINK_IS_ADULT && (!gSaveContext.n64ddFlag || !Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) ||
// If dungeon entrance randomizer is on, keep the tree mouth open
// when Link is adult and sword & shield have been shown to mido
} else if ((LINK_IS_ADULT && (!gSaveContext.n64ddFlag ||
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) ||
!Flags_GetEventChkInf(0x4)) || (gSaveContext.sceneSetupIndex == 7)) {
this->unk_168 = 0.0f;
BgTreemouth_SetupAction(this, BgTreemouth_DoNothing);

View File

@@ -582,7 +582,8 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}
@@ -688,7 +689,8 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0xFFF0;
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}
@@ -903,7 +905,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
}
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}

View File

@@ -332,7 +332,8 @@ void EnIshi_Init(Actor* thisx, PlayState* play) {
}
// If dungeon entrance randomizer is on, remove the grey boulders that normally
// block child Link from reaching the Fire Temple entrance.
if (type == ROCK_LARGE && gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
if (type == ROCK_LARGE && gSaveContext.n64ddFlag &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
play->sceneNum == 0x061) { // Death Mountain Creater
Actor_Kill(&this->actor);
}

View File

@@ -4127,6 +4127,11 @@ void KaleidoScope_Update(PlayState* play)
gSaveContext.entranceIndex = 0x041B;
break;
}
// In ER, handle overriding the game over respawn entrance
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
Entrance_SetGameOverEntrance();
}
} else {
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}