diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 3eb7916a7..0c11e3c93 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1430,6 +1430,15 @@ typedef enum { // - None VB_PLAY_FIRE_ARROW_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnHeishi2` + // - `bool` (clearCamera - true if the code clears a sub-camera, false otherwise) + VB_PLAY_GATE_OPENING_OR_CLOSING_CS, + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 0a9a77e40..13c14b0a6 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -13,6 +13,7 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Owl/z_en_owl.h" #include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" +#include "src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h" #include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" #include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h" #include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h" @@ -765,6 +766,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li break; } + case VB_PLAY_GATE_OPENING_OR_CLOSING_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + EnHeishi2* enHeishi2 = va_arg(args, EnHeishi2*); + enHeishi2->unk_2F2[0] = 0; + + // The second argument determines whether the vanilla code should be run anyway. It + // should be set to `true` ONLY IF said code calls `Play_ClearCamera`, false otherwise. + bool clearCamera = (bool)va_arg(args, int); + *should = clearCamera && enHeishi2->cameraId != MAIN_CAM; + } + break; + } case VB_PLAY_RAINBOW_BRIDGE_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { *should = false; diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index 61a10b056..192d749d4 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -314,19 +314,21 @@ void func_80A5372C(EnHeishi2* this, PlayState* play) { f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim); Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f); - this->unk_2F2[0] = 200; - this->cameraId = Play_CreateSubCamera(play); - Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); - this->unk_280.x = 947.0f; - this->unk_280.y = 1195.0f; - this->unk_280.z = 2682.0f; + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { + this->unk_2F2[0] = 200; + this->cameraId = Play_CreateSubCamera(play); + Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); + Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); + this->unk_280.x = 947.0f; + this->unk_280.y = 1195.0f; + this->unk_280.z = 2682.0f; - this->unk_28C.x = 1164.0f; - this->unk_28C.y = 1145.0f; - this->unk_28C.z = 3014.0f; + this->unk_28C.x = 1164.0f; + this->unk_28C.y = 1145.0f; + this->unk_28C.z = 3014.0f; - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + } this->actionFunc = func_80A53850; } @@ -334,11 +336,15 @@ void func_80A53850(EnHeishi2* this, PlayState* play) { BgSpot15Saku* gate; SkelAnime_Update(&this->skelAnime); - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { + Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + } gate = (BgSpot15Saku*)this->gate; if ((this->unk_2F2[0] == 0) || (gate->unk_168 == 0)) { - Play_ClearCamera(play, this->cameraId); - Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) { + Play_ClearCamera(play, this->cameraId); + Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + } Message_CloseTextbox(play); this->unk_30C = 1; Player_SetCsActionWithHaltedActors(play, NULL, 7); @@ -479,23 +485,25 @@ void func_80A53DF8(EnHeishi2* this, PlayState* play) { f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim); Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f); - this->unk_2F2[0] = 200; - this->cameraId = Play_CreateSubCamera(play); - Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); - this->unk_2BC.x = -71.0f; - this->unk_280.x = -71.0f; - this->unk_2BC.y = 571.0f; - this->unk_280.y = 571.0f; - this->unk_2BC.z = -1487.0f; - this->unk_280.z = -1487.0f; - this->unk_298.x = 181.0f; - this->unk_28C.x = 181.0f; - this->unk_298.y = 417.0f; - this->unk_28C.y = 417.0f; - this->unk_298.z = -1079.0f; - this->unk_28C.z = -1079.0f; - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { + this->unk_2F2[0] = 200; + this->cameraId = Play_CreateSubCamera(play); + Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); + Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); + this->unk_2BC.x = -71.0f; + this->unk_280.x = -71.0f; + this->unk_2BC.y = 571.0f; + this->unk_280.y = 571.0f; + this->unk_2BC.z = -1487.0f; + this->unk_280.z = -1487.0f; + this->unk_298.x = 181.0f; + this->unk_28C.x = 181.0f; + this->unk_298.y = 417.0f; + this->unk_28C.y = 417.0f; + this->unk_298.z = -1079.0f; + this->unk_28C.z = -1079.0f; + Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + } this->actionFunc = func_80A53F30; } @@ -503,11 +511,15 @@ void func_80A53F30(EnHeishi2* this, PlayState* play) { BgGateShutter* gate; SkelAnime_Update(&this->skelAnime); - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { + Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + } gate = (BgGateShutter*)this->gate; if ((this->unk_2F2[0] == 0) || (gate->openingState == 0)) { - Play_ClearCamera(play, this->cameraId); - Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) { + Play_ClearCamera(play, this->cameraId); + Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + } if ((this->unk_30A != 2)) { if (this->unk_30A == 0) { this->actor.textId = 0x2015;