From e96503c0bdabee121d30db938246ad96bc0a06ed Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 31 Dec 2025 00:21:53 +0100 Subject: [PATCH] Fix custom tunics not updating on scene change (#6026) --- .../cosmetics/CustomSkeletons.cpp | 22 +++++-------------- .../GameInteractor_HookTable.h | 2 ++ .../game-interactor/GameInteractor_Hooks.cpp | 8 +++++++ .../game-interactor/GameInteractor_Hooks.h | 2 ++ soh/src/code/z_inventory.c | 2 ++ soh/src/code/z_skelanime.c | 2 ++ 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp b/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp index 8d22e0e1c..77be9b19a 100644 --- a/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp +++ b/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp @@ -8,21 +8,8 @@ extern "C" { extern PlayState* gPlayState; } -static void UpdateCustomSkeletonOnEquipTunic() { - if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) { - return; - } - - static int8_t previousTunic = -1; - int8_t equippedTunic = CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC); - if (equippedTunic != previousTunic) { - SOH::SkeletonPatcher::UpdateCustomSkeletons(); - previousTunic = equippedTunic; - } -} - -static void UpdateCustomSkeletonOnAssetAltChange() { - if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) { +static void UpdateCustomSkeleton() { + if (!GameInteractor::IsSaveLoaded(true) || gPlayState == NULL) { return; } @@ -30,8 +17,9 @@ static void UpdateCustomSkeletonOnAssetAltChange() { } static void RegisterCustomSkeletons() { - COND_HOOK(OnGameFrameUpdate, true, UpdateCustomSkeletonOnEquipTunic); - COND_HOOK(OnAssetAltChange, true, UpdateCustomSkeletonOnAssetAltChange); + COND_HOOK(OnAssetAltChange, true, UpdateCustomSkeleton); + COND_HOOK(OnLinkSkeletonInit, true, SOH::SkeletonPatcher::UpdateCustomSkeletons); + COND_HOOK(OnLinkEquipmentChange, true, SOH::SkeletonPatcher::UpdateCustomSkeletons); } static RegisterShipInitFunc initFunc(RegisterCustomSkeletons); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 5da302fe8..b961d0ff6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -22,6 +22,8 @@ DEFINE_HOOK(OnSceneFlagUnset, (int16_t sceneNum, int16_t flagType, int16_t flag) DEFINE_HOOK(OnFlagSet, (int16_t flagType, int16_t flag)); DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag)); DEFINE_HOOK(OnSceneSpawnActors, ()); +DEFINE_HOOK(OnLinkSkeletonInit, ()); +DEFINE_HOOK(OnLinkEquipmentChange, ()); DEFINE_HOOK(OnPlayerUpdate, ()); DEFINE_HOOK(OnSetDoAction, (uint16_t action)); DEFINE_HOOK(OnPlayerSfx, (u16 sfxId)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 2ffb7099e..f096139b2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -86,6 +86,14 @@ void GameInteractor_ExecuteOnSceneSpawnActors() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnLinkSkeletonInit() { + GameInteractor::Instance->ExecuteHooks(); +} + +void GameInteractor_ExecuteOnLinkEquipmentChange() { + GameInteractor::Instance->ExecuteHooks(); +} + void GameInteractor_ExecuteOnPlayerUpdate() { GameInteractor::Instance->ExecuteHooks(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index fe3533f73..4964c896a 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -25,6 +25,8 @@ void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag); void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag); void GameInteractor_ExecuteOnSceneSpawnActors(); +void GameInteractor_ExecuteOnLinkSkeletonInit(); +void GameInteractor_ExecuteOnLinkEquipmentChange(); void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnSetDoAction(uint16_t action); void GameInteractor_ExecuteOnPlayerSfx(u16 sfxId); diff --git a/soh/src/code/z_inventory.c b/soh/src/code/z_inventory.c index f2b329ed5..4141ffe1f 100644 --- a/soh/src/code/z_inventory.c +++ b/soh/src/code/z_inventory.c @@ -187,6 +187,8 @@ u8 gItemSlots[] = { void Inventory_ChangeEquipment(s16 equipment, u16 value) { gSaveContext.equips.equipment &= gEquipNegMasks[equipment]; gSaveContext.equips.equipment |= value << gEquipShifts[equipment]; + + GameInteractor_ExecuteOnLinkEquipmentChange(); } u8 Inventory_DeleteEquipment(PlayState* play, s16 equipment) { diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index a7e93e8c3..4335df0c8 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -1140,6 +1140,8 @@ void SkelAnime_InitLink(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHeade } LinkAnimation_Change(play, skelAnime, animation, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f); + + GameInteractor_ExecuteOnLinkSkeletonInit(); } /**