diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 3b3ad4cb4..c8a0f747c 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1270,6 +1270,14 @@ typedef enum { // - None VB_PLAY_BOLERO_OF_FIRE_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnDaiku` + VB_PLAY_CARPENTER_FREE_CS, + // #### `result` // Close enough & various cutscene checks // ```c diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 5aedb90ec..a46ebb814 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -43,6 +43,8 @@ extern void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* bgSpot03Taki, s32 buffe extern void EnGo2_CurledUp(EnGo2* enGo2, PlayState* play); extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play); + +extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play); } #define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() @@ -564,6 +566,17 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } + case VB_PLAY_CARPENTER_FREE_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) { + EnDaiku* enDaiku = va_arg(args, EnDaiku*); + if (enDaiku->subCamActive) { + enDaiku->subCamActive = false; + EnDaiku_EscapeSuccess(enDaiku, gPlayState); + } + *should = false; + } + break; + } case VB_PLAY_GORON_FREE_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { *should = false; diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 15c1950aa..d40d25499 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -451,6 +451,10 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) { this->subCamActive = true; this->escapeSubCamTimer = sEscapeSubCamParams[this->actor.params & 3].maxFramesActive; + if (!GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) { + return; + } + eyePosDeltaLocal.x = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.x; eyePosDeltaLocal.y = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.y; eyePosDeltaLocal.z = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.z; @@ -477,6 +481,10 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) { void EnDaiku_UpdateSubCamera(EnDaiku* this, PlayState* play) { s32 pad; + if (!GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) { + return; + } + this->subCamAtTarget.x = this->actor.world.pos.x; this->subCamAtTarget.y = this->actor.world.pos.y + 60.0f; this->subCamAtTarget.z = this->actor.world.pos.z; @@ -493,8 +501,10 @@ void EnDaiku_EscapeSuccess(EnDaiku* this, PlayState* play) { Actor* gerudoGuard; Vec3f vec; - Play_ClearCamera(play, this->subCamId); - Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + if (GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) { + Play_ClearCamera(play, this->subCamId); + Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); + } this->subCamActive = false; if (GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {