diff --git a/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipMoonCrash.cpp b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipMoonCrash.cpp new file mode 100644 index 0000000000..5f08c77881 --- /dev/null +++ b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipMoonCrash.cpp @@ -0,0 +1,39 @@ +#include +#include +#include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/ShipInit.hpp" + +extern "C" { +#include "variables.h" +} + +#define CVAR_NAME "gEnhancements.Cutscenes.SkipStoryCutscenes" +#define CVAR CVarGetInteger(CVAR_NAME, 0) + +#define TERMINA_FIELD_MOON_CRASH_CS_ENTRANCE 0x54C0 + +#define MOON_CRASH_NEW_CYCLE_CS_ID 13 +#define MOON_CRASH_NEW_CYCLE_ENTRANCE_ID 0xC030 + +/** + * Skips only the visible cutscenes (Clock Tower destruction and Link's terrible fate with the Fire Wall). + * Note: There is a cutscene command SPECIFICALLY for resetting game state related to the moon crash, + * CS_MISC_RESET_SAVE_FROM_MOON_CRASH, that MUST NOT be skipped, or else + * it would break the vanilla functionality of a Moon Crash reset. + */ +void RegisterSkipMoonCrash() { + // Skips initial cutscene in Termina Field where the moon falls, goes straight to clock tower cutscene + COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVAR, { + if (gSaveContext.save.cutsceneIndex == 0x0 && + gSaveContext.save.entrance == TERMINA_FIELD_MOON_CRASH_CS_ENTRANCE) { + // This cutscene command would otherwise be run as part of the Fire Wall cutscene that gets skipped. + // IT MUST BE CALLED HERE IF THAT CUTSCENE IS SKIPPED OR ELSE THE GAME STATE WILL NOT RESET CORRECTLY! + Sram_ResetSaveFromMoonCrash(&gPlayState->sramCtx); + + gSaveContext.save.cutsceneIndex = MOON_CRASH_NEW_CYCLE_CS_ID; + gSaveContext.save.entrance = MOON_CRASH_NEW_CYCLE_ENTRANCE_ID; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterSkipMoonCrash, { CVAR_NAME });