summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris <f1ana@users.noreply.github.com>2026-04-06 21:09:07 -0400
committerGitHub <noreply@github.com>2026-04-07 01:09:07 +0000
commit695c05d339d555aa2c933bc0a481f2baa03481b4 (patch)
tree8b40c79830ba92ca291686c81945b99c05764b99
parent77f2883510965b61e563bd1432d193decf36c14a (diff)
Fix cooldown behavior for crystal and light switches, water gate (#6461)
-rw-r--r--soh/soh/Enhancements/TimeSavers/SkipTimerDelay.cpp42
-rw-r--r--soh/soh/Enhancements/TimeSavers/SkipWaterGateDelay.cpp18
-rw-r--r--soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h8
-rw-r--r--soh/soh/Enhancements/timesaver_hook_handlers.cpp20
-rw-r--r--soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c3
-rw-r--r--soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c5
6 files changed, 49 insertions, 47 deletions
diff --git a/soh/soh/Enhancements/TimeSavers/SkipTimerDelay.cpp b/soh/soh/Enhancements/TimeSavers/SkipTimerDelay.cpp
deleted file mode 100644
index 733d420fd..000000000
--- a/soh/soh/Enhancements/TimeSavers/SkipTimerDelay.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "soh/Enhancements/game-interactor/GameInteractor.h"
-#include "soh/ShipInit.hpp"
-
-extern "C" {
-#include "src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h"
-#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
-#include "src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h"
-extern PlayState* gPlayState;
-}
-
-#define SKIP_MISC_INTERACTIONS_NAME CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions")
-#define SKIP_MISC_INTERACTIONS_VALUE CVarGetInteger(SKIP_MISC_INTERACTIONS_NAME, IS_RANDO)
-
-static void RegisterSkipTimerDelay() {
- // Skip Water Temple gate delay
- COND_ID_HOOK(OnActorUpdate, ACTOR_BG_SPOT06_OBJECTS, SKIP_MISC_INTERACTIONS_VALUE, [](void* actor) {
- auto spot06 = static_cast<BgSpot06Objects*>(actor);
- if (spot06->dyna.actor.params == 0) {
- spot06->timer = 0;
- }
- });
-
- // Skip Spirit Sun on Floor activation delay
- COND_ID_HOOK(OnActorUpdate, ACTOR_BG_JYA_BOMBCHUIWA, SKIP_MISC_INTERACTIONS_VALUE, [](void* actor) {
- auto jya = static_cast<BgJyaBombchuiwa*>(actor);
- if (!(jya->drawFlags & 4) && jya->timer > 0 && jya->timer < 9) {
- jya->timer = 9;
- }
- });
-
- // Skip Spirit Sun on Floor & Sun on Block activation delay
- COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_LIGHTSWITCH, SKIP_MISC_INTERACTIONS_VALUE, [](void* actor) {
- if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE &&
- (gPlayState->roomCtx.curRoom.num == 4 || gPlayState->roomCtx.curRoom.num == 8)) {
- auto sun = static_cast<ObjLightswitch*>(actor);
- sun->toggleDelay = 0;
- }
- });
-}
-
-static RegisterShipInitFunc initFunc_SkipTimerDelay(RegisterSkipTimerDelay,
- { SKIP_MISC_INTERACTIONS_NAME, "IS_RANDO" });
diff --git a/soh/soh/Enhancements/TimeSavers/SkipWaterGateDelay.cpp b/soh/soh/Enhancements/TimeSavers/SkipWaterGateDelay.cpp
new file mode 100644
index 000000000..22e7ed305
--- /dev/null
+++ b/soh/soh/Enhancements/TimeSavers/SkipWaterGateDelay.cpp
@@ -0,0 +1,18 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
+extern SaveContext gSaveContext;
+}
+
+static void RegisterSpot06GateSkip() {
+ COND_VB_SHOULD(VB_BG_SPOT06_OBJECTS_GATE_SKIP,
+ CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO), {
+ BgSpot06Objects* actor = va_arg(args, BgSpot06Objects*);
+ actor->timer = 0;
+ *should = false;
+ });
+}
+
+static RegisterShipInitFunc initFunc(RegisterSpot06GateSkip, { CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint") }); \ No newline at end of file
diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
index ae9ea8958..0c2c6230a 100644
--- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
+++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
@@ -205,6 +205,14 @@ typedef enum {
// #### `result`
// ```c
+ // this->timer > 0 && this->timer <= 100
+ // ```
+ // #### `args`
+ // - `*BgSpot06Objects`
+ VB_BG_SPOT06_OBJECTS_GATE_SKIP,
+
+ // #### `result`
+ // ```c
// gSaveContext.bgsFlag
// ```
// #### `args`
diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp
index 39af5da45..4c50a8632 100644
--- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp
+++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp
@@ -24,11 +24,14 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Jj/z_en_jj.h"
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
+#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
#include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h"
+#include "src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h"
+#include "src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h"
#include <overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h>
#include <overlays/actors/ovl_En_Ik/z_en_ik.h>
#include <objects/object_gnd/object_gnd.h>
@@ -328,6 +331,15 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
RateLimitedSuccessChime();
break;
}
+ case ACTOR_BG_JYA_BOMBCHUIWA: {
+ BgJyaBombchuiwa* bombchuiwa = (BgJyaBombchuiwa*)actor;
+ if (!(bombchuiwa->drawFlags & 4) && bombchuiwa->timer >= 0 && bombchuiwa->timer < 9) {
+ bombchuiwa->timer = 9;
+ }
+ *should = false;
+ RateLimitedSuccessChime();
+ break;
+ }
case ACTOR_EN_GO2: {
EnGo2* biggoron = (EnGo2*)actor;
biggoron->isAwake = true;
@@ -376,8 +388,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
RateLimitedSuccessChime();
break;
}
+ case ACTOR_OBJ_LIGHTSWITCH: {
+ ObjLightswitch* lightswitch = (ObjLightswitch*)actor;
+ lightswitch->toggleDelay = 0;
+ *should = false;
+ RateLimitedSuccessChime();
+ break;
+ }
case ACTOR_BG_ICE_SHUTTER:
- case ACTOR_OBJ_LIGHTSWITCH:
case ACTOR_OBJ_SYOKUDAI:
case ACTOR_OBJ_TIMEBLOCK:
case ACTOR_EN_PO_SISTERS:
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 20425cdd0..ccb189ee7 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
@@ -7,6 +7,7 @@
#include "z_bg_spot06_objects.h"
#include "objects/object_spot06_objects/object_spot06_objects.h"
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_HOOKSHOT_PULLS_ACTOR
@@ -266,7 +267,7 @@ void BgSpot06Objects_GateWaitForSwitch(BgSpot06Objects* this, PlayState* play) {
* This is where the gate waits a few frames before rising after the switch is set.
*/
void BgSpot06Objects_GateWaitToOpen(BgSpot06Objects* this, PlayState* play) {
- if (this->timer != 0) {
+ if (GameInteractor_Should(VB_BG_SPOT06_OBJECTS_GATE_SKIP, this->timer != 0, this)) {
this->timer--;
}
diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
index 622ac7bbe..26c1d5a40 100644
--- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
+++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
@@ -256,9 +256,8 @@ void ObjSwitch_SetOn(ObjSwitch* this, PlayState* play) {
} else {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
}
+ this->cooldownOn = true;
}
-
- this->cooldownOn = true;
}
}
@@ -271,8 +270,8 @@ void ObjSwitch_SetOff(ObjSwitch* this, PlayState* play) {
if ((this->dyna.actor.params >> 4 & 7) == 1) {
if (GameInteractor_Should(VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
+ this->cooldownOn = true;
}
- this->cooldownOn = true;
}
}
}