Skip to content

Commit

Permalink
skip song of time cutscenes
Browse files Browse the repository at this point in the history
  • Loading branch information
Archez committed Jan 27, 2025
1 parent cb94159 commit 2535e28
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
3 changes: 3 additions & 0 deletions mm/2s2h/BenGui/BenMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,9 @@ void BenMenu::AddEnhancements() {
AddWidget(path, "Faster Song Playback", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Songs.FasterSongPlayback")
.Options(CheckboxOptions().Tooltip("Speeds up the playback of songs."));
AddWidget(path, "Skip Song of Time cutscenes", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Songs.SkipSoTCutscenes")
.Options(CheckboxOptions().Tooltip("Skips the cutscenes when playing any of the Song of Time songs"));

// Time Savers
path = { "Enhancements", "Time Savers", 1 };
Expand Down
68 changes: 68 additions & 0 deletions mm/2s2h/Enhancements/Songs/SkipSoTCutscenes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <libultraship/bridge.h>
#include "2s2h/GameInteractor/GameInteractor.h"
#include "2s2h/ShipInit.hpp"

extern "C" {
#include "variables.h"
#include "overlays/actors/ovl_En_Test6/z_en_test6.h"

void EnTest6_DoubleSoTCutscene(EnTest6* thisx, PlayState* play);
void EnTest6_InvertedSoTCutscene(EnTest6* thisx, PlayState* play);
void EnTest6_StopDoubleSoTCutscene(EnTest6* thisx, PlayState* play);
void EnTest6_StopInvertedSoTCutscene(EnTest6* thisx, PlayState* play);
}

#define CVAR_NAME "gEnhancements.Songs.SkipSoTCutscenes"
#define CVAR CVarGetInteger(CVAR_NAME, 0)

void RegisterSkipSoTCutscenes() {
// Song of Time cutscene plays as part of an entrance, so set the time and
// hijack the entrance to the destination
COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVAR, {
if ((gSaveContext.save.entrance == ENTRANCE(CUTSCENE, 0) ||
gSaveContext.save.entrance == ENTRANCE(CUTSCENE, 1)) &&
gSaveContext.save.cutsceneIndex == 0xFFF7) {
gSaveContext.save.eventDayCount = 0;
gSaveContext.save.day = 0;
gSaveContext.save.time = CLOCK_TIME(6, 0) - 1;

if (gSaveContext.save.entrance == ENTRANCE(CUTSCENE, 1)) {
// Loads to flash back montage before going to Dawn of... in clock town
// Use ENTRANCE(SOUTH_CLOCK_TOWN, 10) if we ever add a story cutscene skip for the flash backs
gSaveContext.save.entrance = ENTRANCE(LOST_WOODS, 1);
} else {
// Directly to Dawn of... in clock town
gSaveContext.save.entrance = ENTRANCE(SOUTH_CLOCK_TOWN, 0);
}

gSaveContext.save.cutsceneIndex = 0;
}
});

// Skips inverted/double time cutscenes by forcing the actor to stop
COND_ID_HOOK(OnActorUpdate, ACTOR_EN_TEST6, CVAR, [](Actor* actor) {
EnTest6* enTest6 = (EnTest6*)actor;

if (enTest6->actionFunc == EnTest6_DoubleSoTCutscene) {
enTest6->actionFunc = EnTest6_StopDoubleSoTCutscene;
Player* player = GET_PLAYER(gPlayState);

// Respawns the player out when going from day -> night
// copied from last cutscene cue SOTCS_CUEID_DOUBLE_END in EnTest6_SharedSoTCutscene
if (gSaveContext.save.time > CLOCK_TIME(12, 0)) {
Play_SetRespawnData(&gPlayState->state, RESPAWN_MODE_RETURN, gSaveContext.save.entrance,
player->unk_3CE, PLAYER_PARAMS(0xFF, PLAYER_INITMODE_B), &player->unk_3C0,
player->unk_3CC);
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_RETURN].entrance;
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
gSaveContext.respawnFlag = 2;
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_END;
}
} else if (enTest6->actionFunc == EnTest6_InvertedSoTCutscene) {
enTest6->actionFunc = EnTest6_StopInvertedSoTCutscene;
}
});
}

static RegisterShipInitFunc initFunc(RegisterSkipSoTCutscenes, { CVAR_NAME });

0 comments on commit 2535e28

Please sign in to comment.