Modularize coloured ToT Medallions hook (#5877)
* Modularize colourized ToT Medallions hook * Add overlooked reset of Forest Medallion colour * Move asset variables to hook file * Fix includes * Remove forward declarations * Use data structures to reduceboilerplate code * Simplify data structures, reduce boilerplate even more * Correct patchName2 checks * Clang format * Add brackets on if statements
This commit is contained in:
129
soh/soh/Enhancements/Graphics/ToTMedallions.cpp
Normal file
129
soh/soh/Enhancements/Graphics/ToTMedallions.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/mods.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "align_asset_macro.h"
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
static constexpr int32_t CVAR_TOT_MEDALLION_COLORS_DEFAULT = 0;
|
||||
#define CVAR_TOT_MEDALLION_COLORS_NAME CVAR_ENHANCEMENT("ToTMedallionsColors")
|
||||
#define CVAR_TOT_MEDALLION_COLORS_VALUE \
|
||||
CVarGetInteger(CVAR_TOT_MEDALLION_COLORS_NAME, CVAR_TOT_MEDALLION_COLORS_DEFAULT)
|
||||
|
||||
// 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;
|
||||
|
||||
static Gfx grayscaleWhite = gsDPSetGrayscaleColor(255, 255, 255, 255);
|
||||
|
||||
class ToTPatchSetup {
|
||||
public:
|
||||
ToTPatchSetup(Gfx ifColored, const char* patchName, int index, const char* patchName2 = "", int index2 = 0)
|
||||
: patchName(patchName), index(index), ifColored(ifColored), patchName2(patchName2), index2(index2) {
|
||||
}
|
||||
|
||||
void ApplyPatch(bool colored = true) {
|
||||
Gfx colorGfx = colored ? ifColored : grayscaleWhite;
|
||||
ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, patchName, index, colorGfx);
|
||||
if (patchName2 && *patchName2) {
|
||||
ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, patchName2, index2, colorGfx);
|
||||
}
|
||||
}
|
||||
|
||||
void RevertPatch() {
|
||||
ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, patchName);
|
||||
if (patchName2 && *patchName2) {
|
||||
ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, patchName2);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const char* patchName;
|
||||
const char* patchName2;
|
||||
int index;
|
||||
int index2;
|
||||
Gfx ifColored;
|
||||
};
|
||||
|
||||
typedef struct MedallionColorPatch {
|
||||
QuestItem questItemId;
|
||||
ToTPatchSetup patch;
|
||||
} MedallionColorPatch;
|
||||
|
||||
static ToTPatchSetup startGrayscale =
|
||||
ToTPatchSetup(gsSPGrayscale(true), "ToTMedallions_StartGrayscale", 7, "ToTMedallions_2_StartGrayscale", 7);
|
||||
|
||||
static MedallionColorPatch medallionColorPatches[] = {
|
||||
{ QUEST_MEDALLION_WATER, ToTPatchSetup(gsDPSetGrayscaleColor(0, 161, 255, 255), "ToTMedallions_MakeBlue", 16) },
|
||||
{ QUEST_MEDALLION_SPIRIT, ToTPatchSetup(gsDPSetGrayscaleColor(255, 135, 0, 255), "ToTMedallions_MakeOrange", 45) },
|
||||
{ QUEST_MEDALLION_LIGHT, ToTPatchSetup(gsDPSetGrayscaleColor(255, 255, 0, 255), "ToTMedallions_MakeYellow", 69,
|
||||
"ToTMedallions_2_MakeYellow", 16) },
|
||||
{ QUEST_MEDALLION_FOREST, ToTPatchSetup(gsDPSetGrayscaleColor(0, 255, 0, 255), "ToTMedallions_MakeGreen", 94) },
|
||||
{ QUEST_MEDALLION_FIRE, ToTPatchSetup(gsDPSetGrayscaleColor(255, 0, 0, 255), "ToTMedallions_MakeRed", 118) },
|
||||
{ QUEST_MEDALLION_SHADOW, ToTPatchSetup(gsDPSetGrayscaleColor(212, 0, 255, 255), "ToTMedallions_MakePurple", 142,
|
||||
"ToTMedallions_2_MakePurple", 27) },
|
||||
};
|
||||
|
||||
static ToTPatchSetup endGrayscale =
|
||||
ToTPatchSetup(gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL), "ToTMedallions_EndGrayscaleAndEndDlist", 160,
|
||||
"ToTMedallions_2_EndGrayscaleAndEndDlist", 51);
|
||||
|
||||
static void PatchToTMedallions() {
|
||||
// TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect
|
||||
// effects to take effect in there
|
||||
startGrayscale.ApplyPatch();
|
||||
|
||||
for (auto& medallionPatch : medallionColorPatches) {
|
||||
medallionPatch.patch.ApplyPatch(CHECK_QUEST_ITEM(medallionPatch.questItemId));
|
||||
}
|
||||
|
||||
endGrayscale.ApplyPatch();
|
||||
}
|
||||
|
||||
static void ResetToTMedallions() {
|
||||
// Unpatch everything
|
||||
startGrayscale.RevertPatch();
|
||||
|
||||
for (auto& medallionPatch : medallionColorPatches) {
|
||||
medallionPatch.patch.RevertPatch();
|
||||
}
|
||||
|
||||
endGrayscale.RevertPatch();
|
||||
}
|
||||
|
||||
void UpdateToTMedallions() {
|
||||
if (CVAR_TOT_MEDALLION_COLORS_VALUE) {
|
||||
PatchToTMedallions();
|
||||
} else {
|
||||
ResetToTMedallions();
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckTempleOfTime(int16_t sceneNum) {
|
||||
if (sceneNum != SCENE_TEMPLE_OF_TIME) {
|
||||
return;
|
||||
}
|
||||
PatchToTMedallions();
|
||||
}
|
||||
|
||||
static void RegisterToTMedallions() {
|
||||
COND_HOOK(OnItemReceive, CVAR_TOT_MEDALLION_COLORS_VALUE, [](GetItemEntry) {
|
||||
if (gPlayState) {
|
||||
CheckTempleOfTime(gPlayState->sceneNum);
|
||||
}
|
||||
});
|
||||
COND_HOOK(OnSceneInit, CVAR_TOT_MEDALLION_COLORS_VALUE, CheckTempleOfTime);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterToTMedallions, { CVAR_TOT_MEDALLION_COLORS_NAME });
|
||||
@@ -49,16 +49,6 @@ extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
/// Switches Link's age and respawns him at the last entrance he entered.
|
||||
void SwitchAge() {
|
||||
if (gPlayState == NULL)
|
||||
@@ -741,107 +731,6 @@ void RegisterRandomizedEnemySizes() {
|
||||
});
|
||||
}
|
||||
|
||||
void PatchToTMedallions() {
|
||||
// TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect
|
||||
// effects to take effect in there
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 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 RegisterToTMedallions() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry _unused) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState ||
|
||||
gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) {
|
||||
return;
|
||||
}
|
||||
PatchToTMedallions();
|
||||
});
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || sceneNum != SCENE_TEMPLE_OF_TIME) {
|
||||
return;
|
||||
}
|
||||
PatchToTMedallions();
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterFloorSwitchesHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
|
||||
Actor* actor = static_cast<Actor*>(refActor);
|
||||
@@ -896,7 +785,6 @@ void InitMods() {
|
||||
RegisterEnemyDefeatCounts();
|
||||
RegisterBossDefeatTimestamps();
|
||||
RegisterRandomizedEnemySizes();
|
||||
RegisterToTMedallions();
|
||||
RegisterFloorSwitchesHook();
|
||||
RegisterPatchHandHandler();
|
||||
RegisterHurtContainerModeHandler();
|
||||
|
||||
@@ -10,7 +10,7 @@ extern "C" {
|
||||
void UpdateDirtPathFixState(int32_t sceneNum);
|
||||
void UpdateMirrorModeState(int32_t sceneNum);
|
||||
void UpdateHurtContainerModeState(bool newState);
|
||||
void PatchToTMedallions();
|
||||
void UpdateToTMedallions();
|
||||
void UpdatePermanentHeartLossState();
|
||||
void UpdateHyperEnemiesState();
|
||||
void UpdateHyperBossesState();
|
||||
|
||||
@@ -602,7 +602,7 @@ void SohMenu::AddMenuEnhancements() {
|
||||
AddWidget(path, "Color Temple of Time's Medallions", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("ToTMedallionsColors"))
|
||||
.RaceDisable(false)
|
||||
.Callback([](WidgetInfo& info) { PatchToTMedallions(); })
|
||||
.Callback([](WidgetInfo& info) { UpdateToTMedallions(); })
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"When Medallions are collected, the Medallion imprints around the Master Sword Pedestal in the Temple "
|
||||
"of Time will become colored-in."));
|
||||
|
||||
Reference in New Issue
Block a user