diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp index 09bdd727e6..e8d94d9e42 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp @@ -3,6 +3,7 @@ #include "soh/ShipInit.hpp" extern "C" { +#include "macros.h" #include "z64save.h" #include "functions.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" @@ -10,6 +11,28 @@ extern PlayState* gPlayState; extern SaveContext gSaveContext; } +// Where intro leaves Link, instead of scene's spawn point (1, 0, 95) +static const Vec3f sIntroEndPos = { 0.0f, 0.0f, 60.0f }; + +static HOOK_ID sIntroSpawnHook = 0; + +// Puts Link where intro would've left him with top-down camera +static void SkipIntro_OnSceneSpawnActors() { + GameInteractor::Instance->UnregisterGameHook(sIntroSpawnHook); + sIntroSpawnHook = 0; + + if (gPlayState->sceneNum == SCENE_LINKS_HOUSE) { + Player* player = GET_PLAYER(gPlayState); + player->actor.world.pos = sIntroEndPos; + player->actor.prevPos = sIntroEndPos; + player->actor.home.pos = sIntroEndPos; + gPlayState->unk_1242B = 1; // VIEWPOINT_LOCKED + // Watching the intro leaves this visit on the cutscene layer, which stops func_80083108 + // from running & dimming the buttons. Zeroing cutsceneIndex loses that, so put it back + gSaveContext.sceneLayer = SCENE_LAYER_CUTSCENE_FIRST + 1; + } +} + void RegisterSkipIntro() { bool shouldRegister = CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), 0) || IS_RANDO; COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, shouldRegister, { @@ -41,8 +64,14 @@ void RegisterSkipIntro() { // Skip the intro cutscene for whatever the spawnEntrance is calculated to be. if (gSaveContext.entranceIndex == spawnEntrance) { gSaveContext.cutsceneIndex = 0; - if (!IS_RANDO) + if (!IS_RANDO) { gSaveContext.dayTime = 0x8000; + if (sIntroSpawnHook == 0) { + sIntroSpawnHook = + GameInteractor::Instance->RegisterGameHook( + SkipIntro_OnSceneSpawnActors); + } + } *should = false; } }