summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjevangelia <263709373+djevangelia@users.noreply.github.com>2026-07-11 17:18:55 +0200
committerGitHub <noreply@github.com>2026-07-11 15:18:55 +0000
commit847e3cd3238a34f3e4fc95b5871a2c79aafaabee (patch)
treee1d22a574e5d4215213fa1718d164d5d809b1e6d
parentbd7191875a62063c67c2eb51700f6d5d09d12ac9 (diff)
Maintenance, edits and addition to Lake Hylia water control (#6884)
-rw-r--r--soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp82
-rw-r--r--soh/src/code/z_map_exp.c10
-rw-r--r--soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c55
3 files changed, 76 insertions, 71 deletions
diff --git a/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp b/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp
index 8b4cb2632..69ffbf134 100644
--- a/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp
+++ b/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp
@@ -2,6 +2,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
+#include <libultraship/bridge/resourcebridge.h>
extern "C" {
extern PlayState* gPlayState;
@@ -9,68 +10,50 @@ extern PlayState* gPlayState;
#include "functions.h"
#include "variables.h"
#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
+#include "textures/map_grand_static/map_grand_static.h"
-extern s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId);
-extern void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects*, PlayState*);
-extern void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects*, PlayState*);
extern void BgSpot06Objects_LockFloat(BgSpot06Objects*, PlayState*);
+extern void BgSpot06Objects_WaterControl_Lower(BgSpot06Objects*, PlayState*);
+extern void BgSpot06Objects_WaterControl_Raise(BgSpot06Objects*, PlayState*);
}
#define WATER_LEVEL_RAISED (-1313)
-// Main water control switch
-static Actor* sSwitchMain = nullptr;
-// Alternate control switch on fishing island
-static Actor* sSwitchIsland = nullptr;
-static Actor* sLock = nullptr;
+static Actor* sSwitchMain = nullptr; // Main water control switch
+static Actor* sSwitchIsland = nullptr; // Alternate control switch on fishing island
+static Actor* sLock = nullptr; // Water Temple hookshot lock
static u8 sPrevFlagState = 0;
static void SpawnSwitches(PlayState* play) {
- // Object containing floor switch data (and ice block data)
- Object_Spawn(&play->objectCtx, OBJECT_GAMEPLAY_DANGEON_KEEP);
-
- bool waterTempleCleared = Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
- bool waterLowered = !Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
- // Persist the water level across scene reloads.
- if (waterTempleCleared && waterLowered) {
- Flags_SetSwitch(play, 0x3E);
- }
-
s16 switchParams;
- if (waterTempleCleared) {
- // Toggle-able floor switch
- switchParams = 0x3E10;
+
+ // If Water Temple cleared, spawn normal switches and sync current water level with switch status.
+ // Else, spawn frozen rusty switch that is glitched and can't be pressed + spawn Navi check spots
+ if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
+ // This eventchkinf flag is set and unset on switch press - the permanent flag of water level
+ if (!Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER)) {
+ Flags_SetSwitch(play, 0x3E); // Temp switch flag set = lowered water level
+ }
+ switchParams = 0x3E10; // Toggle-able floor switch
} else {
- // Frozen rusty switch, same flag as above. It's glitched and can't be pressed
switchParams = 0x3E81;
+ Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0,
+ 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF)); // Navi check main
+ Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, 1320.0f, -1218.7f, 4025.0f, 0, 0, 0,
+ 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF)); // Navi check fishing
}
+ // Spawn floor switch and sign on main island and fishing pond island
sSwitchMain =
- // Spawn a floor switch
Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_SWITCH, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, switchParams);
- // Spawn a sign
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, -970.0f, -1242.0f, 6954.0f, 0, 0, 0,
0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF));
- if (!waterTempleCleared) {
- // Spawn a Navi check spot when Water Temple isn't cleared
- Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0,
- 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF));
- }
-
- // Second switch on the fishing pond island. Up against the wall
sSwitchIsland =
- // Spawn a floor switch
Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_SWITCH, 1320.0f, -1218.7f, 4025.0f, 0, 0, 0, switchParams);
- // Spawn a sign
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, 1320.0f, -1217.7f, 3951.0f, 0, -0x4000, 0,
0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF));
- if (!waterTempleCleared) {
- // Spawn a Navi check spot when Water Temple isn't cleared
- Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, 1320.0f, -1218.7f, 4025.0f, 0, 0, 0,
- 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF));
- }
- sPrevFlagState = Flags_GetSwitch(play, 0x3E) != 0;
+ sPrevFlagState = (Flags_GetSwitch(play, 0x3E) != 0); // For checking if switch has been pressed
}
void RegisterLakeHyliaWaterControl() {
@@ -112,13 +95,22 @@ void RegisterLakeHyliaWaterControl() {
}
}
- u8 flagState = Flags_GetSwitch(gPlayState, 0x3E) != 0;
- if (sPrevFlagState == flagState) {
- return;
+ // Check if switch has been pressed
+ u8 flagState = (Flags_GetSwitch(gPlayState, 0x3E) != 0);
+ if (sPrevFlagState != flagState) {
+ sPrevFlagState = flagState;
+ if (flagState) {
+ waterPlane->actionFunc = BgSpot06Objects_WaterControl_Lower;
+ Flags_UnsetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
+ gPlayState->interfaceCtx.mapSegment[0] = (char*)ResourceGetDataByName(gDrainedLakeHyliaMinimapTex);
+ gPlayState->interfaceCtx.mapSegmentName[0] = (char*)gDrainedLakeHyliaMinimapTex;
+ } else {
+ waterPlane->actionFunc = BgSpot06Objects_WaterControl_Raise;
+ Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
+ gPlayState->interfaceCtx.mapSegment[0] = (char*)ResourceGetDataByName(gLakeHyliaMinimapTex);
+ gPlayState->interfaceCtx.mapSegmentName[0] = (char*)gLakeHyliaMinimapTex;
+ }
}
- sPrevFlagState = flagState;
- waterPlane->actionFunc =
- flagState ? BgSpot06Objects_WaterPlaneCutsceneLower : BgSpot06Objects_WaterPlaneCutsceneRise;
});
// Synchronize pressed states of both main and island switches
diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c
index 886036352..681e20f05 100644
--- a/soh/src/code/z_map_exp.c
+++ b/soh/src/code/z_map_exp.c
@@ -392,22 +392,22 @@ void Map_InitData(PlayState* play, s16 room) {
extendedMapIndex = mapIndex;
if (play->sceneNum == SCENE_GRAVEYARD) {
if (CHECK_QUEST_ITEM(QUEST_SONG_NOCTURNE)) {
- extendedMapIndex = 0x14;
+ extendedMapIndex = 0x14; // Entrance to Shadow Temple visible
}
} else if (play->sceneNum == SCENE_LAKE_HYLIA) {
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
- (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)))) {
- extendedMapIndex = 0x15;
+ (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER)))) {
+ extendedMapIndex = 0x15; // Lowered water level
}
} else if (play->sceneNum == SCENE_GERUDO_VALLEY) {
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) && !GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {
- extendedMapIndex = 0x16;
+ extendedMapIndex = 0x16; // Bridge not built
}
} else if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
if ((!IS_RANDO && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
(IS_RANDO && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
- extendedMapIndex = 0x17;
+ extendedMapIndex = 0x17; // Horseback archery visible
}
}
osSyncPrintf(VT_FGCOL(BLUE));
diff --git a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
index 5e7523a81..1078a278d 100644
--- a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
+++ b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
@@ -206,8 +206,11 @@ void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) {
break;
}
- // Due to Ships resource caching, the water box collisions for the river have to be manually reset
+ // Due to Ships resource caching, the water boxes have to be manually reset
+ play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_RAISED;
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
+ play->colCtx.colHeader->waterBoxes[LHWB_MAIN_1].ySurface = WATER_LEVEL_RAISED;
+ play->colCtx.colHeader->waterBoxes[LHWB_MAIN_2].ySurface = WATER_LEVEL_RAISED;
}
/**
@@ -509,17 +512,8 @@ void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects* this, PlayState* pl
if (this->lakeHyliaWaterLevel >= 0.0001f) {
this->dyna.actor.world.pos.y = WATER_LEVEL_RAISED;
this->actionFunc = BgSpot06Objects_DoNothing;
-
- // On rando, this is used with the water control system switch to finalize raising the water
- if (IS_RANDO) {
- this->lakeHyliaWaterLevel = 0;
- play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_RAISED;
- play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
- Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); // Set the "raise lake hylia water" flag
- play->roomCtx.unk_74[0] = 0; // Apply the moving under water texture to lake hylia ground
- }
} else {
- Math_SmoothStepToF(&this->lakeHyliaWaterLevel, 1.0f, 0.1f, IS_RANDO ? 10.0f : 1.0f, 0.001f);
+ Math_SmoothStepToF(&this->lakeHyliaWaterLevel, 1.0f, 0.1f, 1.0f, 0.001f);
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_LOWERED;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_1].ySurface = this->dyna.actor.world.pos.y;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_2].ySurface = this->dyna.actor.world.pos.y;
@@ -529,32 +523,51 @@ void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects* this, PlayState* pl
}
/**
- * Custom action func to lower the Laker Hylia water plane from a switch.
+ * SoH: Randomizer, custom action function to raise the Laker Hylia water plane from a switch.
+ */
+void BgSpot06Objects_WaterControl_Raise(BgSpot06Objects* this, PlayState* play) {
+ this->dyna.actor.world.pos.y = this->lakeHyliaWaterLevel + WATER_LEVEL_RAISED;
+
+ if (this->lakeHyliaWaterLevel >= 0.0001f) {
+ this->dyna.actor.world.pos.y = WATER_LEVEL_RAISED;
+ this->actionFunc = BgSpot06Objects_DoNothing;
+ this->lakeHyliaWaterLevel = 0;
+ play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_RAISED;
+ play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
+ play->roomCtx.unk_74[0] = 0; // Apply the moving under water texture to Lake Hylia ground
+ } else {
+ Math_SmoothStepToF(&this->lakeHyliaWaterLevel, 1.0f, 0.1f, 10.0f, 0.001f);
+ play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_LOWERED;
+ play->colCtx.colHeader->waterBoxes[LHWB_MAIN_1].ySurface = this->dyna.actor.world.pos.y;
+ play->colCtx.colHeader->waterBoxes[LHWB_MAIN_2].ySurface = this->dyna.actor.world.pos.y;
+ Actor_PlaySfx_FlaggedCentered2(&this->dyna.actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
+ }
+}
+
+/**
+ * SoH: Randomizer, custom action function to lower the Laker Hylia water plane from a switch.
*/
-void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects* this, PlayState* play) {
+void BgSpot06Objects_WaterControl_Lower(BgSpot06Objects* this, PlayState* play) {
f32 yPos = this->dyna.actor.world.pos.y = this->lakeHyliaWaterLevel + WATER_LEVEL_RAISED;
+ play->roomCtx.unk_74[0] = 87; // Remove the moving under water texture from Lake Hylia ground
- // A slightly smaller number thatn -680 (which is when textures change)
+ // A slightly smaller number than -680.0f (which is when surface textures change)
// Then we change the position since the "low water" texture has a different height
if (this->lakeHyliaWaterLevel <= -679.9f) {
this->dyna.actor.world.pos.y = (this->lakeHyliaWaterLevel + 680.0f) + WATER_LEVEL_RAISED;
}
-
- Flags_UnsetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); // Unset the "raised lake hylia water" flag
- play->roomCtx.unk_74[0] = 87; // Remove the moving under water texture from lake hylia ground
-
if (this->lakeHyliaWaterLevel <= -681.0f) {
this->lakeHyliaWaterLevel = -681.0f;
this->dyna.actor.world.pos.y = WATER_LEVEL_RAISED;
this->actionFunc = BgSpot06Objects_DoNothing;
} else {
- // Go slightly beyond -681 so the smoothing doesn't slow down too much (matches the reverse of water rise func)
+ // Go slightly beyond -681.0f so the smoothing doesn't slow down too much (matches the reverse of water rise
+ // func)
Math_SmoothStepToF(&this->lakeHyliaWaterLevel, -682.0f, 0.1f, 10.0f, 0.01f);
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_LOWERED;
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z - 50;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_1].ySurface = yPos;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_2].ySurface = yPos;
+ Actor_PlaySfx_FlaggedCentered2(&this->dyna.actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
}
-
- Actor_PlaySfx_FlaggedCentered2(&this->dyna.actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
}