mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-14 10:37:17 -07:00
Entrance Rando (#1760)
This commit is contained in:
parent
8be2c4ddd7
commit
15a9975200
36 changed files with 1341 additions and 142 deletions
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h"
|
||||
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
u16 D_8011E1C0 = 0;
|
||||
u16 D_8011E1C4 = 0;
|
||||
|
||||
|
@ -1236,6 +1238,10 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
|
|||
play->fadeTransition = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (randoCsSkip) {
|
||||
Entrance_OverrideCutsceneEntrance(cmd->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "textures/do_action_static/do_action_static.h"
|
||||
#include "textures/icon_item_static/icon_item_static.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
|
@ -6361,6 +6362,12 @@ void Interface_Update(PlayState* play) {
|
|||
|
||||
gSaveContext.respawnFlag = -2;
|
||||
play->nextEntranceIndex = gSaveContext.entranceIndex;
|
||||
|
||||
// In ER, handle sun song respawn from last entrance from grottos
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_ForceGrottoReturn();
|
||||
}
|
||||
|
||||
play->sceneLoadFlag = 0x14;
|
||||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||||
func_800F6964(30);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <ImGuiImpl.h>
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/debugconsole.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
#include <overlays/actors/ovl_En_Niw/z_en_niw.h>
|
||||
|
||||
#include <time.h>
|
||||
|
@ -158,6 +159,11 @@ void Play_Destroy(GameState* thisx) {
|
|||
PlayState* play = (PlayState*)thisx;
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
// In ER, remove link from epona when entering somewhere that doesn't support epona
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) {
|
||||
Entrance_HandleEponaState();
|
||||
}
|
||||
|
||||
play->state.gfxCtx->callback = NULL;
|
||||
play->state.gfxCtx->callbackParam = 0;
|
||||
SREG(91) = 0;
|
||||
|
@ -512,6 +518,7 @@ void Play_Init(GameState* thisx) {
|
|||
play,
|
||||
gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].scene,
|
||||
gEntranceTable[((void)0, gSaveContext.sceneSetupIndex) + ((void)0, gSaveContext.entranceIndex)].spawn);
|
||||
|
||||
osSyncPrintf("\nSCENE_NO=%d COUNTER=%d\n", ((void)0, gSaveContext.entranceIndex), gSaveContext.sceneSetupIndex);
|
||||
|
||||
Cutscene_HandleEntranceTriggers(play);
|
||||
|
@ -1754,6 +1761,10 @@ void* Play_LoadFile(PlayState* play, RomFile* file) {
|
|||
}
|
||||
|
||||
void Play_InitEnvironment(PlayState* play, s16 skyboxId) {
|
||||
// For entrance rando, ensure the correct weather state and sky mode is applied
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Entrance_OverrideWeatherState();
|
||||
}
|
||||
Skybox_Init(&play->state, &play->skyboxCtx, skyboxId);
|
||||
Environment_Init(play, &play->envCtx, 0);
|
||||
}
|
||||
|
@ -1781,6 +1792,10 @@ void Play_InitScene(PlayState* play, s32 spawn)
|
|||
void Play_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn) {
|
||||
|
||||
OTRPlay_SpawnScene(play, sceneNum, spawn);
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Entrance_OverrideSpawnScene(sceneNum, spawn);
|
||||
}
|
||||
}
|
||||
|
||||
void func_800C016C(PlayState* play, Vec3f* src, Vec3f* dest) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <string.h>
|
||||
#include <soh/Enhancements/randomizer/randomizerTypes.h>
|
||||
#include <soh/Enhancements/randomizer/randomizer_inf.h>
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define NUM_DUNGEONS 8
|
||||
|
@ -196,6 +197,19 @@ void Sram_OpenSave() {
|
|||
}
|
||||
}
|
||||
|
||||
// Setup the modified entrance table and entrance shuffle table for rando
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Entrance_Init();
|
||||
if (!CVar_GetS32("gRememberSaveLocation", 0) || gSaveContext.savedSceneNum == SCENE_YOUSEI_IZUMI_TATE ||
|
||||
gSaveContext.savedSceneNum == SCENE_KAKUSIANA) {
|
||||
Entrance_SetSavewarpEntrance();
|
||||
}
|
||||
} else {
|
||||
// When going from a rando save to a vanilla save within the same game instance
|
||||
// we need to reset the entrance table back to its vanilla state
|
||||
Entrance_ResetEntranceTable();
|
||||
}
|
||||
|
||||
osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex);
|
||||
osSyncPrintf(VT_RST);
|
||||
|
||||
|
|
|
@ -47,7 +47,10 @@ void BgSpot01Idosoko_Init(Actor* thisx, PlayState* play) {
|
|||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
CollisionHeader_GetVirtual(&gKakarikoBOTWStoneCol, &colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
if (!LINK_IS_ADULT) {
|
||||
// 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)) {
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
} else {
|
||||
BgSpot01Idosoko_SetupAction(this, func_808ABF54);
|
||||
|
|
|
@ -58,6 +58,12 @@ void func_808B3420(BgSpot12Saku* this, PlayState* play, CollisionHeader* collisi
|
|||
void BgSpot12Saku_Init(Actor* thisx, PlayState* play) {
|
||||
BgSpot12Saku* this = (BgSpot12Saku*)thisx;
|
||||
|
||||
// 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)) {
|
||||
thisx->params = 0x0002;
|
||||
}
|
||||
|
||||
func_808B3420(this, play, &gGerudoFortressGTGShutterCol, DPM_UNK);
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) {
|
||||
|
@ -125,6 +131,12 @@ void func_808B37AC(BgSpot12Saku* this, PlayState* play) {
|
|||
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) &&
|
||||
Flags_GetSwitch(play, 0x3A)) {
|
||||
Flags_SetSwitch(play, 0x2);
|
||||
}
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,9 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) {
|
|||
|
||||
if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) {
|
||||
BgTreemouth_SetupAction(this, func_808BC8B8);
|
||||
} else if (LINK_IS_ADULT || (gSaveContext.sceneSetupIndex == 7)) {
|
||||
// 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)) ||
|
||||
!Flags_GetEventChkInf(0x4)) || (gSaveContext.sceneSetupIndex == 7)) {
|
||||
this->unk_168 = 0.0f;
|
||||
BgTreemouth_SetupAction(this, BgTreemouth_DoNothing);
|
||||
} else {
|
||||
|
|
|
@ -867,7 +867,12 @@ void func_80986B2C(PlayState* play) {
|
|||
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
play->nextEntranceIndex = 0xCD;
|
||||
// In entrance rando have impa bring link back to the front of castle grounds
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) {
|
||||
play->nextEntranceIndex = 0x0138;
|
||||
} else {
|
||||
play->nextEntranceIndex = 0xCD;
|
||||
}
|
||||
play->fadeTransition = 38;
|
||||
play->sceneLoadFlag = 0x14;
|
||||
func_8002DF54(play, &player->actor, 8);
|
||||
|
@ -911,7 +916,12 @@ void GivePlayerRandoRewardImpa(Actor* impa, PlayState* play, RandomizerCheck che
|
|||
play->sceneLoadFlag = 0x14;
|
||||
play->fadeTransition = 3;
|
||||
gSaveContext.nextTransition = 3;
|
||||
play->nextEntranceIndex = 0x0594;
|
||||
// In entrance rando have impa bring link back to the front of castle grounds
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) {
|
||||
play->nextEntranceIndex = 0x0138;
|
||||
} else {
|
||||
play->nextEntranceIndex = 0x0594;
|
||||
}
|
||||
gSaveContext.nextCutsceneIndex = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "z_door_ana.h"
|
||||
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_25
|
||||
|
||||
|
@ -139,6 +140,12 @@ void DoorAna_WaitOpen(DoorAna* this, PlayState* play) {
|
|||
destinationIdx = this->actor.home.rot.z + 1;
|
||||
}
|
||||
play->nextEntranceIndex = entrances[destinationIdx];
|
||||
|
||||
// In ER, load the correct entrance based on the grotto link is falling into
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_OverrideActorEntrance(&this->actor);
|
||||
}
|
||||
|
||||
DoorAna_SetupAction(this, DoorAna_GrabPlayer);
|
||||
} else {
|
||||
if (!Player_InCsMode(play) && !(player->stateFlags1 & 0x8800000) &&
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "z_door_warp1.h"
|
||||
#include "objects/object_warp1/object_warp1.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#define FLAGS 0
|
||||
|
||||
|
@ -580,6 +581,11 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) {
|
|||
play->nextEntranceIndex = 0x10E;
|
||||
gSaveContext.nextCutsceneIndex = 0;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
|
||||
Entrance_OverrideBlueWarp();
|
||||
}
|
||||
|
||||
osSyncPrintf("\n\n\nおわりおわり");
|
||||
play->sceneLoadFlag = 0x14;
|
||||
play->fadeTransition = 7;
|
||||
|
@ -682,6 +688,10 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) {
|
|||
gSaveContext.nextCutsceneIndex = 0xFFF0;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
|
||||
Entrance_OverrideBlueWarp();
|
||||
}
|
||||
|
||||
play->sceneLoadFlag = 0x14;
|
||||
play->fadeTransition = 7;
|
||||
}
|
||||
|
@ -890,6 +900,11 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
|
|||
gSaveContext.nextCutsceneIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
|
||||
Entrance_OverrideBlueWarp();
|
||||
}
|
||||
|
||||
play->sceneLoadFlag = 0x14;
|
||||
play->fadeTransition = 3;
|
||||
gSaveContext.nextTransition = 7;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "z_en_ge1.h"
|
||||
#include "vt.h"
|
||||
#include "objects/object_ge1/object_ge1.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
|
||||
|
@ -93,6 +94,20 @@ void EnGe1_Init(Actor* thisx, PlayState* play) {
|
|||
s32 pad;
|
||||
EnGe1* this = (EnGe1*)thisx;
|
||||
|
||||
// When spawning the gate operator, also spawn an extra gate operator on the wasteland side
|
||||
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) ||
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) && (this->actor.params & 0xFF) == GE1_TYPE_GATE_OPERATOR) {
|
||||
// Spawn the extra gaurd with params matching the custom type added (0x0300 + 0x02)
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_GE1, -1358.0f, 88.0f, -3018.0f, 0, 0x95B0, 0,
|
||||
0x0300 | GE1_TYPE_EXTRA_GATE_OPERATOR);
|
||||
}
|
||||
|
||||
// Convert the "extra" gate operator into a normal one so it matches the same params
|
||||
if ((this->actor.params & 0xFF) == GE1_TYPE_EXTRA_GATE_OPERATOR) {
|
||||
this->actor.params &= ~0xFF;
|
||||
this->actor.params |= GE1_TYPE_GATE_OPERATOR;
|
||||
}
|
||||
|
||||
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &gGerudoWhiteSkel, &gGerudoWhiteIdleAnim, this->jointTable,
|
||||
this->morphTable, GE1_LIMB_MAX);
|
||||
|
@ -169,7 +184,12 @@ void EnGe1_Init(Actor* thisx, PlayState* play) {
|
|||
this->hairstyle = GE1_HAIR_STRAIGHT;
|
||||
|
||||
if (EnGe1_CheckCarpentersFreed()) {
|
||||
this->actionFunc = EnGe1_CheckForCard_GTGGuard;
|
||||
// If the gtg gate is permanently open, don't let the gaurd charge to open it again
|
||||
if (gSaveContext.n64ddFlag && gSaveContext.sceneFlags[93].swch & 0x00000004) {
|
||||
this->actionFunc = EnGe1_SetNormalText;
|
||||
} else {
|
||||
this->actionFunc = EnGe1_CheckForCard_GTGGuard;
|
||||
}
|
||||
} else {
|
||||
this->actionFunc = EnGe1_WatchForPlayerFrontOnly;
|
||||
}
|
||||
|
@ -247,6 +267,10 @@ void EnGe1_KickPlayer(EnGe1* this, PlayState* play) {
|
|||
play->nextEntranceIndex = 0x3B4;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Entrance_OverrideGeurdoGuardCapture();
|
||||
}
|
||||
|
||||
play->fadeTransition = 0x26;
|
||||
play->sceneLoadFlag = 0x14;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ typedef void (*EnGe1ActionFunc)(struct EnGe1*, PlayState*);
|
|||
typedef enum {
|
||||
/* 0x00 */ GE1_TYPE_GATE_GUARD,
|
||||
/* 0x01 */ GE1_TYPE_GATE_OPERATOR,
|
||||
/* 0x02 */ GE1_TYPE_EXTRA_GATE_OPERATOR, // Custom guard type for entrance randomizer to open the gate
|
||||
/* 0x04 */ GE1_TYPE_NORMAL = 4,
|
||||
/* 0x05 */ GE1_TYPE_VALLEY_FLOOR,
|
||||
/* 0x45 */ GE1_TYPE_HORSEBACK_ARCHERY = 0x45,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "z_en_ge2.h"
|
||||
#include "vt.h"
|
||||
#include "objects/object_gla/object_gla.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4)
|
||||
|
||||
|
@ -253,6 +254,10 @@ void EnGe2_CaptureClose(EnGe2* this, PlayState* play) {
|
|||
play->nextEntranceIndex = 0x3B4;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Entrance_OverrideGeurdoGuardCapture();
|
||||
}
|
||||
|
||||
play->fadeTransition = 0x26;
|
||||
play->sceneLoadFlag = 0x14;
|
||||
}
|
||||
|
@ -279,6 +284,10 @@ void EnGe2_CaptureCharge(EnGe2* this, PlayState* play) {
|
|||
play->nextEntranceIndex = 0x3B4;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Entrance_OverrideGeurdoGuardCapture();
|
||||
}
|
||||
|
||||
play->fadeTransition = 0x26;
|
||||
play->sceneLoadFlag = 0x14;
|
||||
}
|
||||
|
|
|
@ -330,6 +330,12 @@ void EnIshi_Init(Actor* thisx, PlayState* play) {
|
|||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
// 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) &&
|
||||
play->sceneNum == 0x061) { // Death Mountain Creater
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
EnIshi_SetupWait(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "vt.h"
|
||||
#include "overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.h"
|
||||
#include "objects/object_ossan/object_ossan.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_27)
|
||||
|
||||
|
@ -154,6 +155,15 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) {
|
|||
s32 pad;
|
||||
EnSyatekiMan* this = (EnSyatekiMan*)thisx;
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_INTERIOR_ENTRANCES)) {
|
||||
// If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting gallery man
|
||||
if ((LINK_IS_CHILD && Entrance_SceneAndSpawnAre(0x42, 0x00)) || //Kakariko Village -> Adult Shooting Gallery, index 003B in the entrance table
|
||||
(LINK_IS_ADULT && Entrance_SceneAndSpawnAre(0x42, 0x01))) { //Market -> Child Shooting Gallery, index 016D in the entrance table
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
osSyncPrintf("\n\n");
|
||||
// "Old man appeared!! Muhohohohohohohon"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 親父登場!!むほほほほほほほーん ☆☆☆☆☆ \n" VT_RST);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <soh/Enhancements/custom-message/CustomMessageTypes.h>
|
||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||
#include "soh/Enhancements/debugconsole.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
typedef enum {
|
||||
/* 0x00 */ KNOB_ANIM_ADULT_L,
|
||||
|
@ -4221,14 +4222,26 @@ s32 func_80839034(PlayState* play, Player* this, CollisionPoly* poly, u32 bgId)
|
|||
func_800994A0(play);
|
||||
} else {
|
||||
play->nextEntranceIndex = play->setupExitList[sp3C - 1];
|
||||
|
||||
// Main override for entrance rando and entrance skips
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
play->nextEntranceIndex = Entrance_OverrideNextIndex(play->nextEntranceIndex);
|
||||
}
|
||||
|
||||
if (play->nextEntranceIndex == 0x7FFF) {
|
||||
gSaveContext.respawnFlag = 2;
|
||||
play->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex;
|
||||
play->fadeTransition = 3;
|
||||
gSaveContext.nextTransition = 3;
|
||||
} else if (play->nextEntranceIndex >= 0x7FF9) {
|
||||
play->nextEntranceIndex =
|
||||
D_808544F8[D_80854514[play->nextEntranceIndex - 0x7FF9] + play->curSpawn];
|
||||
// handle dynamic exits
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
play->nextEntranceIndex = Entrance_OverrideDynamicExit(D_80854514[play->nextEntranceIndex - 0x7FF9] + play->curSpawn);
|
||||
} else {
|
||||
play->nextEntranceIndex =
|
||||
D_808544F8[D_80854514[play->nextEntranceIndex - 0x7FF9] + play->curSpawn];
|
||||
}
|
||||
|
||||
func_800994A0(play);
|
||||
} else {
|
||||
if (SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2) {
|
||||
|
@ -13400,6 +13413,10 @@ void func_8084F88C(Player* this, PlayState* play) {
|
|||
play->nextEntranceIndex = 0x0088;
|
||||
} else if (this->unk_84F < 0) {
|
||||
Play_TriggerRespawn(play);
|
||||
// In ER, handle DMT and other special void outs to respawn from last entrance from grotto
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_ForceRegularVoidOut();
|
||||
}
|
||||
} else {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
|
|
|
@ -458,6 +458,7 @@ void FileChoose_UpdateRandomizer() {
|
|||
Randomizer_LoadItemLocations(fileLoc, silent);
|
||||
Randomizer_LoadMerchantMessages(fileLoc);
|
||||
Randomizer_LoadMasterQuestDungeons(fileLoc);
|
||||
Randomizer_LoadEntranceOverrides(fileLoc, silent);
|
||||
fileSelectSpoilerFileLoaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -2136,6 +2137,7 @@ void FileChoose_LoadGame(GameState* thisx) {
|
|||
Randomizer_LoadRequiredTrials("");
|
||||
Randomizer_LoadMerchantMessages("");
|
||||
Randomizer_LoadMasterQuestDungeons("");
|
||||
Randomizer_LoadEntranceOverrides("", true);
|
||||
|
||||
gSaveContext.respawn[0].entranceIndex = -1;
|
||||
gSaveContext.respawnFlag = 0;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "vt.h"
|
||||
#include "alloca.h"
|
||||
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
void Select_LoadTitle(SelectContext* this) {
|
||||
this->state.running = false;
|
||||
SET_NEXT_GAMESTATE(&this->state, Title_Init, TitleContext);
|
||||
|
@ -32,6 +34,12 @@ void Select_LoadGame(SelectContext* this, s32 entranceIndex) {
|
|||
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP);
|
||||
gSaveContext.entranceIndex = entranceIndex;
|
||||
|
||||
// Check the entrance to see if the exit should be overriden to a grotto return point for entrance rando
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
// Ignore return value as we want to load into the entrance specified by the debug menu
|
||||
Grotto_OverrideSpecialEntrance(Entrance_GetOverride(entranceIndex));
|
||||
}
|
||||
|
||||
if (CVar_GetS32("gBetterDebugWarpScreen", 0)) {
|
||||
CVar_SetS32("gBetterDebugWarpScreenCurrentScene", this->currentScene);
|
||||
CVar_SetS32("gBetterDebugWarpScreenTopDisplayedScene", this->topDisplayedScene);
|
||||
|
@ -74,6 +82,14 @@ void Select_Grotto_LoadGame(SelectContext* this, s32 grottoIndex) {
|
|||
gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x4ff;
|
||||
gSaveContext.respawn[RESPAWN_MODE_RETURN].pos = this->betterGrottos[grottoIndex].pos;
|
||||
|
||||
// Check the entrance to see if the exit should be overriden to a grotto return point for entrance rando
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
// Use grotto content and parent scene num to identify the right grotto
|
||||
s16 grottoEntrance = Grotto_GetRenamedGrottoIndexFromOriginal(this->betterGrottos[grottoIndex].data, this->betterGrottos[grottoIndex].exitScene);
|
||||
// Ignore return value as we want to load into the entrance specified by the debug menu
|
||||
Grotto_OverrideSpecialEntrance(Entrance_GetOverride(grottoEntrance));
|
||||
}
|
||||
|
||||
if (CVar_GetS32("gBetterDebugWarpScreen", 0)) {
|
||||
CVar_SetS32("gBetterDebugWarpScreenCurrentScene", this->currentScene);
|
||||
CVar_SetS32("gBetterDebugWarpScreenTopDisplayedScene", this->topDisplayedScene);
|
||||
|
@ -623,34 +639,34 @@ static BetterSceneSelectEntry sBetterScenes[] = {
|
|||
};
|
||||
|
||||
static BetterSceneSelectGrottoData sBetterGrottos[] = {
|
||||
{ 0x003F, 0x00EE, 0, 0x2C, { -504.0, 380.0, -1224.0 }},
|
||||
{ 0x003F, 0x04D6, 2, 0x14, { 922.0, 0.0, -933.0 }},
|
||||
{ 0x05B4, 0x00FC, 0, 0xFFFFFFED, { -201.0, 0.0, 1906.0 }},
|
||||
{ 0x003F, 0x00CD, 0, 0x00, { -1428.0, 0.0, 790.0 }},
|
||||
{ 0x003F, 0x0189, 0, 0x03, { -4026.0, -700.0, 13858.0 }},
|
||||
{ 0x003F, 0x0189, 0, 0x22, { -259.0, -500.0, 12356.0 }},
|
||||
{ 0x003F, 0x034D, 0, 0x28, { 861.0, 80.0, -253.0 }},
|
||||
{ 0x05A0, 0x034D, 0, 0xFFFFFFE7, { -400.0, 0.0, 408.0 }},
|
||||
{ 0x003F, 0x01B9, 0, 0x57, { -389.0, 1386.0, -1202.0 }},
|
||||
{ 0x003F, 0x0147, 1, 0x7A, { 50.0, 1233.0, 1776.0 }},
|
||||
{ 0x003F, 0x019D, 0, 0x29, { 369.0, 570.0, 128.0 }},
|
||||
{ 0x059C, 0x0189, 0, 0xFFFFFFE6, { -5002.0, -700.0, 13823.0 }},
|
||||
{ 0x05A4, 0x0246, 1, 0xFFFFFFF9, { -1703.0, 722.0, -481.0 }},
|
||||
{ 0x05A4, 0x014D, 3, 0xFFFFFFFB, { 1091.0, 580.0, -1192.0 }},
|
||||
{ 0x05A4, 0x05D4, 0, 0xFFFFFFFC, { 1798.0, 0.0, 1498.0 }},
|
||||
{ 0x05A4, 0x021D, 0, 0xFFFFFFEF, { -3044.0, -1033.0, 6070.0 }},
|
||||
{ 0x05B0, 0x01A9, 8, 0xFFFFFFF5, { 677.0, 0.0, -2515.0 }},
|
||||
{ 0x05BC, 0x00EA, 0, 0xFFFFFFEB, { -1632.0, 100.0, -123.0 }},
|
||||
{ 0x05BC, 0x0215, 0, 0xFFFFFFEE, { 317.0, 480.0, -2303.0 }},
|
||||
{ 0x05BC, 0x03D0, 0, 0xFFFFFFF0, { -1321.0, 15.0, -968.0 }},
|
||||
{ 0x05BC, 0x01F1, 0, 0xFFFFFFFD, { 71.0, -32.0, -1303.0 }},
|
||||
{ 0x05C4, 0x04D6, 6, 0xFFFFFFF3, { 75.0, -20.0, -1596.0 }},
|
||||
{ 0x0598, 0x017D, 0, 0xFFFFFFE5, { 2059.0, 20.0, -174.0 }},
|
||||
{ 0x05B8, 0x023D, 0, 0xFFFFFFF6, { 986.0, 1571.0, 837.0 }},
|
||||
{ 0x05A8, 0x018D, 0, 0xFFFFFFE4, { -7873.0, -300.0, 6916.0 }},
|
||||
{ 0x05FC, 0x01B9, 0, 0xFFFFFFF8, { -678.0, 1946.0, -284.0 }},
|
||||
{ 0x05AC, 0x0117, 0, 0xFFFFFFF2, { 271.0, -555.0, 1465.0 }},
|
||||
{ 0x05C0, 0x00CD, 0, 0xFFFFFFE1, { -4945.0, -300.0, 2841.0 }},
|
||||
{ 0x003F, 0x00EE, 0, 0x2C, 0x55, { -504.0, 380.0, -1224.0 }}, // Kokiri Forest -> KF Storms Grotto
|
||||
{ 0x003F, 0x04D6, 2, 0x14, 0x5B, { 922.0, 0.0, -933.0 }}, // Lost Woods -> LW Near Shortcuts Grotto
|
||||
{ 0x05B4, 0x00FC, 0, 0xED, 0x56, { -201.0, 0.0, 1906.0 }}, // SFM Entryway -> SFM Wolfos Grotto
|
||||
{ 0x003F, 0x00CD, 0, 0x00, 0x51, { -1428.0, 0.0, 790.0 }}, // Hyrule Field -> HF Near Market Grotto
|
||||
{ 0x003F, 0x0189, 0, 0x03, 0x51, { -4026.0, -700.0, 13858.0 }}, // Hyrule Field -> HF Open Grotto
|
||||
{ 0x003F, 0x0189, 0, 0x22, 0x51, { -259.0, -500.0, 12356.0 }}, // Hyrule Field -> HF Southeast Grotto
|
||||
{ 0x003F, 0x034D, 0, 0x28, 0x52, { 861.0, 80.0, -253.0 }}, // Kak Backyard -> Kak Open Grotto
|
||||
{ 0x05A0, 0x034D, 0, 0xE7, 0x52, { -400.0, 0.0, 408.0 }}, // Kakariko Village -> Kak Redead Grotto
|
||||
{ 0x003F, 0x01B9, 0, 0x57, 0x60, { -389.0, 1386.0, -1202.0 }}, // Death Mountain -> DMT Storms Grotto
|
||||
{ 0x003F, 0x0147, 1, 0x7A, 0x61, { 50.0, 1233.0, 1776.0 }}, // DMC Upper Nearby -> DMC Upper Grotto
|
||||
{ 0x003F, 0x019D, 0, 0x29, 0x54, { 369.0, 570.0, 128.0 }}, // Zora River -> ZR Open Grotto
|
||||
{ 0x059C, 0x0189, 0, 0xE6, 0x51, { -5002.0, -700.0, 13823.0 }}, // Hyrule Field -> HF Inside Fence Grotto
|
||||
{ 0x05A4, 0x0246, 1, 0xF9, 0x61, { -1703.0, 722.0, -481.0 }}, // DMC Lower Nearby -> DMC Hammer Grotto
|
||||
{ 0x05A4, 0x014D, 3, 0xFB, 0x62, { 1091.0, 580.0, -1192.0 }}, // GC Grotto Platform -> GC Grotto
|
||||
{ 0x05A4, 0x05D4, 0, 0xFC, 0x63, { 1798.0, 0.0, 1498.0 }}, // Lon Lon Ranch -> LLR Grotto
|
||||
{ 0x05A4, 0x021D, 0, 0xEF, 0x57, { -3044.0, -1033.0, 6070.0 }}, // Lake Hylia -> LH Grotto
|
||||
{ 0x05B0, 0x01A9, 8, 0xF5, 0x5B, { 677.0, 0.0, -2515.0 }}, // LW Beyond Mido -> LW Scrubs Grotto
|
||||
{ 0x05BC, 0x00EA, 0, 0xEB, 0x54, { -1632.0, 100.0, -123.0 }}, // Zora River -> ZR Storms Grotto
|
||||
{ 0x05BC, 0x0215, 0, 0xEE, 0x56, { 317.0, 480.0, -2303.0 }}, // Sacred Forest Meadow -> SFM Storms Grotto
|
||||
{ 0x05BC, 0x03D0, 0, 0xF0, 0x5A, { -1321.0, 15.0, -968.0 }}, // GV Fortress Side -> GV Storms Grotto
|
||||
{ 0x05BC, 0x01F1, 0, 0xFD, 0x5C, { 71.0, -32.0, -1303.0 }}, // Desert Colossus -> Colossus Grotto
|
||||
{ 0x05C4, 0x04D6, 6, 0xF3, 0x5B, { 75.0, -20.0, -1596.0 }}, // LW Beyond Mido -> Deku Theater
|
||||
{ 0x0598, 0x017D, 0, 0xE5, 0x51, { 2059.0, 20.0, -174.0 }}, // Hyrule Field -> HF Near Kak Grotto
|
||||
{ 0x05B8, 0x023D, 0, 0xF6, 0x5F, { 986.0, 1571.0, 837.0 }}, // Hyrule Castle Grounds -> HC Storms Grotto
|
||||
{ 0x05A8, 0x018D, 0, 0xE4, 0x51, { -7873.0, -300.0, 6916.0 }}, // Hyrule Field -> HF Cow Grotto
|
||||
{ 0x05FC, 0x01B9, 0, 0xF8, 0x60, { -678.0, 1946.0, -284.0 }}, // Death Mountain Summit -> DMT Cow Grotto
|
||||
{ 0x05AC, 0x0117, 0, 0xF2, 0x5A, { 271.0, -555.0, 1465.0 }}, // GV Grotto Ledge -> GV Octorok Grotto
|
||||
{ 0x05C0, 0x00CD, 0, 0xE1, 0x51, { -4945.0, -300.0, 2841.0 }}, // Hyrule Field -> HF Tektite Grotto
|
||||
};
|
||||
|
||||
void Select_UpdateMenu(SelectContext* this) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "vt.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
static void* sEquipmentFRATexs[] = {
|
||||
gPauseEquipment00FRATex, gPauseEquipment01Tex, gPauseEquipment02Tex, gPauseEquipment03Tex, gPauseEquipment04Tex,
|
||||
|
@ -4213,6 +4214,10 @@ void KaleidoScope_Update(PlayState* play)
|
|||
if (pauseCtx->promptChoice == 0) {
|
||||
Play_TriggerRespawn(play);
|
||||
gSaveContext.respawnFlag = -2;
|
||||
// In ER, handle death warp to last entrance from grottos
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_ForceGrottoReturn();
|
||||
}
|
||||
gSaveContext.nextTransition = 2;
|
||||
gSaveContext.health = 0x30;
|
||||
Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue