From fda198db761d394adeb3215c1c04b1eef4aeffd8 Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Tue, 17 Jan 2023 15:01:45 -0500 Subject: [PATCH] Fix: Reset waterbox collisions in Lake Hylia and Morphas room (#2346) --- .../actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c | 9 +++++++++ soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 6 ++++++ 2 files changed, 15 insertions(+) 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 c9e37943e..7bc357263 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 @@ -30,6 +30,8 @@ typedef enum { #define WATER_LEVEL_LOWERED (WATER_LEVEL_RAISED - 680) #define WATER_LEVEL_RIVER_LOWERED (WATER_LEVEL_RIVER_RAISED - 80) +#define WATER_LEVEL_RIVER_LOWER_Z 2203 + void BgSpot06Objects_Init(Actor* thisx, PlayState* play); void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play); void BgSpot06Objects_Update(Actor* thisx, PlayState* play); @@ -210,6 +212,9 @@ 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 + play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z; + if (gSaveContext.n64ddFlag && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { // For randomizer when leaving lake hylia while the water level is lowered, // reset the "raise lake hylia water" flag back to on if the water temple is cleared @@ -591,6 +596,8 @@ void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects* this, PlayState* pl // On rando, this is used with the water control system switch to finalize raising the water if (gSaveContext.n64ddFlag) { 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 } @@ -620,12 +627,14 @@ void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects* this, PlayState* p 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) Math_SmoothStepToF(&this->lakeHyliaWaterLevel, -682.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_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; } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 6ebe523dd..cf9239862 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -18,6 +18,8 @@ #define MO_WATER_LEVEL(play) play->colCtx.colHeader->waterBoxes[0].ySurface +#define MO_STARTING_WATER_LEVEL (-60) + #define HAS_LINK(tent) \ ((tent != NULL) && \ ((tent->work[MO_TENT_ACTION_STATE] == MO_TENT_GRAB) || (tent->work[MO_TENT_ACTION_STATE] == MO_TENT_SHAKE))) @@ -338,6 +340,10 @@ void BossMo_Init(Actor* thisx, PlayState* play2) { BossMo* this = (BossMo*)thisx; u16 i; + // Due to Ships resource caching, the water level for Morpha needs to be reset + // to ensure subsequent re-fights in the same running instance start with the correct level + MO_WATER_LEVEL(play) = MO_STARTING_WATER_LEVEL; + Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); if (this->actor.params != BOSSMO_TENTACLE) {