Skip to content

Commit

Permalink
Generalize grotto return fix (#578)
Browse files Browse the repository at this point in the history
  • Loading branch information
HylianFreddy committed Oct 22, 2022
1 parent f397baf commit b0c7c30
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 21 deletions.
3 changes: 3 additions & 0 deletions code/include/z3D/z3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

// #include "hid.h"

#define TRUE 1
#define FALSE 0

typedef struct {
/* 0x00 */ u8 buttonItems[5]; //B,Y,X,I,II
/* 0x05 */ u8 buttonSlots[4]; //Y,X,I,II
Expand Down
8 changes: 6 additions & 2 deletions code/oot.ld
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ SECTIONS
*(.patch_WarpSongEntranceOverride)
}

.patch_SetFWPlayerParams 0x4911B8 : {
*(.patch_SetFWPlayerParams)
}

.patch_SwapFaroresWind 0x49186C : {
*(.patch_SwapFaroresWind)
}
Expand Down Expand Up @@ -1376,8 +1380,8 @@ SECTIONS
*(.patch_SendDroppedBottleContents)
}

.patch_ReturnFWSetupGrottoInfo 0x496B88 : {
*(.patch_ReturnFWSetupGrottoInfo)
.patch_ReturnFW 0x496B88 : {
*(.patch_ReturnFW)
}

.patch_SetSpecialVoidOutRespawnFlag 0x496C70 : {
Expand Down
8 changes: 6 additions & 2 deletions code/oot_e.ld
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ SECTIONS
*(.patch_WarpSongEntranceOverride)
}

.patch_SetFWPlayerParams 0x4911D8 : {
*(.patch_SetFWPlayerParams)
}

.patch_SwapFaroresWind 0x49188C : {
*(.patch_SwapFaroresWind)
}
Expand Down Expand Up @@ -1376,8 +1380,8 @@ SECTIONS
*(.patch_SendDroppedBottleContents)
}

.patch_ReturnFWSetupGrottoInfo 0x496BA8 : {
*(.patch_ReturnFWSetupGrottoInfo)
.patch_ReturnFW 0x496BA8 : {
*(.patch_ReturnFW)
}

.patch_SetSpecialVoidOutRespawnFlag 0x496C90 : {
Expand Down
2 changes: 2 additions & 0 deletions code/src/actors/player.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "fairy.h"
#include "icetrap.h"
#include "arrow.h"
#include "grotto.h"

#define PlayerActor_Init_addr 0x191844
#define PlayerActor_Init ((ActorFunc)PlayerActor_Init_addr)
Expand Down Expand Up @@ -69,6 +70,7 @@ void PlayerActor_rInit(Actor* thisx, GlobalContext* globalCtx) {
gSaveContext.equips.equipment &= ~0xF0; // unequip shield
}

Grotto_SanitizeEntranceType();
// If the player has started with 0 hearts, some entrances that knock Link down will cause a Game Over.
// When respawning after the Game Over, change the entrance type to avoid softlocks.
u8 playerEntranceType = (thisx->params & 0xF00) >> 8;
Expand Down
32 changes: 25 additions & 7 deletions code/src/grotto.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include "grotto.h"
#include "savefile.h"
#include "settings.h"
#include "common.h"

// Information necessary for entering each grotto
static const GrottoLoadInfo grottoLoadTable[NUM_GROTTOS] = {
Expand Down Expand Up @@ -82,6 +81,7 @@ static s16 grottoExitList[NUM_GROTTOS] = {0};
static s16 grottoLoadList[NUM_GROTTOS] = {0};
static s8 grottoId = 0xFF;
static s8 lastEntranceType = NOT_GROTTO;
static u8 overridingNextEntrance = FALSE;

// Initialize both lists so that each index refers to itself. An index referring
// to itself means that the entrance is not shuffled. Indices will be overwritten
Expand Down Expand Up @@ -179,6 +179,7 @@ s16 Grotto_CheckSpecialEntrance(s16 nextEntranceIndex) {
lastEntranceType = NOT_GROTTO;
}

overridingNextEntrance = TRUE;
return nextEntranceIndex;
}

Expand Down Expand Up @@ -242,21 +243,38 @@ void Grotto_ForceRegularVoidOut(void) {
}
}

// If setting FW at a grotto exit, save different player params in the FW data, so
// we can remember to restore the lastEntranceType when returning to the warp point.
s32 Grotto_ChooseFWPlayerParams() {
if ((gSettingsContext.shuffleGrottoEntrances == ON || gSettingsContext.shuffleOverworldSpawns == ON || gSettingsContext.shuffleWarpSongs == ON) &&
lastEntranceType == GROTTO_RETURN) {

return 0x4FF;
}
return 0x6FF; // Normal FW params
}

// If returning to a FW point saved at a grotto exit, copy the FW data to the Grotto Return Point
// so that Sun's Song and Game Over will behave correctly
void Grotto_SetupReturnInfoOnFWReturn(void) {
if (gSettingsContext.shuffleGrottoEntrances == ON || gSettingsContext.shuffleOverworldSpawns == ON || gSettingsContext.shuffleWarpSongs == ON) {
if ((gSettingsContext.shuffleGrottoEntrances == ON || gSettingsContext.shuffleOverworldSpawns == ON || gSettingsContext.shuffleWarpSongs == ON) &&
gSaveContext.fw.playerParams == 0x4FF) {

gSaveContext.fw.playerParams = gSaveContext.respawn[RESPAWN_MODE_TOP].playerParams = 0x6FF;
gSaveContext.respawn[RESPAWN_MODE_RETURN] = gSaveContext.respawn[RESPAWN_MODE_TOP];
gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x0DFF;
lastEntranceType = GROTTO_RETURN;
} else {
lastEntranceType = NOT_GROTTO;
}
}

void Grotto_SanitizeEntranceType(void) {
// Clear entrance type when on the title screen or after being thrown out
// by the Hyrule Castle guards if the last entrance was HC Storms Grotto -> HC
// This allows OHKO playthroughs to get past the guards properly.
if (!IsInGame() || gSaveContext.entranceIndex == 0x47E) {
// If a scene transition is not overridden at all (i.e. guards throwing Link out / quitting game)
// the lastEntranceType must be cleared to avoid messing up savewarps and deathwarps.
// This does not apply to void out and other respawns, which should keep the lastEntranceType.
void Grotto_SanitizeEntranceType() {
if (!overridingNextEntrance && gSaveContext.respawnFlag == 0) {
lastEntranceType = NOT_GROTTO;
}
overridingNextEntrance = FALSE;
}
2 changes: 1 addition & 1 deletion code/src/grotto.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex);
void Grotto_SetLoadOverride(s16 originalIndex, s16 overrideIndex);
s16 Grotto_CheckSpecialEntrance(s16 nextEntranceIndex);
void Grotto_ForceGrottoReturnOnSpecialEntrance(void);
void Grotto_SanitizeEntranceType();
void Grotto_SanitizeEntranceType(void);

#endif //_GROTTO_H_
15 changes: 13 additions & 2 deletions code/src/hooks.s
Original file line number Diff line number Diff line change
Expand Up @@ -1258,8 +1258,8 @@ hook_OverrideGrottoActorEntrance:
pop {r0-r12, lr}
b 0x3F22C4

.global hook_ReturnFWSetupGrottoInfo
hook_ReturnFWSetupGrottoInfo:
.global hook_ReturnFW
hook_ReturnFW:
push {r0-r12, lr}
bl Grotto_SetupReturnInfoOnFWReturn
pop {r0-r12, lr}
Expand Down Expand Up @@ -1708,6 +1708,17 @@ hook_GanonDrawMasterSword:
strb r10,[r4,#0x0] @ delete MS effect
bx lr

.global hook_SetFWPlayerParams
hook_SetFWPlayerParams:
push {r0-r9,r11-r12,lr}
bl Grotto_ChooseFWPlayerParams
mov r10,r0
pop {r0-r9,r11-r12,lr}
bx lr

@ ----------------------------------
@ ----------------------------------

.section .loader
.global hook_into_loader
hook_into_loader:
Expand Down
2 changes: 0 additions & 2 deletions code/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ void before_GlobalContext_Update(GlobalContext* globalCtx) {

Settings_SkipSongReplays();

Grotto_SanitizeEntranceType();

Multiplayer_Run();
}

Expand Down
17 changes: 12 additions & 5 deletions code/src/patches.s
Original file line number Diff line number Diff line change
Expand Up @@ -1636,10 +1636,10 @@ SceneExitDynamicOverride_patch:
OverrideGrottoActorEntrance_patch:
b hook_OverrideGrottoActorEntrance

.section .patch_ReturnFWSetupGrottoInfo
.global ReturnFWSetupGrottoInfo_patch
ReturnFWSetupGrottoInfo_patch:
bl hook_ReturnFWSetupGrottoInfo
.section .patch_ReturnFW
.global ReturnFW_patch
ReturnFW_patch:
bl hook_ReturnFW

.section .patch_WarpSongEntranceOverride
.global WarpSongEntranceOverride_patch
Expand Down Expand Up @@ -1981,8 +1981,15 @@ CollisionATvsAC_patch:
GanonDrawMasterSword_patch:
bl hook_GanonDrawMasterSword

.section .patch_SetFWPlayerParams
.global SetFWPlayerParams_patch
SetFWPlayerParams_patch:
bl hook_SetFWPlayerParams

@ ----------------------------------
@ ----------------------------------

.section .patch_loader
.global loader_patch

loader_patch:
b hook_into_loader

0 comments on commit b0c7c30

Please sign in to comment.