diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 24077697f..d7123c570 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -26,16 +26,30 @@ extern "C" { #include +#include "align_asset_macro.h" #include "macros.h" #include "functions.h" #include "variables.h" #include "functions.h" +void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); +void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); + extern SaveContext gSaveContext; extern PlayState* gPlayState; extern void Overlay_DisplayText(float duration, const char* text); uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); } +// GreyScaleEndDlist +#define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL" +static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL; + +// This is used for the Temple of Time Medalions' color +#define dtokinoma_room_0DL_007A70 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007A70" +static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL_007A70; +#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0" +static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0; + // TODO: When there's more uses of something like this, create a new GI::RawAction? void ReloadSceneTogglingLinkAge() { gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; @@ -1116,6 +1130,91 @@ void RegisterRandomizedEnemySizes() { }); } +void PatchToTMedallions() { + // TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect + // effects to take effect in there + if (CVarGetInteger("gToTMedallionsColors", 0)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale", 7, gsSPGrayscale(true)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale", 7, gsSPGrayscale(true)); + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(0, 161, 255, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 135, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(0, 255, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 0, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(212, 0, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(212, 0, 255, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist", 160, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist", 51, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + } else { + // Unpatch everything + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale"); + + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple"); + + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist"); + } +} + +void RegisterToTMedallionsFromItem() { + GameInteractor::Instance->RegisterGameHook([](GetItemEntry _unused) { + if (!CVarGetInteger("gToTMedallionsColors", 0) && gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) { + return; + } + PatchToTMedallions(); + }); +} + +void RegisterToTMedallionsFromScene() { + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (!CVarGetInteger("gToTMedallionsColors", 0) && gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) { + return; + } + PatchToTMedallions(); + }); +} + void InitMods() { RegisterTTS(); RegisterInfiniteMoney(); @@ -1147,5 +1246,7 @@ void InitMods() { RegisterAltTrapTypes(); RegisterRandomizerSheikSpawn(); RegisterRandomizedEnemySizes(); + RegisterToTMedallionsFromItem(); + RegisterToTMedallionsFromScene(); NameTag_RegisterHooks(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index 8125659ab..46123f968 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -9,6 +9,7 @@ extern "C" { void UpdateDirtPathFixState(int32_t sceneNum); void UpdateMirrorModeState(int32_t sceneNum); +void PatchToTMedallions(); void UpdatePermanentHeartLossState(); void InitMods(); diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index af836dff5..d7efeb4f3 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -243,6 +243,7 @@ const std::vector enhancementsCvars = { "gAddTraps.Speed", "gAddTraps.Tele", "gAddTraps.Void", + "gToTMedallionsColors", }; const std::vector cheatCvars = { @@ -791,6 +792,9 @@ const std::vector randomizerPresetEntries = { // Chest size & texture matches contents PRESET_ENTRY_S32("gChestSizeAndTextureMatchesContents", CSMC_BOTH), + // Color Temple of Time's Medallions + PRESET_ENTRY_S32("gToTMedallionsColors", 1), + // Pause link animation (0 to 16) PRESET_ENTRY_S32("gPauseLiveLink", 16), // Frames to wait diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 9a006fb86..a970e3686 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -994,6 +994,10 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Always shows dungeon entrance icons on the minimap"); UIWidgets::PaddedEnhancementCheckbox("Show Gauntlets in First Person", "gFPSGauntlets", true, false); UIWidgets::Tooltip("Renders Gauntlets when using the Bow and Hookshot like in OOT3D"); + if (UIWidgets::PaddedEnhancementCheckbox("Color Temple of Time's Medallions", "gToTMedallionsColors", true, false)) { + PatchToTMedallions(); + } + UIWidgets::Tooltip("When medallions are collected, the medallion imprints around the Master Sword pedestal in the Temple of Time will become colored"); UIWidgets::Spacer(0); if (ImGui::BeginMenu("Animated Link in Pause Menu")) { ImGui::Text("Rotation");