Skip to content

Commit

Permalink
Add better song of double time enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettjoecox committed Nov 25, 2024
1 parent 7c222f9 commit 992634a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 6 deletions.
4 changes: 4 additions & 0 deletions mm/2s2h/BenGui/SearchableMenuItems.h
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,10 @@ void AddEnhancements() {
"Eliminates the Cooldown between Blast Mask usage.", WIDGET_CVAR_CHECKBOX } },
// Song Enhancements
{ { .widgetName = "Ocarina", .widgetType = WIDGET_SEPARATOR_TEXT },
{ "Better Song of Double Time", "gEnhancements.Songs.BetterSongOfDoubleTime",
"When playing the Song of Double Time, you can now choose the exact time you want to go to, similar to "
"the 3DS version.",
WIDGET_CVAR_CHECKBOX },
{ "Enable Sun's Song", "gEnhancements.Songs.EnableSunsSong",
"Enables the partially implemented Sun's Song. RIGHT-DOWN-UP-RIGHT-DOWN-UP to play it. "
"This song will make time move very fast until either Link moves to a different scene, "
Expand Down
1 change: 1 addition & 0 deletions mm/2s2h/Enhancements/Enhancements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ void InitEnhancements() {
RegisterFierceDeityPutaway();

// Songs
RegisterBetterSongOfDoubleTime();
RegisterEnableSunsSong();
RegisterFasterSongPlayback();
RegisterPauseOwlWarp();
Expand Down
2 changes: 1 addition & 1 deletion mm/2s2h/Enhancements/Graphics/3DSClock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void Register3DSClock() {

static s32 sFinalHoursIntro = 0;

sThreeDayClockAlpha = gPlayState->interfaceCtx.aAlpha;
sThreeDayClockAlpha = gPlayState->interfaceCtx.bAlpha;

OPEN_DISPS(gPlayState->state.gfxCtx);
s16 posX = 160;
Expand Down
111 changes: 111 additions & 0 deletions mm/2s2h/Enhancements/Songs/BetterSongOfDoubleTime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <libultraship/bridge.h>
#include "2s2h/GameInteractor/GameInteractor.h"
#include "spdlog/spdlog.h"

extern "C" {
#include "macros.h"
#include "assets/interface/week_static/week_static.h"
extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}

static bool activelyChangingTime = false;
static u32 originalTime = CLOCK_TIME(0, 0);
static u32 originalDay = 0;

extern void UpdateGameTime(u16 gameTime);

const u32 INTERVAL = (CLOCK_TIME_MINUTE * 30);

static const char* sDoWeekTableCopy[] = {
gClockDay1stTex,
gClockDay2ndTex,
gClockDayFinalTex,
};

static HOOK_ID onPlayerUpdateHookId = 0;

void OnPlayerUpdate(Actor* actor) {
if (!activelyChangingTime) {
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorUpdate>(onPlayerUpdateHookId);
return;
}

gPlayState->interfaceCtx.bAlpha = 255;

Input* input = &gPlayState->state.input[0];

// Pressing B should cancel the song
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
Audio_PlaySfx_MessageCancel();
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_END;
activelyChangingTime = false;

gSaveContext.save.day = originalDay;
UpdateGameTime(originalTime);
Interface_NewDay(gPlayState, CURRENT_DAY);
// This may have happened in the UpdateGameTime function, if there was a day/night difference, but
// we need to ensure it happens regardless because the day may have changed even if the time is the same
gPlayState->numSetupActors = ABS(gPlayState->numSetupActors);
// Load environment values for new day
func_800FEAF4(&gPlayState->envCtx);
}

// Pressing A should confirm the song
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySfx_MessageDecide();
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_END;
activelyChangingTime = false;

gSaveContext.save.eventDayCount = CURRENT_DAY;
}

// Analog stick should change the time
if (input->cur.stick_x > 0) { // Advance time
u16 newTime = CLAMP(gSaveContext.save.time + INTERVAL, 0,
(gSaveContext.save.day == 3 && gSaveContext.save.time < CLOCK_TIME(6, 0))
? (CLOCK_TIME(6, 0) - CLOCK_TIME_HOUR)
: INFINITY);
if (newTime > CLOCK_TIME(6, 0) && gSaveContext.save.time < CLOCK_TIME(6, 0)) {
gSaveContext.save.day = CLAMP(gSaveContext.save.day + 1, originalDay, 3);
Interface_NewDay(gPlayState, CURRENT_DAY);
func_800FEAF4(&gPlayState->envCtx);
}
UpdateGameTime(newTime);
} else if (input->cur.stick_x < 0) { // Reverse time
u16 newTime = CLAMP(gSaveContext.save.time - INTERVAL,
(gSaveContext.save.day == originalDay &&
((gSaveContext.save.time > CLOCK_TIME(6, 0) && originalTime > CLOCK_TIME(6, 0)) ||
(gSaveContext.save.time < CLOCK_TIME(6, 0) && originalTime < CLOCK_TIME(6, 0))))
? originalTime
: 0,
INFINITY);
if (newTime < CLOCK_TIME(6, 0) && gSaveContext.save.time > CLOCK_TIME(6, 0)) {
gSaveContext.save.day = CLAMP(gSaveContext.save.day - 1, originalDay, 3);
Interface_NewDay(gPlayState, CURRENT_DAY);
func_800FEAF4(&gPlayState->envCtx);
}
UpdateGameTime(newTime);
}
}

void RegisterBetterSongOfDoubleTime() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](s8 sceneId, s8 spawnNum) {
// In case we didn't properly reset this variable
activelyChangingTime = false;
originalTime = CLOCK_TIME(0, 0);
originalDay = 0;
});

