diff --git a/soh/soh/Enhancements/Minigames/LostWoodsOcarinaGame.cpp b/soh/soh/Enhancements/Minigames/LostWoodsOcarinaGame.cpp new file mode 100644 index 0000000000..18f926c3d2 --- /dev/null +++ b/soh/soh/Enhancements/Minigames/LostWoodsOcarinaGame.cpp @@ -0,0 +1,105 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "functions.h" +#include "variables.h" +#include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" +extern PlayState* gPlayState; + +void EnSkj_WaitForPlayback(EnSkj* enSkj, PlayState* play); +} + +typedef enum { + OCARINA_GAME_STARTING_NOTES = 3, + OCARINA_GAME_ROUND_ONE_NOTES = 5, + OCARINA_GAME_ROUND_TWO_NOTES = 6, + OCARINA_GAME_ROUND_THREE_NOTES = 8, +} OcarinaGameDefaults; + +#define CVAR_CUSTOMIZE_NAME CVAR_ENHANCEMENT("CustomizeOcarinaGame") +#define CVAR_CUSTOMIZE_VALUE CVarGetInteger(CVAR_CUSTOMIZE_NAME, 0) + +#define CVAR_STARTING_NOTES_NAME CVAR_ENHANCEMENT("OcarinaGame.StartingNotes") +#define CVAR_STARTING_NOTES_VALUE CVarGetInteger(CVAR_STARTING_NOTES_NAME, OCARINA_GAME_STARTING_NOTES) + +#define CVAR_ROUND_ONE_NOTES_NAME CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes") +#define CVAR_ROUND_ONE_NOTES_VALUE CVarGetInteger(CVAR_ROUND_ONE_NOTES_NAME, OCARINA_GAME_ROUND_ONE_NOTES) + +#define CVAR_ROUND_TWO_NOTES_NAME CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes") +#define CVAR_ROUND_TWO_NOTES_VALUE CVarGetInteger(CVAR_ROUND_TWO_NOTES_NAME, OCARINA_GAME_ROUND_TWO_NOTES) + +#define CVAR_ROUND_THREE_NOTES_NAME CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes") +#define CVAR_ROUND_THREE_NOTES_VALUE CVarGetInteger(CVAR_ROUND_THREE_NOTES_NAME, OCARINA_GAME_ROUND_THREE_NOTES) + +#define CVAR_NOTE_SPEED_NAME CVAR_ENHANCEMENT("OcarinaGame.NoteSpeed") +#define CVAR_NOTE_SPEED_VALUE CVarGetInteger(CVAR_NOTE_SPEED_NAME, 1) + +#define CVAR_INFINITE_TIME_NAME CVAR_ENHANCEMENT("OcarinaUnlimitedFailTime") +#define CVAR_INFINITE_TIME_VALUE CVarGetInteger(CVAR_INFINITE_TIME_NAME, 0) + +#define CVAR_INSTANT_WIN_NAME CVAR_ENHANCEMENT("InstantOcarinaGameWin") +#define CVAR_INSTANT_WIN_VALUE CVarGetInteger(CVAR_INSTANT_WIN_NAME, 0) + +static void RegisterLostWoodsOcarinaGameRoundNotesSetup() { + COND_VB_SHOULD(VB_SET_LOST_WOODS_OCARINA_GAME_NOTES, CVAR_CUSTOMIZE_VALUE, { + s32 minigameRound = va_arg(args, s32); + u8* roundNotes = va_arg(args, u8*); + + switch (minigameRound) { + case 0: + *roundNotes = CVAR_ROUND_ONE_NOTES_VALUE; + break; + case 1: + *roundNotes = CVAR_ROUND_TWO_NOTES_VALUE; + break; + default: + *roundNotes = CVAR_ROUND_THREE_NOTES_VALUE; + break; + } + + *should = false; + }); +} + +static void RegisterLostWoodsOcarinaGameStartingNotesSetup() { + COND_VB_SHOULD(VB_SET_LOST_WOODS_OCARINA_GAME_STARTING_NOTES, + CVAR_CUSTOMIZE_VALUE && (CVAR_STARTING_NOTES_VALUE != OCARINA_GAME_STARTING_NOTES), { + for (u8 i = 0; i < CVAR_STARTING_NOTES_VALUE; i++) { + AudioOcarina_MemoryGameNextNote(); + } + *should = false; + }); +} + +static void RegisterLostWoodsOcarinaGameModifyNoteSpeed() { + COND_VB_SHOULD(VB_MODIFY_LOST_WOODS_OCARINA_GAME_NOTE_SPEED, CVAR_CUSTOMIZE_VALUE && (CVAR_NOTE_SPEED_VALUE != 1), { + s32 appendPos = va_arg(args, s32); + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][appendPos].length /= CVAR_NOTE_SPEED_VALUE; + }); +} + +static void RegisterLostWoodsOcarinaGameInfiniteTime() { + COND_VB_SHOULD(VB_LOST_WOODS_OCARINA_GAME_TIMER_TICK, CVAR_CUSTOMIZE_VALUE && CVAR_INFINITE_TIME_VALUE, + { *should = false; }); +} + +static void RegisterLostWoodsOcarinaGameInstantWin() { + COND_VB_SHOULD(VB_PLAY_LOST_WOODS_OCARINA_GAME, CVAR_CUSTOMIZE_VALUE && CVAR_INSTANT_WIN_VALUE, { + EnSkj* enSkj = va_arg(args, EnSkj*); + gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_0F; + enSkj->multiuseTimer = 160; + enSkj->actionFunc = EnSkj_WaitForPlayback; + *should = false; + }); +} + +static RegisterShipInitFunc initFunc_Notes(RegisterLostWoodsOcarinaGameRoundNotesSetup, { CVAR_CUSTOMIZE_NAME }); +static RegisterShipInitFunc initFunc_StartingNotes(RegisterLostWoodsOcarinaGameStartingNotesSetup, + { CVAR_CUSTOMIZE_NAME, CVAR_STARTING_NOTES_NAME }); +static RegisterShipInitFunc initFunc_ModifyTime(RegisterLostWoodsOcarinaGameModifyNoteSpeed, + { CVAR_CUSTOMIZE_NAME, CVAR_NOTE_SPEED_NAME }); +static RegisterShipInitFunc initFunc_InfiniteTime(RegisterLostWoodsOcarinaGameInfiniteTime, + { CVAR_CUSTOMIZE_NAME, CVAR_INFINITE_TIME_NAME }); +static RegisterShipInitFunc initFunc_InstantWin(RegisterLostWoodsOcarinaGameInstantWin, + { CVAR_CUSTOMIZE_NAME, CVAR_INSTANT_WIN_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index ceeb4068c9..58c60ba670 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1552,6 +1552,14 @@ typedef enum { // - `*DoorShutter` VB_LOCK_BOSS_DOOR, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_LOST_WOODS_OCARINA_GAME_TIMER_TICK, + // #### `result` // ```c // true @@ -1600,6 +1608,14 @@ typedef enum { // - `*EnMd` VB_MIDO_SPAWN, + // #### `result` + // ```c + // false + // ``` + // #### `args` + // - `s32` (note append position) + VB_MODIFY_LOST_WOODS_OCARINA_GAME_NOTE_SPEED, + // #### `result` // ```c // this->interactInfo.talkState == NPC_TALK_STATE_ACTION @@ -1933,6 +1949,14 @@ typedef enum { // - None VB_PLAY_GORON_FREE_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnSkj` + VB_PLAY_LOST_WOODS_OCARINA_GAME, + // #### `result` // ```c // true @@ -2413,6 +2437,23 @@ typedef enum { // - `s16` (default time limit) VB_SET_FROG_OCARINA_GAME_TIME_LIMIT, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `s32` (round number, zero-based) + // - `*u8` (note end position) + VB_SET_LOST_WOODS_OCARINA_GAME_NOTES, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_SET_LOST_WOODS_OCARINA_GAME_STARTING_NOTES, + // #### `result` // ```c // true diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c index 402e5c822d..d1ec266d6d 100644 --- a/soh/src/code/code_800EC960.c +++ b/soh/src/code/code_800EC960.c @@ -2403,35 +2403,16 @@ void AudioOcarina_RecordSong(void) { void AudioOcarina_MemoryGameInit(u8 minigameRound) { u8 i; - // #region SOH [Enhancement] - if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 0)) { - u8 startingNotes = 3; - u8 roundOneCount = CVarGetInteger(CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"), 5); - u8 roundTwoCount = CVarGetInteger(CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes"), 6); - u8 roundThreeCount = CVarGetInteger(CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes"), 8); - u8 modMinigameNoteCnts[] = { roundOneCount, roundTwoCount, roundThreeCount }; + if (minigameRound > 2) { + minigameRound = 2; + } - startingNotes = CVarGetInteger(CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), 3); - - if (minigameRound > 2) { - minigameRound = 2; - } - - sOcaMemoryGameAppendPos = 0; - sOcaMemoryGameEndPos = modMinigameNoteCnts[minigameRound]; - - for (i = 0; i < startingNotes; i++) { - AudioOcarina_MemoryGameNextNote(); - } - // #endregion - } else { - if (minigameRound > 2) { - minigameRound = 2; - } - - sOcaMemoryGameAppendPos = 0; + sOcaMemoryGameAppendPos = 0; + if (GameInteractor_Should(VB_SET_LOST_WOODS_OCARINA_GAME_NOTES, true, minigameRound, &sOcaMemoryGameEndPos)) { sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound]; + } + if (GameInteractor_Should(VB_SET_LOST_WOODS_OCARINA_GAME_STARTING_NOTES, true)) { for (i = 0; i < 3; i++) { AudioOcarina_MemoryGameNextNote(); } @@ -2453,24 +2434,13 @@ s32 AudioOcarina_MemoryGameNextNote(void) { randomPitch = sButtonToPitchMap[(randomButtonIndex + 1) % 5]; } - // #region SOH [Enhancement] - if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 0)) { - int noteSpeed = 0x2D; - noteSpeed = noteSpeed / CVarGetInteger(CVAR_ENHANCEMENT("OcarinaGame.NoteSpeed"), 1); + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = randomPitch; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 0x2D; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].volume = 0x50; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].bend = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = randomPitch; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = noteSpeed; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].volume = 0x50; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].bend = 0; - // #endregion - } else { - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = randomPitch; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 0x2D; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].volume = 0x50; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].bend = 0; - } + GameInteractor_Should(VB_MODIFY_LOST_WOODS_OCARINA_GAME_NOTE_SPEED, false, sOcaMemoryGameAppendPos); sOcaMemoryGameAppendPos++; diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 8a0e41ec43..507bdfdacc 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1414,21 +1414,12 @@ void EnSkj_StartOcarinaMinigame(EnSkj* this, PlayState* play) { EnSkj_TurnPlayer(this, player); - if (dialogState == TEXT_STATE_CLOSING) { - // #region SOH [Enhancement] - if (CVarGetInteger(CVAR_ENHANCEMENT("InstantOcarinaGameWin"), 0) && - CVarGetInteger(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 0)) { - play->msgCtx.ocarinaMode = OCARINA_MODE_0F; + if (dialogState == TEXT_STATE_CLOSING && GameInteractor_Should(VB_PLAY_LOST_WOODS_OCARINA_GAME, true, this)) { + func_8010BD58(play, OCARINA_ACTION_MEMORY_GAME); + if (sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid != NULL) { + sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid->minigameState = SKULL_KID_OCARINA_PLAY_NOTES; this->songFailTimer = 160; this->actionFunc = EnSkj_WaitForPlayback; - // #endregion - } else { - func_8010BD58(play, OCARINA_ACTION_MEMORY_GAME); - if (sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid != NULL) { - sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid->minigameState = SKULL_KID_OCARINA_PLAY_NOTES; - this->songFailTimer = 160; - this->actionFunc = EnSkj_WaitForPlayback; - } } } } @@ -1478,12 +1469,7 @@ void EnSkj_WaitForPlayback(EnSkj* this, PlayState* play) { break; case MSGMODE_MEMORY_GAME_PLAYER_PLAYING: if (this->songFailTimer != 0) { - // #region SOH [Enhancement] - if (CVarGetInteger(CVAR_ENHANCEMENT("OcarinaUnlimitedFailTime"), 0) == 1 && - CVarGetInteger(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 0) == 1) { - // don't decrement timer - // #endregion - } else { + if (GameInteractor_Should(VB_LOST_WOODS_OCARINA_GAME_TIMER_TICK, true)) { this->songFailTimer--; } } else { // took too long, game failed