REGISTER_VB_SHOULD(VB_DISPLAY_SONG_OF_DOUBLE_TIME_PROMPT, {
if (CVarGetInteger("gEnhancements.Songs.BetterSongOfDoubleTime", 0)) {
*should = false;
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_DOUBLE_TIME;
activelyChangingTime = true;
originalTime = gSaveContext.save.time;
originalDay = gSaveContext.save.day;

onPlayerUpdateHookId = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_PLAYER, OnPlayerUpdate);
}
});
}
1 change: 1 addition & 0 deletions mm/2s2h/Enhancements/Songs/Songs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SONGS_H
#define SONGS_H

void RegisterBetterSongOfDoubleTime();
void RegisterEnableSunsSong();
void RegisterFasterSongPlayback();
void RegisterZoraEggCount();
Expand Down
1 change: 1 addition & 0 deletions mm/2s2h/GameInteractor/GameInteractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef enum {
VB_TRANSFORM_THUNDER_MATRIX,
VB_PLAY_HEART_CONTAINER_GET_FANFARE,
VB_BE_HOOKSHOT_SURFACE,
VB_DISPLAY_SONG_OF_DOUBLE_TIME_PROMPT,
} GIVanillaBehavior;

typedef enum {
Expand Down
12 changes: 7 additions & 5 deletions mm/src/code/z_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -6025,12 +6025,14 @@ void Message_Update(PlayState* play) {
} else if (sLastPlayedSong == OCARINA_SONG_DOUBLE_TIME) {
if (interfaceCtx->restrictions.songOfDoubleTime == 0) {
if ((CURRENT_DAY != 3) || (gSaveContext.save.isNight == 0)) {
if (gSaveContext.save.isNight) {
Message_StartTextbox(play, D_801D0464[CURRENT_DAY - 1], NULL);
} else {
Message_StartTextbox(play, D_801D045C[CURRENT_DAY - 1], NULL);
if (GameInteractor_Should(VB_DISPLAY_SONG_OF_DOUBLE_TIME_PROMPT, true)) {
if (gSaveContext.save.isNight) {
Message_StartTextbox(play, D_801D0464[CURRENT_DAY - 1], NULL);
} else {
Message_StartTextbox(play, D_801D045C[CURRENT_DAY - 1], NULL);
}
play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_DOUBLE_TIME;
}
play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_DOUBLE_TIME;
} else {
Message_StartTextbox(play, 0x1B94, NULL);
play->msgCtx.ocarinaMode = OCARINA_MODE_END;
Expand Down

0 comments on commit 992634a

Please sign in to comment.