From 099d9cd0fdb095b5e7e023b460c675d8992ae840 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 17 May 2023 12:51:17 -0700 Subject: [PATCH 01/13] Threaded save was causing issues for old `oot-save.sav` conversion. Added an option just for that instance to run `SaveManager::SaveFileThreaded` outside of a thread. Everything else still runs threaded. (#2894) --- soh/soh/SaveManager.cpp | 12 ++++++++---- soh/soh/SaveManager.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 99ec2026c..240f73863 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -754,14 +754,18 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext) { GameInteractor::Instance->ExecuteHooks(fileNum); } -void SaveManager::SaveFile(int fileNum) { +void SaveManager::SaveFile(int fileNum, bool threaded) { if (fileNum == 0xFF) { return; } // Can't think of any time the promise would be needed, so use push_task instead of submit auto saveContext = new SaveContext; memcpy(saveContext, &gSaveContext, sizeof(gSaveContext)); - smThreadPool->push_task_back(&SaveManager::SaveFileThreaded, this, fileNum, saveContext); + if (threaded) { + smThreadPool->push_task_back(&SaveManager::SaveFileThreaded, this, fileNum, saveContext); + } else { + SaveFileThreaded(fileNum, saveContext); + } } void SaveManager::SaveGlobal() { @@ -2135,7 +2139,7 @@ void SaveManager::ConvertFromUnversioned() { static SaveContext saveContextSave = gSaveContext; InitFile(false); CopyV0Save(*file, gSaveContext); - SaveFile(fileNum); + SaveFile(fileNum, false); InitMeta(fileNum); gSaveContext = saveContextSave; } @@ -2156,7 +2160,7 @@ extern "C" void Save_InitFile(int isDebug) { } extern "C" void Save_SaveFile(void) { - SaveManager::Instance->SaveFile(gSaveContext.fileNum); + SaveManager::Instance->SaveFile(gSaveContext.fileNum, true); } extern "C" void Save_SaveGlobal(void) { diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 8b32774e1..d5c8def68 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -52,7 +52,7 @@ public: void Init(); void InitFile(bool isDebug); - void SaveFile(int fileNum); + void SaveFile(int fileNum, bool threaded); void SaveGlobal(); void LoadFile(int fileNum); bool SaveFile_Exist(int fileNum); From b361d5ede18e887986951c21ea2c64b8573760c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaro=20Mart=C3=ADnez?= Date: Wed, 17 May 2023 21:21:26 -0500 Subject: [PATCH 02/13] Use UTF-8 for MSVC and enable visual styles for Windows (#2888) * Add proper manifest for Windows * MSVC: Use UTF-8 encoding compile option --- CMakeLists.txt | 1 + soh/CMakeLists.txt | 2 ++ soh/Resource.rc | 7 +++++++ soh/SHIPOFHARKINIAN.manifest | 31 +++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 soh/SHIPOFHARKINIAN.manifest diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba457735..698810a73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) add_compile_options($<$:/MP>) +add_compile_options($<$:/utf-8>) if (CMAKE_SYSTEM_NAME MATCHES "Windows|Linux") if(NOT DEFINED BUILD_CROWD_CONTROL) diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 5aaeb6fd4..23e657f0d 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -500,6 +500,7 @@ if(MSVC) /INCREMENTAL:NO; /FORCE:MULTIPLE > + /MANIFEST:NO; /DEBUG; /SUBSYSTEM:WINDOWS ) @@ -514,6 +515,7 @@ if(MSVC) /INCREMENTAL:NO; /FORCE:MULTIPLE > + /MANIFEST:NO; /DEBUG; /SUBSYSTEM:WINDOWS ) diff --git a/soh/Resource.rc b/soh/Resource.rc index ad27c5471..7d9f356d0 100644 --- a/soh/Resource.rc +++ b/soh/Resource.rc @@ -91,6 +91,13 @@ END // remains consistent on all systems. IDI_ICON1 ICON "SHIPOFHARKINIAN.ico" +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +1 RT_MANIFEST "SHIPOFHARKINIAN.manifest" + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/soh/SHIPOFHARKINIAN.manifest b/soh/SHIPOFHARKINIAN.manifest new file mode 100644 index 000000000..80d9f6036 --- /dev/null +++ b/soh/SHIPOFHARKINIAN.manifest @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + From 30cc61abce6def547994f64d6563e096d3de320d Mon Sep 17 00:00:00 2001 From: AltoXorg <56553686+Alto1772@users.noreply.github.com> Date: Thu, 18 May 2023 10:22:57 +0800 Subject: [PATCH 03/13] fix search rom extension oversight (#2891) Co-authored-by: Christopher Leggett Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> --- soh/soh/Extractor/Extract.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Extractor/Extract.cpp b/soh/soh/Extractor/Extract.cpp index a9ddc4f41..f8eed8579 100644 --- a/soh/soh/Extractor/Extract.cpp +++ b/soh/soh/Extractor/Extract.cpp @@ -222,9 +222,9 @@ void Extractor::GetRoms(std::vector& roms) { if (S_ISREG(path.st_mode)) { // Get the position of the extension character. - char* ext = strchr(dir->d_name, '.'); - if (ext != NULL && (strcmp(ext, ".z64") == 0) && (strcmp(ext, ".n64") == 0) && - (strcmp(ext, ".v64") == 0)) { + char* ext = strrchr(dir->d_name, '.'); + if (ext != NULL && (strcmp(ext, ".z64") == 0 || strcmp(ext, ".n64") == 0 || + strcmp(ext, ".v64") == 0)) { roms.push_back(dir->d_name); } } From 4d02d89e03727c8e4d71541ff8eb9a5cdf260e8f Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 20 May 2023 09:24:02 -0400 Subject: [PATCH 04/13] Fixes buying songs crash on Switch (#2899) --- .../game-interactor/GameInteractor_Hooks.h | 64 ++++++++++--------- soh/soh/OTRGlobals.cpp | 5 +- soh/soh/OTRGlobals.h | 2 +- soh/src/code/z_parameter.c | 12 +++- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index b8029914f..07843c950 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -1,40 +1,46 @@ #include "GameInteractor.h" +#ifdef __cplusplus +extern "C" { +#endif // MARK: - Gameplay -extern "C" void GameInteractor_ExecuteOnLoadGame(int32_t fileNum); -extern "C" void GameInteractor_ExecuteOnExitGame(int32_t fileNum); -extern "C" void GameInteractor_ExecuteOnGameFrameUpdate(); -extern "C" void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry); -extern "C" void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry); -extern "C" void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum); -extern "C" void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum); -extern "C" void GameInteractor_ExecuteOnSceneSpawnActors(); -extern "C" void GameInteractor_ExecuteOnPlayerUpdate(); -extern "C" void GameInteractor_ExecuteOnOcarinaSongAction(); -extern "C" void GameInteractor_ExecuteOnActorUpdate(void* actor); -extern "C" void GameInteractor_ExecuteOnPlayerBonk(); -extern "C" void GameInteractor_ExecuteOnOcarinaSongAction(); +void GameInteractor_ExecuteOnLoadGame(int32_t fileNum); +void GameInteractor_ExecuteOnExitGame(int32_t fileNum); +void GameInteractor_ExecuteOnGameFrameUpdate(); +void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry); +void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry); +void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum); +void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum); +void GameInteractor_ExecuteOnSceneSpawnActors(); +void GameInteractor_ExecuteOnPlayerUpdate(); +void GameInteractor_ExecuteOnOcarinaSongAction(); +void GameInteractor_ExecuteOnActorUpdate(void* actor); +void GameInteractor_ExecuteOnPlayerBonk(); +void GameInteractor_ExecuteOnOcarinaSongAction(); // MARK: - Save Files -extern "C" void GameInteractor_ExecuteOnSaveFile(int32_t fileNum); -extern "C" void GameInteractor_ExecuteOnLoadFile(int32_t fileNum); -extern "C" void GameInteractor_ExecuteOnDeleteFile(int32_t fileNum); +void GameInteractor_ExecuteOnSaveFile(int32_t fileNum); +void GameInteractor_ExecuteOnLoadFile(int32_t fileNum); +void GameInteractor_ExecuteOnDeleteFile(int32_t fileNum); // MARK: - Dialog -extern "C" void GameInteractor_ExecuteOnDialogMessage(); -extern "C" void GameInteractor_ExecuteOnPresentTitleCard(); -extern "C" void GameInteractor_ExecuteOnInterfaceUpdate(); -extern "C" void GameInteractor_ExecuteOnKaleidoscopeUpdate(int16_t inDungeonScene); +void GameInteractor_ExecuteOnDialogMessage(); +void GameInteractor_ExecuteOnPresentTitleCard(); +void GameInteractor_ExecuteOnInterfaceUpdate(); +void GameInteractor_ExecuteOnKaleidoscopeUpdate(int16_t inDungeonScene); // MARK: - Main Menu -extern "C" void GameInteractor_ExecuteOnPresentFileSelect(); -extern "C" void GameInteractor_ExecuteOnUpdateFileSelectSelection(uint16_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileCopySelection(uint16_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileCopyConfirmationSelection(uint16_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileEraseSelection(uint16_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileEraseConfirmationSelection(uint16_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileAudioSelection(uint8_t optionIndex); -extern "C" void GameInteractor_ExecuteOnUpdateFileTargetSelection(uint8_t optionIndex); +void GameInteractor_ExecuteOnPresentFileSelect(); +void GameInteractor_ExecuteOnUpdateFileSelectSelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileCopySelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileCopyConfirmationSelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileEraseSelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileEraseConfirmationSelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileAudioSelection(uint8_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileTargetSelection(uint8_t optionIndex); // MARK: - Game -extern "C" void GameInteractor_ExecuteOnSetGameLanguage(); +void GameInteractor_ExecuteOnSetGameLanguage(); +#ifdef __cplusplus +} +#endif diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d192de6aa..2757e1b03 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -688,9 +688,10 @@ std::unordered_map ItemIDtoGetItemID{ { ITEM_WEIRD_EGG, GI_WEIRD_EGG } }; -extern "C" uint32_t GetGIID(uint32_t itemID) { - if (ItemIDtoGetItemID.contains(itemID)) +extern "C" int32_t GetGIID(uint32_t itemID) { + if (ItemIDtoGetItemID.contains(itemID)) { return ItemIDtoGetItemID.at(itemID); + } return -1; } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index e1d448af8..a77f89fca 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -145,7 +145,7 @@ void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex); void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement); void SaveManager_ThreadPoolWait(); -uint32_t GetGIID(uint32_t itemID); +int32_t GetGIID(uint32_t itemID); #endif #endif diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 954ce1190..42bdbd77a 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -15,6 +15,7 @@ #endif #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define DO_ACTION_TEX_WIDTH() 48 @@ -1706,7 +1707,7 @@ u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) { // Processes Item_Give returns u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { - uint32_t get = GetGIID(itemID); + int32_t get = GetGIID(itemID); if (get == -1) { modId = MOD_RANDOMIZER; get = itemID; @@ -6158,8 +6159,13 @@ void Interface_Update(PlayState* play) { u16 tempSaleMod = gSaveContext.pendingSaleMod; gSaveContext.pendingSale = ITEM_NONE; gSaveContext.pendingSaleMod = MOD_NONE; - if (tempSaleMod == 0) { - tempSaleItem = GetGIID(tempSaleItem); + if (tempSaleMod == MOD_NONE) { + s16 giid = GetGIID(tempSaleItem); + if (giid == -1) { + tempSaleMod = MOD_RANDOMIZER; + } else { + tempSaleItem = giid; + } } GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod, tempSaleItem)); } From 0b47a19c2c6e17c45349a2f47e07d75024249701 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 20 May 2023 09:05:47 -0700 Subject: [PATCH 05/13] Mask Sale Fix (#2900) --- soh/src/code/z_parameter.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 42bdbd77a..410fd22a4 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1707,6 +1707,11 @@ u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) { // Processes Item_Give returns u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { + // ITEM_SOLD_OUT doesn't have an ItemTable entry, so pass custom entry instead + if (itemID == ITEM_SOLD_OUT) { + GetItemEntry gie = { ITEM_SOLD_OUT, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_LESSER, NULL }; + return Return_Item_Entry(gie, returnItem); + } int32_t get = GetGIID(itemID); if (get == -1) { modId = MOD_RANDOMIZER; From cf42057842b812c194041599e64a6b3eb956b003 Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Sat, 20 May 2023 16:25:29 -0400 Subject: [PATCH 06/13] Fix: seed srand on launch and fix spoiler log for seed testing generation (#2902) --- soh/soh/Enhancements/randomizer/3drando/menu.cpp | 15 +++++---------- .../randomizer/3drando/playthrough.cpp | 5 +++-- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 ++-- soh/soh/OTRGlobals.cpp | 2 ++ 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index de6c20be0..c2fd5061d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -518,7 +518,7 @@ std::string GenerateRandomizer(std::unordered_map srand(time(NULL)); // if a blank seed was entered, make a random one if (seedString.empty()) { - Settings::seed = rand() & 0xFFFFFFFF; + seedString = std::to_string(rand() % 0xFFFFFFFF); } else if (seedString.rfind("seed_testing_count", 0) == 0 && seedString.length() > 18) { int count; try { @@ -530,17 +530,12 @@ std::string GenerateRandomizer(std::unordered_map } Playthrough::Playthrough_Repeat(cvarSettings, excludedLocations, count); return ""; - } else { - try { - uint32_t seedHash = boost::hash_32{}(seedString); - int seed = seedHash & 0xFFFFFFFF; - Settings::seed = seed; - Settings::seedString = seedString; - } catch (...) { - return ""; - } } + Settings::seedString = seedString; + uint32_t seedHash = boost::hash_32{}(Settings::seedString); + Settings::seed = seedHash & 0xFFFFFFFF; + int ret = Playthrough::Playthrough_Init(Settings::seed, cvarSettings, excludedLocations); if (ret < 0) { if (ret == -1) { // Failed to generate after 5 tries diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 67ccb5276..dbcb93e42 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -87,8 +87,9 @@ int Playthrough_Repeat(std::unordered_map cvarSet printf("\x1b[0;0HGENERATING %d SEEDS", count); uint32_t repeatedSeed = 0; for (int i = 0; i < count; i++) { - repeatedSeed = rand() % 0xFFFFFFFF; - Settings::seed = repeatedSeed; + Settings::seedString = std::to_string(rand() % 0xFFFFFFFF); + repeatedSeed = boost::hash_32{}(Settings::seedString); + Settings::seed = repeatedSeed % 0xFFFFFFFF; CitraPrint("testing seed: " + std::to_string(Settings::seed)); ClearProgress(); Playthrough_Init(Settings::seed, cvarSettings, excludedLocations); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 6fd58e908..203dd8cfd 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3191,8 +3191,8 @@ void DrawRandoEditor(bool& open) { } UIWidgets::Spacer(0); - if (ImGui::Button("Generate Randomizer")) { - GenerateRandomizer(CVarGetInteger("gRandoManualSeedEntry", 0) ? seedString : std::to_string(rand() & 0xFFFFFFFF).c_str()); + if (ImGui::Button("Generate Randomizer")) { + GenerateRandomizer(CVarGetInteger("gRandoManualSeedEntry", 0) ? seedString : ""); } UIWidgets::Spacer(0); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 2757e1b03..b0a207dfd 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -782,6 +782,8 @@ extern "C" void InitOTR() { } else { CVarClear("gLetItSnow"); } + + srand(now); #ifdef ENABLE_CROWD_CONTROL CrowdControl::Instance = new CrowdControl(); CrowdControl::Instance->Init(); From cf711d916408f9355ca8c6507d559802318dfe44 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sun, 21 May 2023 09:13:38 -0700 Subject: [PATCH 07/13] Initialize `gSlotAgeReqs[SLOT_TRADE_CHILD]` and `gItemAgeReqs[ITEM_MASK_BUNNY]` on load initialization according to `gMMBunnyHood` and `gTimelessEquipment` to prevent bunny hood from being unequipped from adult equips on first load. (#2904) Move the code to change those values based on the child trade slot item to the selecting mask loop to not be setting them every frame just because you're in the inventory. --- soh/include/variables.h | 1 + soh/src/code/z_play.c | 9 +++++++++ .../overlays/misc/ovl_kaleido_scope/z_kaleido_item.c | 12 ++++++------ .../misc/ovl_kaleido_scope/z_kaleido_scope.h | 1 - 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/soh/include/variables.h b/soh/include/variables.h index a2ac65faf..55adf0d2e 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -103,6 +103,7 @@ extern "C" extern u32 gGsFlagsShifts[4]; extern void* gItemIcons[0x82]; extern u8 gItemAgeReqs[]; + extern u8 gSlotAgeReqs[]; extern u8 gItemSlots[56]; extern void (*gSceneCmdHandlers[SCENE_CMD_ID_MAX])(PlayState*, SceneCmd*); extern s16 gLinkObjectIds[2]; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 9ac45cdcc..3804b5bfc 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -604,6 +604,15 @@ void Play_Init(GameState* thisx) { (s32)(zAllocAligned + zAllocSize) - (s32)(zAllocAligned - zAlloc)); Fault_AddClient(&D_801614B8, ZeldaArena_Display, NULL, NULL); + // In order to keep bunny hood equipped on first load, we need to pre-set the age reqs for the item and slot + if (CVarGetInteger("gMMBunnyHood", 0) || CVarGetInteger("gTimelessEquipment", 0)) { + gItemAgeReqs[ITEM_MASK_BUNNY] = 9; + if(INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_MASK_BUNNY) + gSlotAgeReqs[SLOT_TRADE_CHILD] = 9; + } + else { + gItemAgeReqs[ITEM_MASK_BUNNY] = gSlotAgeReqs[SLOT_TRADE_CHILD] = 1; + } func_800304DC(play, &play->actorCtx, play->linkActorEntry); while (!func_800973FC(play, &play->roomCtx)) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index aae19180e..53bec6c7a 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -344,12 +344,6 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->cursorItem[PAUSE_ITEM] = cursorItem; pauseCtx->cursorSlot[PAUSE_ITEM] = cursorSlot; - gSlotAgeReqs[SLOT_TRADE_CHILD] = gItemAgeReqs[ITEM_MASK_BUNNY] = - ((CVarGetInteger("gMMBunnyHood", 0) || CVarGetInteger("gTimelessEquipment", 0)) && - INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_MASK_BUNNY) - ? 9 - : 1; - if (!CHECK_SLOT_AGE(cursorSlot)) { pauseCtx->nameColorSet = 1; } @@ -405,6 +399,12 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { } } gSelectingMask = cursorSlot == SLOT_TRADE_CHILD; + + gSlotAgeReqs[SLOT_TRADE_CHILD] = gItemAgeReqs[ITEM_MASK_BUNNY] = + ((CVarGetInteger("gMMBunnyHood", 0) || CVarGetInteger("gTimelessEquipment", 0)) && + INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_MASK_BUNNY) + ? 9 + : 1; } if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && cursorSlot == SLOT_TRADE_ADULT && CHECK_BTN_ALL(input->press.button, BTN_A)) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h index ad53fdd3a..a3c97d9b2 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h @@ -7,7 +7,6 @@ extern u8 gAmmoItems[]; extern s16 D_8082AAEC[]; extern s16 D_8082AB2C[]; -extern u8 gSlotAgeReqs[]; extern u8 gEquipAgeReqs[][4]; extern u8 gAreaGsFlags[]; extern bool gSelectingMask; From 7962e0e6d6a87e73540f809c1897510fd971695c Mon Sep 17 00:00:00 2001 From: Patrick12115 <115201185+Patrick12115@users.noreply.github.com> Date: Sun, 21 May 2023 18:12:25 -0400 Subject: [PATCH 08/13] Add Scene Specific Checks to Dirt Path Fixes (#2907) * Move from Dev to Dev-Spock * Moved to mod.h * Update GameInteractor.h --- soh/soh/Enhancements/mods.cpp | 19 +++++++++++++++++++ soh/soh/Enhancements/mods.h | 3 +++ soh/soh/GameMenuBar.cpp | 7 ++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 94d8853db..36ccef505 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -486,6 +486,24 @@ void RegisterBonkDamage() { }); } +void UpdateDirtPathFixState(int32_t sceneNum) { + switch (sceneNum) { + case SCENE_SPOT00: + case SCENE_SPOT04: + case SCENE_SPOT15: + CVarSetInteger("gDirtPathFix", CVarGetInteger("gSceneSpecificDirtPathFix", 0)); + return; + default: + CVarClear("gDirtPathFix"); + } +} + +void RegisterMenuPathFix() { + GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { + UpdateDirtPathFixState(sceneNum); + }); +} + void InitMods() { RegisterTTS(); RegisterInfiniteMoney(); @@ -504,4 +522,5 @@ void InitMods() { RegisterRupeeDash(); RegisterHyperBosses(); RegisterBonkDamage(); + RegisterMenuPathFix(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index 99f547d3a..16effa712 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -1,3 +1,5 @@ +#include + #ifndef MODS_H #define MODS_H @@ -5,6 +7,7 @@ extern "C" { #endif +void UpdateDirtPathFixState(int32_t sceneNum); void InitMods(); #ifdef __cplusplus diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 42ee23284..e25bf953e 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -29,6 +29,7 @@ #include "soh/SaveManager.h" #include "OTRGlobals.h" #include "soh/Enhancements/presets.h" +#include "soh/Enhancements/mods.h" #include "soh/resource/type/Skeleton.h" #ifdef ENABLE_CROWD_CONTROL @@ -46,6 +47,8 @@ extern "C" { void disableBetaQuest() { isBetaQuestEnabled = false; } } +extern "C" PlayState* gPlayState; + enum SeqPlayers { /* 0 */ SEQ_BGM_MAIN, /* 1 */ SEQ_FANFARE, @@ -860,7 +863,9 @@ namespace GameMenuBar { ImGui::EndMenu(); } UIWidgets::PaddedText("Fix Vanishing Paths", true, false); - UIWidgets::EnhancementCombobox("gDirtPathFix", zFightingOptions, 0); + if (UIWidgets::EnhancementCombobox("gSceneSpecificDirtPathFix", zFightingOptions, 0) && gPlayState != NULL) { + UpdateDirtPathFixState(gPlayState->sceneNum); + } UIWidgets::Tooltip("Disabled: Paths vanish more the higher the resolution (Z-fighting is based on resolution)\n" "Consistent: Certain paths vanish the same way in all resolutions\n" "No Vanish: Paths do not vanish, Link seems to sink in to some paths\n" From 5de124039157e942179e574c78611614580f6f19 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 21 May 2023 22:35:56 +0000 Subject: [PATCH 09/13] Cleanup gameplay stats code/UI and support RTA timing (#2862) --- soh/include/z64save.h | 2 + soh/soh/Enhancements/gameplaystats.cpp | 818 +++++++++--------- soh/soh/Enhancements/gameplaystats.h | 18 +- soh/soh/GameMenuBar.cpp | 10 +- soh/soh/OTRGlobals.cpp | 9 + soh/soh/OTRGlobals.h | 1 + soh/soh/SaveManager.cpp | 8 + soh/src/code/z_play.c | 8 + .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 2 +- 9 files changed, 470 insertions(+), 406 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index a7e7ca652..6fb434bf3 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -83,6 +83,8 @@ typedef struct { /* */ u32 entrancesDiscovered[SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT]; /* */ u32 scenesDiscovered[SAVEFILE_SCENES_DISCOVERED_IDX_COUNT]; /* */ u8 locationsSkipped[RC_MAX]; + /* */ bool rtaTiming; + /* */ uint64_t fileCreatedAt; } SohStats; typedef struct { diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 5d60964bd..b65d62d1d 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -14,120 +14,215 @@ extern "C" { #include #include "variables.h" extern PlayState* gPlayState; +uint64_t GetUnixTimestamp(); } -const std::vector sceneMappings = { - {"Inside the Deku Tree"}, - {"Dodongo's Cavern"}, - {"Inside Jabu-Jabu's Belly"}, - {"Forest Temple"}, - {"Fire Temple"}, - {"Water Temple"}, - {"Spirit Temple"}, - {"Shadow Temple"}, - {"Bottom of the Well"}, - {"Ice Cavern"}, - {"Ganon's Tower"}, - {"Gerudo Training Ground"}, - {"Theives' Hideout"}, - {"Inside Ganon's Castle"}, - {"Tower Collapse"}, - {"Castle Collapse"}, - {"Treasure Box Shop"}, - {"Gohma's Lair"}, - {"King Dodongo's Lair"}, - {"Barinade's Lair"}, - {"Phantom Ganon's Lair"}, - {"Volvagia's Lair"}, - {"Morpha's Lair"}, - {"Twinrova's Lair"}, - {"Bongo Bongo's Lair"}, - {"Ganondorf's Lair"}, - {"Ganon's Lair"}, - {"Market Entrance (Day)"}, - {"Market Entrance (Night)"}, - {"Market Entrance (Adult)"}, - {"Back Alley (Day)"}, - {"Back Alley (Night)"}, - {"Market (Day)"}, - {"Market (Night)"}, - {"Market (Adult)"}, - {"Outside ToT (Day)"}, - {"Outside ToT (Night)"}, - {"Outside ToT (Adult)"}, - {"Know-It-All Bros' House"}, - {"Twins' House"}, - {"Mido's House"}, - {"Saria's House"}, - {"Carpenter Boss's House"}, - {"Man in Green's House"}, - {"Bazaar"}, - {"Kokiri Shop"}, - {"Goron Shop"}, - {"Zora Shop"}, - {"Kakariko Potion Shop"}, - {"Market Potion Shop"}, - {"Bombchu Shop"}, - {"Happy Mask Shop"}, - {"Link's House"}, - {"Richard's House"}, - {"Stable"}, - {"Impa's House"}, - {"Lakeside Lab"}, - {"Carpenters' Tent"}, - {"Gravekeeper's Hut"}, - {"Great Fairy"}, - {"Fairy Fountain"}, - {"Great Fairy"}, - {"Grotto"}, - {"Redead Grave"}, - {"Fairy Fountain Grave"}, - {"Royal Family's Tomb"}, - {"Shooting Gallery"}, - {"Temple of Time"}, - {"Chamber of Sages"}, - {"Castle Maze (Day)"}, - {"Castle Maze (Night)"}, - {"Cutscene Map"}, - {"Dampe's Grave"}, - {"Fishing Pond"}, - {"Castle Courtyard"}, - {"Bombchu Bowling Alley"}, - {"Ranch House"}, - {"Guard House"}, - {"Granny's Potion Shop"}, - {"Ganon Fight"}, - {"House of Skulltula"}, - {"Hyrule Field"}, - {"Kakariko Village"}, - {"Graveyard"}, - {"Zora's River"}, - {"Kokiri Forest"}, - {"Sacred Forest Meadow"}, - {"Lake Hylia"}, - {"Zora's Domain"}, - {"Zora's Fountain"}, - {"Gerudo Valley"}, - {"Lost Woods"}, - {"Desert Colossus"}, - {"Gerudo's Fortress"}, - {"Haunted Wasteland"}, - {"Hyrule Castle"}, - {"Death Mountain Trail"}, - {"Death Mountain Crater"}, - {"Goron City"}, - {"Lon Lon Ranch"}, - {"Outside Ganon's Castle"}, +const char* const sceneMappings[] = { + "Inside the Deku Tree", + "Dodongo's Cavern", + "Inside Jabu-Jabu's Belly", + "Forest Temple", + "Fire Temple", + "Water Temple", + "Spirit Temple", + "Shadow Temple", + "Bottom of the Well", + "Ice Cavern", + "Ganon's Tower", + "Gerudo Training Ground", + "Theives' Hideout", + "Inside Ganon's Castle", + "Tower Collapse", + "Castle Collapse", + "Treasure Box Shop", + "Gohma's Lair", + "King Dodongo's Lair", + "Barinade's Lair", + "Phantom Ganon's Lair", + "Volvagia's Lair", + "Morpha's Lair", + "Twinrova's Lair", + "Bongo Bongo's Lair", + "Ganondorf's Lair", + "Ganon's Lair", + "Market Entrance (Day)", + "Market Entrance (Night)", + "Market Entrance (Adult)", + "Back Alley (Day)", + "Back Alley (Night)", + "Market (Day)", + "Market (Night)", + "Market (Adult)", + "Outside ToT (Day)", + "Outside ToT (Night)", + "Outside ToT (Adult)", + "Know-It-All Bros' House", + "Twins' House", + "Mido's House", + "Saria's House", + "Carpenter Boss's House", + "Man in Green's House", + "Bazaar", + "Kokiri Shop", + "Goron Shop", + "Zora Shop", + "Kakariko Potion Shop", + "Market Potion Shop", + "Bombchu Shop", + "Happy Mask Shop", + "Link's House", + "Richard's House", + "Stable", + "Impa's House", + "Lakeside Lab", + "Carpenters' Tent", + "Gravekeeper's Hut", + "Great Fairy", + "Fairy Fountain", + "Great Fairy", + "Grotto", + "Redead Grave", + "Fairy Fountain Grave", + "Royal Family's Tomb", + "Shooting Gallery", + "Temple of Time", + "Chamber of Sages", + "Castle Maze (Day)", + "Castle Maze (Night)", + "Cutscene Map", + "Dampe's Grave", + "Fishing Pond", + "Castle Courtyard", + "Bombchu Bowling Alley", + "Ranch House", + "Guard House", + "Granny's Potion Shop", + "Ganon Fight", + "House of Skulltula", + "Hyrule Field", + "Kakariko Village", + "Graveyard", + "Zora's River", + "Kokiri Forest", + "Sacred Forest Meadow", + "Lake Hylia", + "Zora's Domain", + "Zora's Fountain", + "Gerudo Valley", + "Lost Woods", + "Desert Colossus", + "Gerudo's Fortress", + "Haunted Wasteland", + "Hyrule Castle", + "Death Mountain Trail", + "Death Mountain Crater", + "Goron City", + "Lon Lon Ranch", + "Outside Ganon's Castle", //Debug Rooms - {"Test Map"}, - {"Test Room"}, - {"Depth Test"}, - {"Stalfos Mini-Boss"}, - {"Stalfos Boss"}, - {"Dark Link"}, - {"Castle Maze (Broken)"}, - {"SRD Room"}, - {"Chest Room"} + "Test Map", + "Test Room", + "Depth Test", + "Stalfos Mini-Boss", + "Stalfos Boss", + "Dark Link", + "Castle Maze (Broken)", + "SRD Room", + "Chest Room", +}; + +const char* const countMappings[] = { + "Anubis:", + "Armos:", + "Arwing:", + "Bari:", + "Biri:", + "Beamos:", + "Big Octo:", + "Bubble (Blue):", + "Bubble (Green):", + "Bubble (Red):", + "Bubble (White):", + "Business Scrub:", + "Dark Link:", + "Dead Hand:", + "Deku Baba:", + "Deku Baba (Big):", + "Deku Scrub:", + "Dinolfos:", + "Dodongo:", + "Dodongo (Baby):", + "Door Mimic:", + "Flare Dancer:", + "Floormaster:", + "Flying Floor Tile:", + "Flying Pot:", + "Freezard:", + "Gerudo Thief:", + "Gibdo:", + "Gohma Larva:", + "Guay:", + "Iron Knuckle:", + "Iron Knuckle (Nab):", + "Keese:", + "Keese (Fire):", + "Keese (Ice):", + "Leever:", + "Leever (Big):", + "Like-Like:", + "Lizalfos:", + "Mad Scrub:", + "Moblin:", + "Moblin (Club):", + "Octorok:", + "Parasitic Tentacle:", + "Peahat:", + "Peahat Larva:", + "Poe:", + "Poe (Big):", + "Poe (Composer):", + "Poe Sisters:", + "Redead:", + "Shabom:", + "Shellblade:", + "Skull Kid:", + "Skulltula:", + "Skulltula (Big):", + "Skulltula (Gold):", + "Skullwalltula:", + "Spike:", + "Stalchild:", + "Stalfos:", + "Stinger:", + "Tailpasaran:", + "Tektite (Blue):", + "Tektite (Red):", + "Torch Slug:", + "Wallmaster:", + "Withered Deku Baba:", + "Wolfos:", + "Wolfos (White):", + "Deku Sticks:", + "Deku Nuts:", + "Bombs:", + "Arrows:", + "Deku Seeds:", + "Bombchus:", + "Beans:", + "A:", + "B:", + "L:", + "R:", + "Z:", + "C-Up:", + "C-Right:", + "C-Down:", + "C-Left:", + "D-Up:", + "D-Right:", + "D-Down:", + "D-Left:", + "Start:", }; #define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) @@ -157,125 +252,134 @@ TimestampInfo itemTimestampDisplay[TIMESTAMP_MAX]; TimestampInfo sceneTimestampDisplay[8191]; //std::vector sceneTimestampDisplay; -void DisplayTimeHHMMSS(uint32_t timeInTenthsOfSeconds, std::string text, ImVec4 color) { - - uint32_t sec = timeInTenthsOfSeconds / 10; +std::string formatTimestampGameplayStat(uint32_t value) { + uint32_t sec = value / 10; uint32_t hh = sec / 3600; uint32_t mm = (sec - hh * 3600) / 60; uint32_t ss = sec - hh * 3600 - mm * 60; - uint32_t ds = timeInTenthsOfSeconds % 10; + uint32_t ds = value % 10; + return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); +} +std::string formatIntGameplayStat(uint32_t value) { + return fmt::format("{}", value); +} + +std::string formatHexGameplayStat(uint32_t value) { + return fmt::format("{:#x} ({:d})", value, value); +} + +std::string formatHexOnlyGameplayStat(uint32_t value) { + return fmt::format("{:#x}", value, value); +} + +void GameplayStatsRow(const char* label, std::string value, ImVec4 color = COLOR_WHITE) { ImGui::PushStyleColor(ImGuiCol_Text, color); - - std::string padded = fmt::format("{:<40}", text); - ImGui::Text(padded.c_str()); - ImGui::SameLine(); - ImGui::Text("%2u:%02u:%02u.%u", hh, mm, ss, ds); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text(label); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize(value.c_str()).x - 8.0f)); + ImGui::Text("%s", value.c_str()); ImGui::PopStyleColor(); } -void SortChronological(TimestampInfo* arr, size_t len) { - TimestampInfo temp; - for (int i = 0; i < len; i++) { - for (int j = 0; j + 1 < len - i; j++) { - if (arr[j].time > arr[j + 1].time) { - temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; - } - } - } +bool compareTimestampInfoByTime(const TimestampInfo& a, const TimestampInfo& b) { + return CVarGetInteger("gGameplayStats.TimestampsReverse", 0) ? a.time > b.time : a.time < b.time; } -void DisplayStat(const char* text, uint32_t value) { - - ImGui::Text(text); - ImGui::SameLine(); - ImGui::Text("%7u", value); -} - -void DisplayStatIfNonZero(const char* text, uint32_t value) { - if (value > 0) { - DisplayStat(text, value); - } - return; -} - -std::string ResolveSceneID(int sceneID, int roomID){ - std::string scene = ""; +const char* ResolveSceneID(int sceneID, int roomID){ if (sceneID == SCENE_KAKUSIANA) { switch (roomID) { case 0: - scene = "Generic Grotto"; - break; + return "Generic Grotto"; case 1: - scene = "Lake Hylia Scrub Grotto"; - break; + return "Lake Hylia Scrub Grotto"; case 2: - scene = "Redead Grotto"; - break; + return "Redead Grotto"; case 3: - scene = "Cow Grotto"; - break; + return "Cow Grotto"; case 4: - scene = "Scrub Trio"; - break; + return "Scrub Trio"; case 5: - scene = "Flooded Grotto"; - break; + return "Flooded Grotto"; case 6: - scene = "Scrub Duo (Upgrade)"; - break; + return "Scrub Duo (Upgrade)"; case 7: - scene = "Wolfos Grotto"; - break; + return "Wolfos Grotto"; case 8: - scene = "Hyrule Castle Storms Grotto"; - break; + return "Hyrule Castle Storms Grotto"; case 9: - scene = "Scrub Duo"; - break; + return "Scrub Duo"; case 10: - scene = "Tektite Grotto"; - break; + return "Tektite Grotto"; case 11: - scene = "Forest Stage"; - break; + return "Forest Stage"; case 12: - scene = "Webbed Grotto"; - break; + return "Webbed Grotto"; case 13: - scene = "Big Skulltula Grotto"; - break; - default: - scene = "???"; + return "Big Skulltula Grotto"; }; } else if (sceneID == SCENE_HAKASITARELAY) { //Only the last room of Dampe's Grave (rm 6) is considered the windmill - scene = roomID == 6 ? "Windmill" : "Dampe's Grave"; + return roomID == 6 ? "Windmill" : "Dampe's Grave"; } else if (sceneID < SCENE_ID_MAX) { - scene = sceneMappings[sceneID]; - } else { - scene = "???"; + return sceneMappings[sceneID]; } - return scene; + + return "???"; } -void DrawStatsTracker(bool& open) { - if (!open) { - if (CVarGetInteger("gGameplayStatsEnabled", 0)) { - CVarClear("gGameplayStatsEnabled"); - LUS::RequestCvarSaveOnNextTick(); - } - return; +void DrawGameplayStatsHeader() { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); + ImGui::BeginTable("gameplayStatsHeader", 1, ImGuiTableFlags_BordersOuter); + ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); + GameplayStatsRow("Build Version:", gSaveContext.sohStats.buildVersion); + if (gSaveContext.sohStats.rtaTiming) { + GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE); + } else { + GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE); + } + if (CVarGetInteger("gGameplayStats.ShowAdditionalTimers", 0)) { // !Only display total game time + GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.sohStats.playTimer / 2), COLOR_GREY); + GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.sohStats.pauseTimer / 3), COLOR_GREY); + GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.sohStats.sceneTimer / 2), COLOR_LIGHT_BLUE); + GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.sohStats.roomTimer / 2), COLOR_LIGHT_BLUE); + } + if (gPlayState != NULL && CVarGetInteger("gGameplayStats.ShowDebugInfo", 0)) { // && display debug info + GameplayStatsRow("play->sceneNum:", formatHexGameplayStat(gPlayState->sceneNum), COLOR_YELLOW); + GameplayStatsRow("gSaveContext.entranceIndex:", formatHexGameplayStat(gSaveContext.entranceIndex), COLOR_YELLOW); + GameplayStatsRow("gSaveContext.cutsceneIndex:", formatHexOnlyGameplayStat(gSaveContext.cutsceneIndex), COLOR_YELLOW); + GameplayStatsRow("play->roomCtx.curRoom.num:", formatIntGameplayStat(gPlayState->roomCtx.curRoom.num), COLOR_YELLOW); + } + ImGui::EndTable(); + ImGui::PopStyleVar(1); +} + +void DrawGameplayStatsTimestampsTab() { + // Set up the array of item timestamps and then sort it chronologically + for (int i = 0; i < TIMESTAMP_MAX; i++) { + strcpy(itemTimestampDisplay[i].name, itemTimestampDisplayName[i]); + itemTimestampDisplay[i].time = gSaveContext.sohStats.itemTimestamp[i]; + itemTimestampDisplay[i].color = itemTimestampDisplayColor[i]; } - ImGui::SetNextWindowSize(ImVec2(480, 550), ImGuiCond_Appearing); - if (!ImGui::Begin("Gameplay Stats", &open, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; + std::sort(itemTimestampDisplay, itemTimestampDisplay + TIMESTAMP_MAX, compareTimestampInfoByTime); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); + ImGui::BeginTable("gameplayStatsTimestamps", 1, ImGuiTableFlags_BordersOuter); + ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); + for (int i = 0; i < TIMESTAMP_MAX; i++) { + // To be shown, the entry must have a non-zero time and a string for its display name + if (itemTimestampDisplay[i].time > 0 && strnlen(itemTimestampDisplay[i].name, 21) > 1) { + GameplayStatsRow(itemTimestampDisplay[i].name, formatTimestampGameplayStat(itemTimestampDisplay[i].time), itemTimestampDisplay[i].color); + } } - u32 totalTimer = GAMEPLAYSTAT_TOTAL_TIME; + ImGui::EndTable(); + ImGui::PopStyleVar(1); + +} + +void DrawGameplayStatsCountsTab() { u32 enemiesDefeated = 0; u32 ammoUsed = 0; u32 buttonPresses = 0; @@ -297,230 +401,154 @@ void DrawStatsTracker(bool& open) { for (int i = COUNT_BUTTON_PRESSES_A; i <= COUNT_BUTTON_PRESSES_START; i++) { buttonPresses += gSaveContext.sohStats.count[i]; } - // Set up the array of item timestamps and then sort it chronologically - for (int i = 0; i < TIMESTAMP_MAX; i++) { - strcpy(itemTimestampDisplay[i].name, itemTimestampDisplayName[i]); - itemTimestampDisplay[i].time = gSaveContext.sohStats.itemTimestamp[i]; - itemTimestampDisplay[i].color = itemTimestampDisplayColor[i]; + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); + ImGui::BeginTable("gameplayStatsCounts", 1, ImGuiTableFlags_BordersOuter); + ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); + GameplayStatsRow("Enemies Defeated:", formatIntGameplayStat(enemiesDefeated)); + if (enemiesDefeated > 0) { + ImGui::TableNextRow(); ImGui::TableNextColumn(); + if (ImGui::TreeNodeEx("Enemy Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { + for (int i = COUNT_ENEMIES_DEFEATED_ANUBIS; i <= COUNT_ENEMIES_DEFEATED_WOLFOS; i++) { + if (i == COUNT_ENEMIES_DEFEATED_FLOORMASTER) { + GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i] / 3)); + } else { + GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i])); + } + } + } } - + GameplayStatsRow("Rupees Collected:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_RUPEES_COLLECTED])); + UIWidgets::Tooltip("Includes rupees collected with a full wallet."); + GameplayStatsRow("Rupees Spent:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_RUPEES_SPENT])); + GameplayStatsRow("Chests Opened:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_CHESTS_OPENED])); + GameplayStatsRow("Ammo Used:", formatIntGameplayStat(ammoUsed)); + if (ammoUsed > 0) { + ImGui::TableNextRow(); ImGui::TableNextColumn(); + if (ImGui::TreeNodeEx("Ammo Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { + for (int i = COUNT_AMMO_USED_STICK; i <= COUNT_AMMO_USED_BEAN; i++) { + GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i])); + } + } + } + GameplayStatsRow("Damage Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_DAMAGE_TAKEN])); + GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SWORD_SWINGS])); + GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_STEPS])); + // If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time) + if (CVarGetInteger("gMMBunnyHood", 0) || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) { + GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2)); + } + GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ROLLS])); + GameplayStatsRow("Bonks:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BONKS])); + GameplayStatsRow("Sidehops:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SIDEHOPS])); + GameplayStatsRow("Backflips:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BACKFLIPS])); + GameplayStatsRow("Ice Traps:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ICE_TRAPS])); + GameplayStatsRow("Pauses:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_PAUSES])); + GameplayStatsRow("Pots Smashed:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_POTS_BROKEN])); + GameplayStatsRow("Bushes Cut:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BUSHES_CUT])); + GameplayStatsRow("Buttons Pressed:", formatIntGameplayStat(buttonPresses)); + if (buttonPresses > 0) { + ImGui::TableNextRow(); ImGui::TableNextColumn(); + if (ImGui::TreeNodeEx("Buttons...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { + for (int i = COUNT_BUTTON_PRESSES_A; i <= COUNT_BUTTON_PRESSES_START; i++) { + GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i])); + } + } + } + ImGui::EndTable(); + ImGui::PopStyleVar(1); +} + +void DrawGameplayStatsBreakdownTab() { for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) { std::string sceneName = ResolveSceneID(gSaveContext.sohStats.sceneTimestamps[i].scene, gSaveContext.sohStats.sceneTimestamps[i].room); std::string name; - if (CVarGetInteger("gGameplayStatRoomBreakdown", 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_KAKUSIANA) { + if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_KAKUSIANA) { name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.sohStats.sceneTimestamps[i].room); } else { name = sceneName; } strcpy(sceneTimestampDisplay[i].name, name.c_str()); - sceneTimestampDisplay[i].time = CVarGetInteger("gGameplayStatRoomBreakdown", 0) ? + sceneTimestampDisplay[i].time = CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ? gSaveContext.sohStats.sceneTimestamps[i].roomTime : gSaveContext.sohStats.sceneTimestamps[i].sceneTime; sceneTimestampDisplay[i].color = COLOR_GREY; sceneTimestampDisplay[i].isRoom = gSaveContext.sohStats.sceneTimestamps[i].isRoom; } - SortChronological(itemTimestampDisplay, sizeof(itemTimestampDisplay) / sizeof(itemTimestampDisplay[0])); - - - // Begin drawing the table and showing the stats - - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); - ImGui::BeginTable("timers", 1, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV); - ImGui::TableSetupColumn("Timers", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableNextColumn(); - - DisplayTimeHHMMSS(totalTimer, "Total Game Time: ", COLOR_WHITE); - UIWidgets::Tooltip("Timer accuracy may be affected by game performance and loading."); - DisplayTimeHHMMSS(gSaveContext.sohStats.playTimer / 2, "Gameplay Time: ", COLOR_WHITE); - UIWidgets::Tooltip("Timer accuracy may be affected by game performance and loading."); - DisplayTimeHHMMSS(gSaveContext.sohStats.pauseTimer / 3, "Pause Menu Time: ", COLOR_WHITE); - DisplayTimeHHMMSS(gSaveContext.sohStats.sceneTimer / 2, "Time in scene: ", COLOR_LIGHT_BLUE); - UIWidgets::Tooltip("Timer accuracy may be affected by game performance and loading."); - DisplayTimeHHMMSS(gSaveContext.sohStats.roomTimer / 2, "Time in room: ", COLOR_LIGHT_BLUE); - UIWidgets::Tooltip("Timer accuracy may be affected by game performance and loading."); - ImGui::Text("Current room: %d", gSaveContext.sohStats.roomNum); - - ImGui::PopStyleVar(1); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); + ImGui::BeginTable("gameplayStatsCounts", 1, ImGuiTableFlags_BordersOuter); + ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); + for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) { + TimestampInfo tsInfo = sceneTimestampDisplay[i]; + bool canShow = !tsInfo.isRoom || CVarGetInteger("gGameplayStats.RoomBreakdown", 0); + if (tsInfo.time > 0 && strnlen(tsInfo.name, 40) > 1 && canShow) { + GameplayStatsRow(tsInfo.name, formatTimestampGameplayStat(tsInfo.time), tsInfo.color); + } + } + std::string toPass; + if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneNum != SCENE_KAKUSIANA) { + toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum), gSaveContext.sohStats.roomNum); + } else { + toPass = ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum); + } + GameplayStatsRow(toPass.c_str(), formatTimestampGameplayStat(CURRENT_MODE_TIMER / 2)); ImGui::EndTable(); + ImGui::PopStyleVar(1); +} + +void DrawGameplayStatsOptionsTab() { + UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", "gGameplayStats.TimestampsReverse"); + UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", "gGameplayStats.RoomBreakdown"); + ImGui::SameLine(); + UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map."); + UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", "gGameplayStats.RTATiming"); + ImGui::SameLine(); + UIWidgets::InsertHelpHoverText( + "Timestamps are relative to starting timestamp rather than in game time, usually necessary for races/speedruns.\n\n" + "Starting timestamp is on first non-c-up input after intro cutscene.\n\n" + "NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT" + ); + UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", "gGameplayStats.ShowAdditionalTimers"); + UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", "gGameplayStats.ShowDebugInfo"); +} + +void DrawStatsTracker(bool& open) { + if (!open) { + if (CVarGetInteger("gGameplayStatsEnabled", 0)) { + CVarClear("gGameplayStatsEnabled"); + LUS::RequestCvarSaveOnNextTick(); + } + return; + } + + ImGui::SetNextWindowSize(ImVec2(480, 550), ImGuiCond_Appearing); + if (!ImGui::Begin("Gameplay Stats", &open, ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::End(); + return; + } + + DrawGameplayStatsHeader(); - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); if (ImGui::BeginTabBar("Stats", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { if (ImGui::BeginTabItem("Timestamps")) { - // Display chronological timestamps of items obtained and bosses defeated - for (int i = 0; i < TIMESTAMP_MAX; i++) { - // To be shown, the entry must have a non-zero time and a string for its display name - if (itemTimestampDisplay[i].time > 0 && strnlen(itemTimestampDisplay[i].name, 21) > 1) { - DisplayTimeHHMMSS(itemTimestampDisplay[i].time, itemTimestampDisplay[i].name, itemTimestampDisplay[i].color); - } - } + DrawGameplayStatsTimestampsTab(); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Counts")) { - DisplayStat("Enemies Defeated: ", enemiesDefeated); - // Show breakdown of enemies defeated in a tree. Only show counts for enemies if they've been defeated at least once. - if (enemiesDefeated > 0) { - if (ImGui::TreeNode("Enemy Details...")) { - DisplayStatIfNonZero("Anubis: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ANUBIS]); - DisplayStatIfNonZero("Armos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ARMOS]); - DisplayStatIfNonZero("Arwing: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ARWING]); - DisplayStatIfNonZero("Bari: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BARI]); - DisplayStatIfNonZero("Biri: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BIRI]); - DisplayStatIfNonZero("Beamos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BEAMOS]); - DisplayStatIfNonZero("Big Octo: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BIG_OCTO]); - DisplayStatIfNonZero("Bubble (Blue): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_BLUE]); - DisplayStatIfNonZero("Bubble (Green): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_GREEN]); - DisplayStatIfNonZero("Bubble (Red): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_RED]); - DisplayStatIfNonZero("Bubble (White): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_WHITE]); - DisplayStatIfNonZero("Business Scrub: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUSINESS_SCRUB]); - DisplayStatIfNonZero("Dark Link: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DARK_LINK]); - DisplayStatIfNonZero("Dead Hand: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEAD_HAND]); - DisplayStatIfNonZero("Deku Baba: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA]); - DisplayStatIfNonZero("Deku Baba (Big): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA_BIG]); - DisplayStatIfNonZero("Deku Scrub: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEKU_SCRUB]); - DisplayStatIfNonZero("Dinolfos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DINOLFOS]); - DisplayStatIfNonZero("Dodongo: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DODONGO]); - DisplayStatIfNonZero("Dodongo (Baby): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DODONGO_BABY]); - DisplayStatIfNonZero("Door Mimic: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DOOR_TRAP]); - DisplayStatIfNonZero("Flare Dancer: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_FLARE_DANCER]); - DisplayStatIfNonZero("Floormaster: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_FLOORMASTER]/3); - DisplayStatIfNonZero("Flying Floor Tile: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_FLOOR_TILE]); - DisplayStatIfNonZero("Flying Pot: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_FLYING_POT]); - DisplayStatIfNonZero("Freezard: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_FREEZARD]); - DisplayStatIfNonZero("Gerudo Thief: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_GERUDO_THIEF]); - DisplayStatIfNonZero("Gibdo: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_GIBDO]); - DisplayStatIfNonZero("Gohma Larva: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_GOHMA_LARVA]); - DisplayStatIfNonZero("Guay: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_GUAY]); - DisplayStatIfNonZero("Iron Knuckle: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE]); - DisplayStatIfNonZero("Iron Knuckle (Nab): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE_NABOORU]); - DisplayStatIfNonZero("Keese: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE]); - DisplayStatIfNonZero("Keese (Fire): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE_FIRE]); - DisplayStatIfNonZero("Keese (Ice): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE_ICE]); - DisplayStatIfNonZero("Leever: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LEEVER]); - DisplayStatIfNonZero("Leever (Big): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LEEVER_BIG]); - DisplayStatIfNonZero("Like-Like: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LIKE_LIKE]); - DisplayStatIfNonZero("Lizalfos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LIZALFOS]); - DisplayStatIfNonZero("Mad Scrub: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_MAD_SCRUB]); - DisplayStatIfNonZero("Moblin: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_MOBLIN]); - DisplayStatIfNonZero("Moblin (Club): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_MOBLIN_CLUB]); - DisplayStatIfNonZero("Octorok: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_OCTOROK]); - DisplayStatIfNonZero("Parasitic Tentacle: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_PARASITIC_TENTACLE]); - DisplayStatIfNonZero("Peahat: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_PEAHAT]); - DisplayStatIfNonZero("Peahat Larva: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_PEAHAT_LARVA]); - DisplayStatIfNonZero("Poe: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE]); - DisplayStatIfNonZero("Poe (Big): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE_BIG]); - DisplayStatIfNonZero("Poe (Composer): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE_COMPOSER]); - DisplayStatIfNonZero("Poe Sisters: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE_SISTERS]); - DisplayStatIfNonZero("Redead: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_REDEAD]); - DisplayStatIfNonZero("Shabom: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SHABOM]); - DisplayStatIfNonZero("Shellblade: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SHELLBLADE]); - DisplayStatIfNonZero("Skull Kid: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULL_KID]); - DisplayStatIfNonZero("Skulltula: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA]); - DisplayStatIfNonZero("Skulltula (Big): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_BIG]); - DisplayStatIfNonZero("Skulltula (Gold): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_GOLD]); - DisplayStatIfNonZero("Skullwalltula: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLWALLTULA]); - DisplayStatIfNonZero("Spike: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SPIKE]); - DisplayStatIfNonZero("Stalchild: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_STALCHILD]); - DisplayStatIfNonZero("Stalfos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_STALFOS]); - DisplayStatIfNonZero("Stinger: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_STINGER]); - DisplayStatIfNonZero("Tailpasaran: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TAILPASARAN]); - DisplayStatIfNonZero("Tektite (Blue): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_BLUE]); - DisplayStatIfNonZero("Tektite (Red): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_RED]); - DisplayStatIfNonZero("Torch Slug: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TORCH_SLUG]); - DisplayStatIfNonZero("Wallmaster: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WALLMASTER]); - DisplayStatIfNonZero("Withered Deku Baba: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WITHERED_DEKU_BABA]); - DisplayStatIfNonZero("Wolfos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WOLFOS]); - DisplayStatIfNonZero("Wolfos (White): ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WOLFOS_WHITE]); - ImGui::NewLine(); - ImGui::TreePop(); - } - } - - DisplayStat("Rupees Collected: ", gSaveContext.sohStats.count[COUNT_RUPEES_COLLECTED]); - UIWidgets::Tooltip("Includes rupees collected with a full wallet."); - DisplayStat("Rupees Spent: ", gSaveContext.sohStats.count[COUNT_RUPEES_SPENT]); - DisplayStat("Chests Opened: ", gSaveContext.sohStats.count[COUNT_CHESTS_OPENED]); - - DisplayStat("Ammo Used: ", ammoUsed); - // Show breakdown of ammo used in a collapsible tree. Only show ammo types if they've been used at least once. - if (ammoUsed > 0) { - if (ImGui::TreeNode("Ammo Details...")) { - DisplayStatIfNonZero("Deku Sticks: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_STICK]); - DisplayStatIfNonZero("Deku Nuts: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_NUT]); - DisplayStatIfNonZero("Deku Seeds: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_SEED]); - DisplayStatIfNonZero("Bombs: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_BOMB]); - DisplayStatIfNonZero("Bombchus: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_BOMBCHU]); - DisplayStatIfNonZero("Arrows: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_ARROW]); - DisplayStatIfNonZero("Beans: ", gSaveContext.sohStats.count[COUNT_AMMO_USED_BEAN]); - ImGui::NewLine(); - ImGui::TreePop(); - } - } - DisplayStat("Damage Taken: ", gSaveContext.sohStats.count[COUNT_DAMAGE_TAKEN]); - DisplayStat("Sword Swings: ", gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]); - DisplayStat("Steps Taken: ", gSaveContext.sohStats.count[COUNT_STEPS]); - // If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time) - if (CVarGetInteger("gMMBunnyHood", 0) || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) { - DisplayTimeHHMMSS(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2, "Bunny Hood Time: ", COLOR_WHITE); - } - DisplayStat("Rolls: ", gSaveContext.sohStats.count[COUNT_ROLLS]); - DisplayStat("Bonks: ", gSaveContext.sohStats.count[COUNT_BONKS]); - DisplayStat("Sidehops: ", gSaveContext.sohStats.count[COUNT_SIDEHOPS]); - DisplayStat("Backflips: ", gSaveContext.sohStats.count[COUNT_BACKFLIPS]); - DisplayStat("Ice Traps: ", gSaveContext.sohStats.count[COUNT_ICE_TRAPS]); - DisplayStat("Pauses: ", gSaveContext.sohStats.count[COUNT_PAUSES]); - DisplayStat("Pots Smashed: ", gSaveContext.sohStats.count[COUNT_POTS_BROKEN]); - DisplayStat("Bushes Cut: ", gSaveContext.sohStats.count[COUNT_BUSHES_CUT]); - DisplayStat("Buttons Pressed: ", buttonPresses); - // Show breakdown of ammo used in a collapsible tree. Only show ammo types if they've been used at least once. - if (buttonPresses > 0) { - if (ImGui::TreeNode("Buttons...")) { - DisplayStatIfNonZero("A: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]); - DisplayStatIfNonZero("B: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_B]); - DisplayStatIfNonZero("L: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_L]); - DisplayStatIfNonZero("R: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_R]); - DisplayStatIfNonZero("Z: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_Z]); - DisplayStatIfNonZero("C-Up: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CUP]); - DisplayStatIfNonZero("C-Right: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CRIGHT]); - DisplayStatIfNonZero("C-Down: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CDOWN]); - DisplayStatIfNonZero("C-Left: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CLEFT]); - DisplayStatIfNonZero("D-Up: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DUP]); - DisplayStatIfNonZero("D-Right: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DRIGHT]); - DisplayStatIfNonZero("D-Down: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DDOWN]); - DisplayStatIfNonZero("D-Left: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DLEFT]); - DisplayStatIfNonZero("Start: ", gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_START]); - ImGui::NewLine(); - ImGui::TreePop(); - } - } - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Breakdown")) { - UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", "gGameplayStatRoomBreakdown"); - ImGui::SameLine(); - UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map."); - if (gPlayState == NULL) { - ImGui::Text("Waiting for file load..."); - } else { - for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) { - TimestampInfo tsInfo = sceneTimestampDisplay[i]; - bool canShow = !tsInfo.isRoom || CVarGetInteger("gGameplayStatRoomBreakdown", 0); - if (tsInfo.time > 0 && strnlen(tsInfo.name, 40) > 1 && canShow) { - DisplayTimeHHMMSS(tsInfo.time, tsInfo.name, tsInfo.color); - } - } - std::string toPass; - if (CVarGetInteger("gGameplayStatRoomBreakdown", 0) && gSaveContext.sohStats.sceneNum != SCENE_KAKUSIANA) { - toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum), gSaveContext.sohStats.roomNum); - } else { - toPass = ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum); - } - DisplayTimeHHMMSS(CURRENT_MODE_TIMER / 2, toPass.c_str(), COLOR_WHITE); - } + DrawGameplayStatsCountsTab(); ImGui::EndTabItem(); } - ImGui::EndTabBar(); + if (ImGui::BeginTabItem("Breakdown")) { + DrawGameplayStatsBreakdownTab(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Options")) { + DrawGameplayStatsOptionsTab(); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); } - ImGui::PopStyleVar(1); + ImGui::Text("Note: Gameplay stats are saved to the current file and will be\nlost if you quit without saving."); ImGui::End(); @@ -670,7 +698,7 @@ void SetupDisplayColors() { } extern "C" void InitStatTracker() { - LUS::AddWindow("Enhancements", "Gameplay Stats", DrawStatsTracker, CVarGetInteger("gGameplayStatsEnabled", 0)); + LUS::AddWindow("Enhancements", "Gameplay Stats", DrawStatsTracker, CVarGetInteger("gGameplayStats.Enabled", 0)); SetupDisplayNames(); SetupDisplayColors(); } \ No newline at end of file diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index d44056970..49dbe2296 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -1,10 +1,18 @@ #pragma once -// Total gameplay time is tracked in tenths of seconds -// I.E. game time counts frames at 20fps/2, pause time counts frames at 30fps/3 -// Frame counts in z_play.c and z_kaleido_scope_call.c -#define GAMEPLAYSTAT_TOTAL_TIME (gSaveContext.sohStats.playTimer / 2 + gSaveContext.sohStats.pauseTimer / 3) -#define CURRENT_MODE_TIMER (CVarGetInteger("gGameplayStatRoomBreakdown", 0) ?\ +// When using RTA timing + // get the diff since the save was created, + // unless the game is complete in which we use the defeated ganon timestamp +// When not using RTA timing + // Total gameplay time is tracked in tenths of seconds + // I.E. game time counts frames at 20fps/2, pause time counts frames at 30fps/3 + // Frame counts in z_play.c and z_kaleido_scope_call.c +#define GAMEPLAYSTAT_TOTAL_TIME (gSaveContext.sohStats.rtaTiming ?\ + (!gSaveContext.sohStats.gameComplete ?\ + (!gSaveContext.sohStats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.sohStats.fileCreatedAt) / 100)) :\ + (gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON])) :\ + (gSaveContext.sohStats.playTimer / 2 + gSaveContext.sohStats.pauseTimer / 3)) +#define CURRENT_MODE_TIMER (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ?\ gSaveContext.sohStats.roomTimer :\ gSaveContext.sohStats.sceneTimer) diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 42ee23284..0682a6bc9 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -1013,14 +1013,14 @@ namespace GameMenuBar { LUS::RequestCvarSaveOnNextTick(); LUS::EnableWindow("Audio Editor", CVarGetInteger("gAudioEditor.WindowOpen", 0)); } - if (ImGui::Button(GetWindowButtonText("Gameplay Stats", CVarGetInteger("gGameplayStatsEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { - if (CVarGetInteger("gGameplayStatsEnabled", 0)) { - CVarClear("gGameplayStatsEnabled"); + if (ImGui::Button(GetWindowButtonText("Gameplay Stats", CVarGetInteger("gGameplayStats.Enabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { + if (CVarGetInteger("gGameplayStats.Enabled", 0)) { + CVarClear("gGameplayStats.Enabled"); } else { - CVarSetInteger("gGameplayStatsEnabled", 1); + CVarSetInteger("gGameplayStats.Enabled", 1); } LUS::RequestCvarSaveOnNextTick(); - LUS::EnableWindow("Gameplay Stats", CVarGetInteger("gGameplayStatsEnabled", 0)); + LUS::EnableWindow("Gameplay Stats", CVarGetInteger("gGameplayStats.Enabled", 0)); } ImGui::PopStyleVar(3); ImGui::PopStyleColor(1); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 1082c35ab..a1860d9a9 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -831,6 +832,14 @@ extern "C" uint64_t GetPerfCounter() { } #endif +extern "C" uint64_t GetUnixTimestamp() { + auto time = std::chrono::system_clock::now(); + auto since_epoch = time.time_since_epoch(); + auto millis = std::chrono::duration_cast(since_epoch); + long now = millis.count(); + return now; +} + // C->C++ Bridge extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) { OTRGlobals::Instance->context->GetWindow()->MainLoop(run_one_game_iter); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index e1d448af8..aeaaa6c6a 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -88,6 +88,7 @@ void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size); void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); uint64_t GetPerfCounter(); +uint64_t GetUnixTimestamp(); struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime); void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime); void ResourceMgr_ClearSkeletons(); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 99ec2026c..a33b9c8b1 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -512,6 +512,8 @@ void SaveManager::InitFileNormal() { for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) { gSaveContext.sohStats.dungeonKeys[dungeon] = 0; } + gSaveContext.sohStats.rtaTiming = CVarGetInteger("gGameplayStats.RTATiming", 0); + gSaveContext.sohStats.fileCreatedAt = 0; gSaveContext.sohStats.playTimer = 0; gSaveContext.sohStats.pauseTimer = 0; for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp); timestamp++) { @@ -1112,6 +1114,8 @@ void SaveManager::LoadBaseVersion2() { SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]); }); + SaveManager::Instance->LoadData("rtaTiming", gSaveContext.sohStats.rtaTiming); + SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.sohStats.fileCreatedAt); SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer); SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer); SaveManager::Instance->LoadArray("timestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) { @@ -1326,6 +1330,8 @@ void SaveManager::LoadBaseVersion3() { SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]); }); + SaveManager::Instance->LoadData("rtaTiming", gSaveContext.sohStats.rtaTiming); + SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.sohStats.fileCreatedAt); SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer); SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer); SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) { @@ -1535,6 +1541,8 @@ void SaveManager::SaveBase(SaveContext* saveContext) { SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->sohStats.dungeonKeys), [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.dungeonKeys[i]); }); + SaveManager::Instance->SaveData("rtaTiming", saveContext->sohStats.rtaTiming); + SaveManager::Instance->SaveData("fileCreatedAt", saveContext->sohStats.fileCreatedAt); SaveManager::Instance->SaveData("playTimer", saveContext->sohStats.playTimer); SaveManager::Instance->SaveData("pauseTimer", saveContext->sohStats.pauseTimer); SaveManager::Instance->SaveArray("itemTimestamps", ARRAY_COUNT(saveContext->sohStats.itemTimestamp), [&](size_t i) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 9ac45cdcc..e0352a7b3 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -751,6 +751,14 @@ void Play_Update(PlayState* play) { if (CHECK_BTN_ALL(input[0].press.button, BTN_R)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_R]++;} if (CHECK_BTN_ALL(input[0].press.button, BTN_Z)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_Z]++;} if (CHECK_BTN_ALL(input[0].press.button, BTN_START)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_START]++;} + + // Start RTA timing on first non-c-up input after intro cutscene + if ( + !gSaveContext.sohStats.fileCreatedAt && !Player_InCsMode(play) && + ((input[0].press.button && input[0].press.button != 0x8) || input[0].rel.stick_x != 0 || input[0].rel.stick_y != 0) + ) { + gSaveContext.sohStats.fileCreatedAt = GetUnixTimestamp(); + } } if (gTrnsnUnkState != 0) { diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index a1cfaa684..9de9f7400 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -1680,8 +1680,8 @@ void func_8090120C(BossGanon2* this, PlayState* play) { if ((ABS(temp_a0_2) < 0x2000) && (sqrtf(SQ(temp_f14) + SQ(temp_f12)) < 70.0f) && (player->swordState != 0) && (player->heldItemAction == PLAYER_IA_SWORD_MASTER)) { func_80064520(play, &play->csCtx); - gSaveContext.sohStats.gameComplete = true; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); From f005bd3b7fcd2ecd7c286cf0c5877ce6deb2fb48 Mon Sep 17 00:00:00 2001 From: Rozelette Date: Mon, 22 May 2023 08:20:06 -0500 Subject: [PATCH 10/13] add skeleton unregistration to actors that manage their own skeletons (#2908) --- .../actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 4 +++- soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 2 ++ soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c | 3 +++ soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c | 3 +++ .../overlays/actors/ovl_Door_Killer/z_door_killer.c | 2 ++ soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c | 11 ++++++++++- soh/src/overlays/actors/ovl_En_Am/z_en_am.c | 2 ++ soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 2 ++ soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c | 2 ++ .../actors/ovl_En_Attack_Niw/z_en_attack_niw.c | 2 ++ soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c | 2 ++ .../overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c | 2 ++ soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c | 2 ++ soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c | 3 +++ .../actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 3 +++ soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 2 ++ soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c | 2 ++ soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c | 2 ++ soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c | 2 ++ soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 2 ++ soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c | 2 ++ soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c | 2 ++ soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c | 2 ++ .../ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c | 2 ++ .../overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c | 2 ++ .../overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c | 2 ++ soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c | 2 ++ soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c | 2 ++ .../actors/ovl_En_Diving_Game/z_en_diving_game.c | 2 ++ soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 2 ++ .../overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c | 2 ++ .../overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c | 2 ++ soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c | 2 ++ soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c | 2 ++ soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c | 2 ++ soh/src/overlays/actors/ovl_En_Door/z_en_door.c | 2 ++ soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c | 3 +++ soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c | 2 ++ soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c | 2 ++ soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c | 2 ++ soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c | 2 ++ soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c | 2 ++ .../overlays/actors/ovl_En_Floormas/z_en_floormas.c | 2 ++ soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 3 +++ soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 2 ++ soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c | 2 ++ soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c | 2 ++ soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 2 ++ soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c | 2 ++ soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c | 2 ++ soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c | 2 ++ soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c | 5 ----- soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c | 2 ++ soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 3 +++ soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c | 2 ++ soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c | 2 ++ soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c | 3 +++ soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c | 2 ++ soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c | 2 ++ soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c | 2 ++ .../overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c | 2 ++ soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c | 2 ++ soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c | 2 ++ soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 2 ++ soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c | 2 ++ soh/src/overlays/actors/ovl_En_In/z_en_in.c | 2 ++ soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c | 2 ++ soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c | 2 ++ soh/src/overlays/actors/ovl_En_Js/z_en_js.c | 2 ++ soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c | 3 +-- soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c | 3 +-- soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c | 3 +-- .../overlays/actors/ovl_En_Karebaba/z_en_karebaba.c | 2 ++ soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 2 ++ soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 2 ++ soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c | 2 ++ soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 2 ++ soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 2 ++ soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c | 2 ++ soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c | 2 ++ soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c | 2 ++ soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c | 2 ++ soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c | 2 ++ .../overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c | 3 +++ .../overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 2 ++ soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c | 4 ++++ soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 3 +++ soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c | 2 ++ soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c | 2 ++ .../overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c | 2 ++ .../overlays/actors/ovl_En_Po_Field/z_en_po_field.c | 2 ++ .../overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c | 2 ++ .../actors/ovl_En_Po_Sisters/z_en_po_sisters.c | 2 ++ soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c | 2 ++ soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c | 2 ++ soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c | 2 ++ soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c | 2 ++ soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c | 2 ++ soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 2 ++ .../overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c | 2 ++ soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c | 2 ++ soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 2 ++ soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c | 2 ++ soh/src/overlays/actors/ovl_En_St/z_en_st.c | 2 ++ soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 2 ++ soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c | 2 ++ .../actors/ovl_En_Syateki_Man/z_en_syateki_man.c | 3 +++ .../actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c | 2 ++ soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 2 ++ .../actors/ovl_En_Takara_Man/z_en_takara_man.c | 9 ++++++++- soh/src/overlays/actors/ovl_En_Test/z_en_test.c | 3 +++ soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c | 2 ++ soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c | 2 ++ soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c | 2 ++ soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c | 3 +++ soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c | 2 ++ soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c | 2 ++ soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c | 2 ++ soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c | 2 ++ soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c | 2 ++ soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 2 ++ soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c | 2 ++ soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c | 2 ++ soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 2 ++ soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c | 3 +++ soh/src/overlays/actors/ovl_player_actor/z_player.c | 3 +++ 126 files changed, 279 insertions(+), 14 deletions(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 34a8e5f2a..49584e2cd 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -109,7 +109,9 @@ void BgDyYoseizo_Init(Actor* thisx, PlayState* play2) { this->actionFunc = BgDyYoseizo_CheckMagicAcquired; } -void BgDyYoseizo_Destroy(Actor* this, PlayState* play) { +void BgDyYoseizo_Destroy(Actor* thisx, PlayState* play) { + BgDyYoseizo* this = (BgDyYoseizo*)thisx; + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } static Color_RGB8 sParticlePrimColors[] = { diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 4f1d8244f..98d1da158 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -346,6 +346,8 @@ void BossSst_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyJntSph(play, &this->colliderJntSph); Collider_DestroyCylinder(play, &this->colliderCyl); Audio_StopSfxByPos(&this->center); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void BossSst_HeadSetupLurk(BossSst* this) { diff --git a/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c b/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c index db9c80fe6..fb302bb27 100644 --- a/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c +++ b/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c @@ -24,6 +24,9 @@ void DemoIk_Type1Draw(DemoIk* this, PlayState* play); void DemoIk_Type2Draw(DemoIk* this, PlayState* play); void DemoIk_Destroy(Actor* thisx, PlayState* play) { + DemoIk* this = (DemoIk*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void DemoIk_BgCheck(DemoIk* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 5ea59cef7..05a292f16 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -1163,7 +1163,10 @@ void DemoIm_Init(Actor* thisx, PlayState* play) { } void DemoIm_Destroy(Actor* thisx, PlayState* play) { + DemoIm* this = (DemoIm*)thisx; DemoIm_DestroyCollider(thisx, play); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 DemoIm_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { diff --git a/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c b/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c index 8784647b0..4558838cb 100644 --- a/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c +++ b/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c @@ -203,6 +203,8 @@ void DoorKiller_Destroy(Actor* thisx, PlayState* play) { if ((thisx->params & 0xFF) == DOOR_KILLER_DOOR) { Collider_DestroyCylinder(play, &this->colliderCylinder); Collider_DestroyJntSph(play, &this->colliderJntSph); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } } diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 5152d290a..965409ac2 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -97,7 +97,16 @@ void DoorWarp1_Destroy(Actor* thisx, PlayState* play) { play->envCtx.adjAmbientColor[i] = play->envCtx.adjFogColor[i] = play->envCtx.adjLight1Color[i] = 0; } - //! @bug SkelAnime_Free is not called for crystal variants + + switch (this->actor.params) { + case WARP_DUNGEON_ADULT: + case WARP_BLUE_CRYSTAL: + case WARP_PURPLE_CRYSTAL: + SkelAnime_Free(&this->skelAnime, play); + break; + default: + break; + } } void DoorWarp1_SetupWarp(DoorWarp1* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c index 44d6f036c..71b562eff 100644 --- a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c +++ b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c @@ -249,6 +249,8 @@ void EnAm_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->hurtCollider); Collider_DestroyCylinder(play, &this->blockCollider); //! @bug Quad collider is not destroyed (though destroy doesnt really do anything anyway) + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnAm_SpawnEffects(EnAm* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index f9d76b60e..97664aa17 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -95,6 +95,8 @@ void EnAni_Destroy(Actor* thisx, PlayState* play) { EnAni* this = (EnAni*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnAni_SetText(EnAni* this, PlayState* play, u16 textId) { diff --git a/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c b/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c index 7b99e4bcb..08e06ac04 100644 --- a/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c +++ b/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c @@ -167,6 +167,8 @@ void EnAnubice_Destroy(Actor* thisx, PlayState* play) { tag->anubis = NULL; } } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnAnubice_FindFlameCircles(EnAnubice* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c index a73c542c6..fd824bed7 100644 --- a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c +++ b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c @@ -68,6 +68,8 @@ void EnAttackNiw_Destroy(Actor* thisx, PlayState* play) { cucco->unk_296--; } } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809B5268(EnAttackNiw* this, PlayState* play, s16 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c index 35f6eb064..9f07839da 100644 --- a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c +++ b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c @@ -403,6 +403,8 @@ void EnBb_Destroy(Actor* thisx, PlayState* play) { EnBb* this = (EnBb*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnBb_SetupFlameTrail(EnBb* this) { diff --git a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c index 24b2ff9f3..8e544a151 100644 --- a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c +++ b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c @@ -196,6 +196,8 @@ void EnBigokuta_Destroy(Actor* thisx, PlayState* play) { for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) { Collider_DestroyCylinder(play, &this->cylinder[i]); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809BCE3C(EnBigokuta* this) { diff --git a/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c b/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c index d2ce6686e..971ac0f20 100644 --- a/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c +++ b/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c @@ -136,6 +136,8 @@ void EnBili_Destroy(Actor* thisx, PlayState* play) { EnBili* this = (EnBili*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } // Setup Action Functions diff --git a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c index fc0c673a1..f521e1718 100644 --- a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c +++ b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c @@ -62,6 +62,9 @@ void EnBird_Init(Actor* thisx, PlayState* play) { } void EnBird_Destroy(Actor* thisx, PlayState* play) { + EnBird* this = (EnBird*)thisx; + + SkelAnime_Free(&this->skelAnime, play); } void func_809C1CAC(EnBird* this, s16 params) { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index db092c862..75f27576b 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -89,6 +89,9 @@ void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) { } void EnBomBowlMan_Destroy(Actor* thisx, PlayState* play) { + EnBomBowlMan* this = (EnBomBowlMan*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnBomBowMan_SetupWaitAsleep(EnBomBowlMan* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 2a83e587e..54ec3cf29 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -208,6 +208,8 @@ void EnBox_Destroy(Actor* thisx, PlayState* play) { EnBox* this = (EnBox*)thisx; DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } void EnBox_RandomDustKinematic(EnBox* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { diff --git a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c index a7c2d119c..78607e0fe 100644 --- a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c +++ b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c @@ -102,6 +102,8 @@ void EnBrob_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); Collider_DestroyCylinder(play, &this->colliders[0]); Collider_DestroyCylinder(play, &this->colliders[1]); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809CADDC(EnBrob* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c index cfe109185..a775137f4 100644 --- a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c +++ b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c @@ -180,6 +180,8 @@ void EnButte_Destroy(Actor* thisx, PlayState* play2) { EnButte* this = (EnButte*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809CD56C(EnButte* this) { diff --git a/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c b/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c index acf4727b4..3b7155b5e 100644 --- a/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c +++ b/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c @@ -161,6 +161,8 @@ void EnBw_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider1); Collider_DestroyCylinder(play, &this->collider2); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809CE884(EnBw* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 1c9df2c7c..b9e0136f1 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -162,6 +162,8 @@ void EnCow_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->colliders[0]); Collider_DestroyCylinder(play, &this->colliders[1]); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809DF494(EnCow* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c b/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c index 40af76a4d..6598406ce 100644 --- a/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c +++ b/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c @@ -124,6 +124,8 @@ void EnCrow_Destroy(Actor* thisx, PlayState* play) { EnCrow* this = (EnCrow*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } // Setup Action functions diff --git a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c index 497a6d527..a3006daec 100644 --- a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c +++ b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c @@ -161,6 +161,8 @@ void EnCs_Destroy(Actor* thisx, PlayState* play) { EnCs* this = (EnCs*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnCs_GetTalkState(EnCs* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 57d2b9055..635f77e41 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -219,6 +219,8 @@ void EnDaiku_Destroy(Actor* thisx, PlayState* play) { EnDaiku* this = (EnDaiku*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnDaiku_UpdateTalking(EnDaiku* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c index a7a107d3a..e098051c7 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c +++ b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c @@ -208,6 +208,8 @@ void EnDaikuKakariko_Destroy(Actor* thisx, PlayState* play) { EnDaikuKakariko* this = (EnDaikuKakariko*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnDaikuKakariko_GetTalkState(EnDaikuKakariko* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c index 5fa65f49c..9f1658ed9 100644 --- a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c +++ b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c @@ -278,6 +278,8 @@ void EnDekubaba_Destroy(Actor* thisx, PlayState* play) { EnDekubaba* this = (EnDekubaba*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDekubaba_DisableHitboxes(EnDekubaba* this) { diff --git a/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index 3305700ec..86daf5187 100644 --- a/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -136,6 +136,8 @@ void EnDekunuts_Destroy(Actor* thisx, PlayState* play) { if (this->actor.params != DEKUNUTS_FLOWER) { Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } } diff --git a/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c b/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c index b41e9cdff..b64d327a9 100644 --- a/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c +++ b/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c @@ -164,6 +164,8 @@ void EnDh_Destroy(Actor* thisx, PlayState* play) { func_800F5B58(); Collider_DestroyCylinder(play, &this->collider1); Collider_DestroyJntSph(play, &this->collider2); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDh_SpawnDebris(PlayState* play, EnDh* this, Vec3f* spawnPos, f32 spread, s32 arg4, f32 accelXZ, diff --git a/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c b/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c index dda60bfe4..090bac2d2 100644 --- a/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c +++ b/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c @@ -177,6 +177,8 @@ void EnDha_Destroy(Actor* thisx, PlayState* play) { EnDha* this = (EnDha*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDha_SetupWait(EnDha* this) { diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index cbd6cee2b..a54b87e7b 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -108,6 +108,8 @@ void EnDivingGame_Destroy(Actor* thisx, PlayState* play) { gSaveContext.timer1State = 0; } Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDivingGame_SpawnRuppy(EnDivingGame* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 6df63c4de..3942e3b2f 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -200,6 +200,8 @@ void EnDns_Destroy(Actor* thisx, PlayState* play) { EnDns* this = (EnDns*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDns_ChangeAnim(EnDns* this, u8 index) { diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c index 215331857..6a0d204bf 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c @@ -96,6 +96,8 @@ void EnDntJiji_Destroy(Actor* thisx, PlayState* play) { EnDntJiji* this = (EnDntJiji*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDntJiji_SetFlower(EnDntJiji* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c index 030735f5b..5f05992ca 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c @@ -167,6 +167,8 @@ void EnDntNomal_Destroy(Actor* thisx, PlayState* play) { } else { Collider_DestroyCylinder(play, &this->bodyCyl); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDntNomal_WaitForObject(EnDntNomal* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c index 3f459e84d..62c83a231 100644 --- a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c +++ b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c @@ -88,6 +88,8 @@ void EnDodojr_Destroy(Actor* thisx, PlayState* play) { EnDodojr* this = (EnDodojr*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_809F64D0(EnDodojr* this) { diff --git a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c index 0f841389d..f6b0939e1 100644 --- a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -353,6 +353,8 @@ void EnDodongo_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyTris(play, &this->colliderHard); Collider_DestroyJntSph(play, &this->colliderBody); Collider_DestroyQuad(play, &this->colliderAT); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDodongo_SetupIdle(EnDodongo* this) { diff --git a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c index e2e63fc03..c860abe26 100644 --- a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c +++ b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c @@ -300,6 +300,8 @@ void EnDog_Init(Actor* thisx, PlayState* play) { void EnDog_Destroy(Actor* thisx, PlayState* play) { EnDog* this = (EnDog*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDog_FollowPath(EnDog* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c index bd60075fd..2e830f250 100644 --- a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c +++ b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c @@ -143,6 +143,8 @@ void EnDoor_Destroy(Actor* thisx, PlayState* play) { if (transitionEntry->id < 0) { transitionEntry->id = -transitionEntry->id; } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDoor_SetupType(EnDoor* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index 84b4cd816..cebceaf9e 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -50,6 +50,9 @@ void EnDs_Init(Actor* thisx, PlayState* play) { } void EnDs_Destroy(Actor* thisx, PlayState* play) { + EnDs* this = (EnDs*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnDs_Talk(EnDs* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c b/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c index b7bfa42f4..7690dfaf5 100644 --- a/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c +++ b/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c @@ -171,6 +171,8 @@ void EnEiyer_Init(Actor* thisx, PlayState* play) { void EnEiyer_Destroy(Actor* thisx, PlayState* play) { EnEiyer* this = (EnEiyer*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } void EnEiyer_RotateAroundHome(EnEiyer* this) { diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index fe39cea99..7911cbddd 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -437,6 +437,8 @@ void EnElf_Destroy(Actor* thisx, PlayState* play) { LightContext_RemoveLight(play, &play->lightCtx, this->lightNodeGlow); LightContext_RemoveLight(play, &play->lightCtx, this->lightNodeNoGlow); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80A02A20(EnElf* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c b/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c index de2aaf391..39988998f 100644 --- a/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c +++ b/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c @@ -472,6 +472,8 @@ void EnFd_Destroy(Actor* thisx, PlayState* play) { EnFd* this = (EnFd*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnFd_Reappear(EnFd* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index a62dc583c..231629b0b 100644 --- a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -198,6 +198,8 @@ void EnFirefly_Destroy(Actor* thisx, PlayState* play) { EnFirefly* this = (EnFirefly*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnFirefly_SetupFlyIdle(EnFirefly* this) { diff --git a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c index be42dc521..4c1a9ba1f 100644 --- a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -157,6 +157,8 @@ void EnFish_Destroy(Actor* thisx, PlayState* play2) { EnFish* this = (EnFish*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnFish_SetYOffset(EnFish* this) { diff --git a/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index 068e255f4..84725221a 100644 --- a/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -179,6 +179,8 @@ void EnFloormas_Destroy(Actor* thisx, PlayState* play) { EnFloormas* this = (EnFloormas*)thisx; ColliderCylinder* col = &this->collider; Collider_DestroyCylinder(play, col); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnFloormas_MakeInvulnerable(EnFloormas* this) { diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index 5c7159da0..fa131fe00 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -309,6 +309,9 @@ void EnFr_Destroy(Actor* thisx, PlayState* play) { EnFr* this = (EnFr*)thisx; LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); + ResourceMgr_UnregisterSkeleton(&this->skelAnimeButterfly); } void EnFr_IsDivingIntoWater(EnFr* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 13d32d757..20bc6dff6 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -99,6 +99,8 @@ void EnFu_Init(Actor* thisx, PlayState* play) { void EnFu_Destroy(Actor* thisx, PlayState* play) { EnFu* this = (EnFu*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } s32 func_80A1D94C(EnFu* this, PlayState* play, u16 textID, EnFuActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c b/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c index b1b25bed5..ffac1fa0c 100644 --- a/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c +++ b/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c @@ -208,6 +208,8 @@ void EnFw_Init(Actor* thisx, PlayState* play) { void EnFw_Destroy(Actor* thisx, PlayState* play) { EnFw* this = (EnFw*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnFw_Bounce(EnFw* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c index 0110c3017..ff4be49e6 100644 --- a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c +++ b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c @@ -224,6 +224,8 @@ void EnGb_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); LightContext_RemoveLight(play, &play->lightCtx, this->light); DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80A2F608(EnGb* this) { diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index c3b56c44e..7e397050f 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -203,6 +203,8 @@ void EnGe1_Destroy(Actor* thisx, PlayState* play) { EnGe1* this = (EnGe1*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnGe1_SetTalkAction(EnGe1* this, PlayState* play, u16 textId, f32 arg3, EnGe1ActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index ab5a48b7a..9437100d5 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -174,6 +174,8 @@ void EnGe2_Destroy(Actor* thisx, PlayState* play) { EnGe2* this = (EnGe2*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } // Detection/check functions diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index fecf3e9ea..4da2b2db7 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -90,6 +90,8 @@ void EnGe3_Destroy(Actor* thisx, PlayState* play) { EnGe3* this = (EnGe3*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnGe3_TurnToFacePlayer(EnGe3* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c index 909aa91b4..040f516ad 100644 --- a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c +++ b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c @@ -269,6 +269,8 @@ void EnGeldB_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyTris(play, &this->blockCollider); Collider_DestroyCylinder(play, &this->bodyCollider); Collider_DestroyQuad(play, &this->swordCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnGeldB_ReactToPlayer(PlayState* play, EnGeldB* this, s16 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index ea41a2e69..bd99a9ba1 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -452,11 +452,6 @@ void EnGirlA_Init(Actor* thisx, PlayState* play) { } void EnGirlA_Destroy(Actor* thisx, PlayState* play) { - EnGirlA* this = (EnGirlA*)thisx; - - if (this->isInitialized) { - SkelAnime_Free(&this->skelAnime, play); - } } s32 EnGirlA_CanBuy_Arrows(PlayState* play, EnGirlA* this) { diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 2519fcb1e..3f6ae565d 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -88,6 +88,8 @@ void EnGm_Destroy(Actor* thisx, PlayState* play) { EnGm* this = (EnGm*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80A3D7C8(void) { diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index c70a55932..ad7d99686 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -1691,6 +1691,9 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { } void EnGo2_Destroy(Actor* thisx, PlayState* play) { + EnGo2* this = (EnGo2*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnGo2_CurledUp(EnGo2* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c b/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c index decc90f5b..641eb0872 100644 --- a/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c +++ b/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c @@ -177,6 +177,8 @@ void EnGoma_Destroy(Actor* thisx, PlayState* play) { if (this->actor.params < 10) { Collider_DestroyCylinder(play, &this->colCyl1); Collider_DestroyCylinder(play, &this->colCyl2); + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } } diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c index bdf90381a..69d543d27 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c @@ -71,6 +71,8 @@ void EnGuest_Destroy(Actor* thisx, PlayState* play) { EnGuest* this = (EnGuest*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnGuest_Update(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c index 7c06608ff..507d480b2 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c +++ b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c @@ -142,6 +142,9 @@ void EnHeishi1_Init(Actor* thisx, PlayState* play) { } void EnHeishi1_Destroy(Actor* thisx, PlayState* play) { + EnHeishi1* this = (EnHeishi1*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnHeishi1_SetupWalk(EnHeishi1* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index 89ea0e499..35c351827 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -166,6 +166,8 @@ void EnHeishi2_Destroy(Actor* thisx, PlayState* play) { if ((this->collider.dim.radius != 0) || (this->collider.dim.height != 0)) { Collider_DestroyCylinder(play, &this->collider); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnHeishi2_DoNothing1(EnHeishi2* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c index 06407227f..83dae5d81 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c +++ b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c @@ -90,6 +90,8 @@ void EnHeishi3_Destroy(Actor* thisx, PlayState* play) { EnHeishi3* this = (EnHeishi3*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnHeishi3_SetupGuardType(EnHeishi3* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index f3a9ddc3a..f684f4ae5 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -107,6 +107,8 @@ void EnHeishi4_Destroy(Actor* thisx, PlayState* play) { EnHeishi4* this = (EnHeishi4*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80A56328(EnHeishi4* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c b/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c index 8f6cc3ec6..f21966d93 100644 --- a/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c +++ b/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c @@ -105,6 +105,8 @@ void EnHintnuts_Destroy(Actor* thisx, PlayState* play) { if (this->actor.params != 0xA) { Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } } diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index 17efce312..b730915e6 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -116,6 +116,8 @@ void EnHs_Destroy(Actor* thisx, PlayState* play) { EnHs* this = (EnHs*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80A6E53C(EnHs* this, PlayState* play, u16 textId, EnHsActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c index 6e0e58913..01deb32fb 100644 --- a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c +++ b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c @@ -71,6 +71,8 @@ void EnHs2_Destroy(Actor* thisx, PlayState* play) { EnHs2* this = (EnHs2*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80A6F0B4(EnHs2* this, PlayState* play, u16 textId, EnHs2ActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index b7eb3a301..248094843 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -906,6 +906,8 @@ void EnHy_Destroy(Actor* thisx, PlayState* play) { EnHy* this = (EnHy*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnHy_InitImpl(EnHy* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index 17825746d..d57ec0d45 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -175,6 +175,8 @@ void EnIk_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyTris(play, &this->shieldCollider); Collider_DestroyCylinder(play, &this->bodyCollider); Collider_DestroyQuad(play, &this->axeCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnIk_SetupAction(EnIk* this, EnIkActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 720f371b4..246a0f3ac 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -503,6 +503,8 @@ void EnIn_Destroy(Actor* thisx, PlayState* play) { if (this->actionFunc != NULL && this->actionFunc != func_80A79FB0) { Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } } diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c index c6da75926..8e1604e9a 100644 --- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c +++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c @@ -234,6 +234,8 @@ void EnInsect_Destroy(Actor* thisx, PlayState* play) { if ((temp_v0 == 2 || temp_v0 == 3) && D_80A7DEB8 > 0) { D_80A7DEB8--; } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80A7C3A0(EnInsect* this) { diff --git a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c index 9b729d260..fbea8b130 100644 --- a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c +++ b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c @@ -143,6 +143,8 @@ void EnJj_Destroy(Actor* thisx, PlayState* play) { case JABUJABU_MAIN: DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); break; case JABUJABU_COLLISION: diff --git a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c index 3248ad33f..12f443ec3 100644 --- a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -76,6 +76,8 @@ void EnJs_Destroy(Actor* thisx, PlayState* play) { EnJs* this = (EnJs*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } u8 func_80A88F64(EnJs* this, PlayState* play, u16 textId) { diff --git a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 2d2e2c6a6..10baf4b03 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -59,8 +59,7 @@ void EnKakasi_Destroy(Actor* thisx, PlayState* play) { EnKakasi* this = (EnKakasi*)thisx; Collider_DestroyCylinder(play, &this->collider); - SkelAnime_Free(&this->skelanime, play); // OTR - Fixed this memory leak - //! @bug SkelAnime_Free is not called + SkelAnime_Free(&this->skelanime, play); } void EnKakasi_Init(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c index efb05975e..a61323f38 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c @@ -109,8 +109,7 @@ void EnKakasi2_Destroy(Actor* thisx, PlayState* play) { EnKakasi2* this = (EnKakasi2*)thisx; Collider_DestroyCylinder(play, &this->collider); - SkelAnime_Free(&this->skelAnime, play); // OTR - Fixed this memory leak - //! @bug SkelAnime_Free is not called + SkelAnime_Free(&this->skelAnime, play); } void func_80A90264(EnKakasi2* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c index 95b0e405f..6d000d6fe 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c @@ -63,8 +63,7 @@ void EnKakasi3_Destroy(Actor* thisx, PlayState* play) { EnKakasi3* this = (EnKakasi3*)thisx; Collider_DestroyCylinder(play, &this->collider); - SkelAnime_Free(&this->skelAnime, play); //OTR - Fixed this memory leak - //! @bug SkelAnime_Free is not called + SkelAnime_Free(&this->skelAnime, play); } void EnKakasi3_Init(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c b/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c index de209a242..6632b949b 100644 --- a/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c +++ b/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c @@ -119,6 +119,8 @@ void EnKarebaba_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->bodyCollider); Collider_DestroyCylinder(play, &this->headCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnKarebaba_ResetCollider(EnKarebaba* this) { diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 5c8a41671..6dec44fe6 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -1145,6 +1145,8 @@ void EnKo_Init(Actor* thisx, PlayState* play) { void EnKo_Destroy(Actor* thisx, PlayState* play) { EnKo* this = (EnKo*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80A99048(EnKo* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index c9f3f6112..30a8d39b9 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -385,6 +385,8 @@ void EnKz_Destroy(Actor* thisx, PlayState* play) { EnKz* this = (EnKz*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } void EnKz_PreMweepWait(EnKz* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c index f932e9aa5..b8c7bfc19 100644 --- a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c +++ b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c @@ -336,6 +336,8 @@ void EnMb_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyTris(play, &this->frontShielding); Collider_DestroyCylinder(play, &this->hitbox); Collider_DestroyQuad(play, &this->attackCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnMb_FaceWaypoint(EnMb* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index b4b4a7b07..72ecf32be 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -699,6 +699,8 @@ void EnMd_Init(Actor* thisx, PlayState* play) { void EnMd_Destroy(Actor* thisx, PlayState* play) { EnMd* this = (EnMd*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AAB874(EnMd* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index 1ffca5429..67399b3d6 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -79,6 +79,8 @@ void EnMk_Destroy(Actor* thisx, PlayState* play) { EnMk* this = (EnMk*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AACA40(EnMk* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c index ce31cf2c7..bd5f3107a 100644 --- a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c +++ b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c @@ -198,6 +198,8 @@ void EnMm_Destroy(Actor* thisx, PlayState* play) { EnMm* this = (EnMm*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80AADA70(void) { diff --git a/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c b/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c index d48517704..f567727c5 100644 --- a/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c +++ b/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c @@ -161,6 +161,8 @@ void EnMm2_Destroy(Actor* thisx, PlayState* play) { EnMm2* this = (EnMm2*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80AAF224(EnMm2* this, PlayState* play, EnMm2ActionFunc actionFunc) { diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c index 3e0321b49..923cb5011 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -99,6 +99,8 @@ void EnMs_Destroy(Actor* thisx, PlayState* play) { EnMs* this = (EnMs*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnMs_Wait(EnMs* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c index 06dc6b868..560cb6cfa 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -147,6 +147,8 @@ void EnNb_Destroy(Actor* thisx, PlayState* play) { D_80AB4318 = 0; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AB0FBC(EnNb* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 6659350ff..e36296654 100644 --- a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -246,6 +246,8 @@ void EnNiw_Destroy(Actor* thisx, PlayState* play) { EnNiw* this = (EnNiw*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AB5BF8(EnNiw* this, PlayState* play, s16 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c index d6013fc79..db41089e8 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c @@ -93,6 +93,9 @@ void EnNiwGirl_Init(Actor* thisx, PlayState* play) { } void EnNiwGirl_Destroy(Actor* thisx, PlayState* play) { + EnNiwGirl* this = (EnNiwGirl*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnNiwGirl_Jump(EnNiwGirl* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 63522dc64..088381c70 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -96,6 +96,8 @@ void EnNiwLady_Destroy(Actor* thisx, PlayState* play) { EnNiwLady* this = (EnNiwLady*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnNiwLady_ChoseAnimation(EnNiwLady* this, PlayState* play, s32 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c index 92a49fc57..9d958d0c5 100644 --- a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c +++ b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c @@ -163,6 +163,10 @@ void EnOkuta_Destroy(Actor* thisx, PlayState* play) { EnOkuta* this = (EnOkuta*)thisx; Collider_DestroyCylinder(play, &this->collider); + + if (thisx->params == 0) { + ResourceMgr_UnregisterSkeleton(&this->skelAnime); + } } void EnOkuta_SpawnBubbles(EnOkuta* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 20c5373c1..eb7932aed 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -240,6 +240,9 @@ void EnOwl_Destroy(Actor* thisx, PlayState* play) { EnOwl* this = (EnOwl*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); + ResourceMgr_UnregisterSkeleton(&this->skelAnime2); } /** diff --git a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c index c284af550..e3c5028e5 100644 --- a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c +++ b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c @@ -124,6 +124,8 @@ void EnPartner_Destroy(Actor* thisx, PlayState* play) { LightContext_RemoveLight(play, &play->lightCtx, this->lightNodeNoGlow); Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnPartner_UpdateLights(EnPartner* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c b/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c index 318fe2b8b..ec1bcd28b 100644 --- a/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c +++ b/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c @@ -256,6 +256,8 @@ void EnPeehat_Destroy(Actor* thisx, PlayState* play) { parent->unk_2FA--; } } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnPeehat_SpawnDust(PlayState* play, EnPeehat* this, Vec3f* pos, f32 arg3, s32 arg4, f32 arg5, f32 arg6) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c b/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c index b5771c87d..8c2e6d569 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c +++ b/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c @@ -86,6 +86,8 @@ void EnPoDesert_Destroy(Actor* thisx, PlayState* play) { LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnPoDesert_SetNextPathPoint(EnPoDesert* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c index c7e8bf877..882ea5baf 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c +++ b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c @@ -188,6 +188,8 @@ void EnPoField_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->flameCollider); Collider_DestroyCylinder(play, &this->collider); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnPoField_SetupWaitForSpawn(EnPoField* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c index e271da21a..7db0fcc16 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c +++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c @@ -117,6 +117,8 @@ void EnPoRelay_Destroy(Actor* thisx, PlayState* play) { D_80AD8D24 = 0; LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnPoRelay_SetupIdle(EnPoRelay* this) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c index 77dc6cbb0..def561831 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c +++ b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c @@ -238,6 +238,8 @@ void EnPoSisters_Destroy(Actor* thisx, PlayState* play) { func_800F5B58(); } Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AD9240(EnPoSisters* this, s32 arg1, Vec3f* arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 117752a8e..dcf933967 100644 --- a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -254,6 +254,8 @@ void EnPoh_Destroy(Actor* thisx, PlayState* play) { if (this->actor.params == EN_POH_RUPEE) { D_80AE1A50--; } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80ADE114(EnPoh* this) { diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c index cde57a6bf..bccf64b30 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -175,6 +175,8 @@ void EnRd_Destroy(Actor* thisx, PlayState* play) { gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AE2630(PlayState* play, Actor* thisx, s32 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c index 9015f3407..a12149145 100644 --- a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c +++ b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c @@ -161,6 +161,8 @@ void EnReeba_Destroy(Actor* thisx, PlayState* play) { } } } + + ResourceMgr_UnregisterSkeleton(&this->skelanime); } void func_80AE4F40(EnReeba* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c index 6894a1c9c..557be5e40 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c @@ -205,6 +205,8 @@ void EnRu1_Destroy(Actor* thisx, PlayState* play) { D_80AF1938 = 0; EnRu1_DestroyColliders(this, play); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnRu1_UpdateEyes(EnRu1* this) { diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c index 697871524..7e06207f0 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c @@ -108,6 +108,8 @@ void EnRu2_Destroy(Actor* thisx, PlayState* play) { EnRu2* this = (EnRu2*)thisx; D_80AF4118 = 0; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AF2608(EnRu2* this) { diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index bb700f82b..3e1bc7fe5 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -532,6 +532,8 @@ void EnSa_Destroy(Actor* thisx, PlayState* play) { EnSa* this = (EnSa*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AF6448(EnSa* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c index 582e66a97..23a530fd7 100644 --- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c +++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c @@ -91,6 +91,8 @@ void EnShopnuts_Destroy(Actor* thisx, PlayState* play) { EnShopnuts* this = (EnShopnuts*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnShopnuts_SetupWait(EnShopnuts* this) { diff --git a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c index 185eb265f..ef88637bf 100644 --- a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c +++ b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c @@ -185,6 +185,8 @@ void EnSkb_Destroy(Actor* thisx, PlayState* play) { } } Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80AFCD60(EnSkb* this) { 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 a93e30107..a5ba6ef0a 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 @@ -464,6 +464,8 @@ void EnSkj_Destroy(Actor* thisx, PlayState* play) { EnSkj* this = (EnSkj*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnSkj_RangeCheck(Player* player, EnSkj* this) { diff --git a/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c index 3a05dbfd9..45768898c 100644 --- a/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c +++ b/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c @@ -643,6 +643,8 @@ void EnSsh_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->colCylinder[i]); } Collider_DestroyJntSph(play, &this->colSph); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnSsh_Wait(EnSsh* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_St/z_en_st.c b/soh/src/overlays/actors/ovl_En_St/z_en_st.c index c9de2bb59..66eb44abc 100644 --- a/soh/src/overlays/actors/ovl_En_St/z_en_st.c +++ b/soh/src/overlays/actors/ovl_En_St/z_en_st.c @@ -815,6 +815,8 @@ void EnSt_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->colCylinder[i]); } Collider_DestroyJntSph(play, &this->colSph); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnSt_WaitOnCeiling(EnSt* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 064de26fe..b45560a04 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -173,6 +173,8 @@ void EnSth_Destroy(Actor* thisx, PlayState* play) { EnSth* this = (EnSth*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnSth_WaitForObjectLoaded(EnSth* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c index da860cb21..7c5473055 100644 --- a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -328,6 +328,8 @@ void EnSw_Destroy(Actor* thisx, PlayState* play) { EnSw* this = (EnSw*)thisx; Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80B0C9F0(EnSw* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index d3371f345..279ac1af3 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -183,6 +183,9 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) { } void EnSyatekiMan_Destroy(Actor* thisx, PlayState* play) { + EnSyatekiMan* this = (EnSyatekiMan*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnSyatekiMan_Start(EnSyatekiMan* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c index cfbe70085..8c231a09c 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c @@ -103,6 +103,8 @@ void EnSyatekiNiw_Destroy(Actor* thisx, PlayState* play) { EnSyatekiNiw* this = (EnSyatekiNiw*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80B11A94(EnSyatekiNiw* this, PlayState* play, s16 arg2) { diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index d3fb9ddba..3fa33d6b4 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -243,6 +243,8 @@ void EnTa_Destroy(Actor* thisx, PlayState* play) { if (this->unk_2E0 & 0x200) { func_800F5B58(); } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80B142F4(EnTa* this, PlayState* play, u16 textId) { diff --git a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index 975bb3f14..8a208f104 100644 --- a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -14,6 +14,7 @@ void EnTakaraMan_Init(Actor* thisx, PlayState* play); void EnTakaraMan_Reset(Actor* thisx, PlayState* play); void EnTakaraMan_Update(Actor* thisx, PlayState* play); void EnTakaraMan_Draw(Actor* thisx, PlayState* play); +void EnTakaraMan_Destroy(Actor* thisx, PlayState* play); void func_80B176E0(EnTakaraMan* this, PlayState* play); void func_80B1778C(EnTakaraMan* this, PlayState* play); @@ -29,7 +30,7 @@ const ActorInit En_Takara_Man_InitVars = { OBJECT_TS, sizeof(EnTakaraMan), (ActorFunc)EnTakaraMan_Init, - NULL, + (ActorFunc)EnTakaraMan_Destroy, (ActorFunc)EnTakaraMan_Update, (ActorFunc)EnTakaraMan_Draw, (ActorResetFunc)EnTakaraMan_Reset, @@ -72,6 +73,12 @@ void EnTakaraMan_Init(Actor* thisx, PlayState* play) { this->actionFunc = func_80B176E0; } +void EnTakaraMan_Destroy(Actor* thisx, PlayState* play) { + EnTakaraMan* this = (EnTakaraMan*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); +} + void func_80B176E0(EnTakaraMan* this, PlayState* play) { f32 frameCount = Animation_GetLastFrame(&object_ts_Anim_000498); diff --git a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c index e30f94c48..be9033e96 100644 --- a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -321,6 +321,9 @@ void EnTest_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->shieldCollider); Collider_DestroyCylinder(play, &this->bodyCollider); Collider_DestroyQuad(play, &this->swordCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); + ResourceMgr_UnregisterSkeleton(&this->upperSkelanime); } /** diff --git a/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c index f64d81163..c4741204b 100644 --- a/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -217,6 +217,8 @@ void EnTite_Destroy(Actor* thisx, PlayState* play) { osSyncPrintf("\n\n"); } Collider_DestroyJntSph(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnTite_SetupIdle(EnTite* this) { diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 60c78d04f..5bcbe6e22 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -526,6 +526,8 @@ void EnTk_Destroy(Actor* thisx, PlayState* play) { EnTk* this = (EnTk*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnTk_Rest(EnTk* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index 7ec5db7e5..704790caf 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -138,6 +138,8 @@ void EnToryo_Destroy(Actor* thisx, PlayState* play) { EnToryo* this = (EnToryo*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 func_80B203D8(EnToryo* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c b/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c index e9b2f6db4..6cc2e90c9 100644 --- a/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c +++ b/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c @@ -120,6 +120,9 @@ void EnTr_Init(Actor* thisx, PlayState* play) { } void EnTr_Destroy(Actor* thisx, PlayState* play) { + EnTr* this = (EnTr*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnTr_CrySpellcast(EnTr* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c b/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c index 90254a29e..5ca56ead7 100644 --- a/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c +++ b/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c @@ -171,6 +171,8 @@ void EnVali_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyQuad(play, &this->leftArmCollider); Collider_DestroyQuad(play, &this->rightArmCollider); Collider_DestroyCylinder(play, &this->bodyCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnVali_SetupLurk(EnVali* this) { diff --git a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c index 2e88d20ad..4eac68129 100644 --- a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c +++ b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c @@ -162,6 +162,8 @@ void EnVm_Destroy(Actor* thisx, PlayState* play) { EnVm* this = (EnVm*)thisx; Collider_DestroyCylinder(play, &this->colliderCylinder); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnVm_SetupWait(EnVm* this) { diff --git a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 07ee9fe23..c015413db 100644 --- a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -148,6 +148,8 @@ void EnWallmas_Destroy(Actor* thisx, PlayState* play) { EnWallmas* this = (EnWallmas*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnWallmas_TimerInit(EnWallmas* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c index 31ceb7071..f7a6d3638 100644 --- a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c +++ b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c @@ -118,6 +118,8 @@ void EnWeiyer_Destroy(Actor* thisx, PlayState* play) { EnWeiyer* this = (EnWeiyer*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80B32384(EnWeiyer* this) { diff --git a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c index 6ec5e00cc..522034446 100644 --- a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -279,6 +279,8 @@ void EnWf_Destroy(Actor* thisx, PlayState* play) { osSyncPrintf("\n\n"); } } + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnWf_ChangeAction(PlayState* play, EnWf* this, s16 mustChoose) { diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 89c478cb5..83d58e069 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -74,6 +74,8 @@ void EnXc_Destroy(Actor* thisx, PlayState* play) { EnXc* this = (EnXc*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnXc_CalculateHeadTurn(EnXc* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c index eeb88ea39..254d2a757 100644 --- a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c +++ b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c @@ -364,6 +364,8 @@ void EnZf_Destroy(Actor* thisx, PlayState* play) { Effect_Delete(play, this->blureIndex); Collider_DestroyCylinder(play, &this->bodyCollider); Collider_DestroyQuad(play, &this->swordCollider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } /** diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c index a5d09cfbd..832fac222 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c @@ -84,6 +84,8 @@ void EnZl3_Destroy(Actor* thisx, PlayState* play) { EnZl3* this = (EnZl3*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void func_80B53468(void) { diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index 3d32a0524..2f6f05a63 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -422,6 +422,8 @@ void EnZl4_Destroy(Actor* thisx, PlayState* play) { EnZl4* this = (EnZl4*)thisx; Collider_DestroyCylinder(play, &this->collider); + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } s32 EnZl4_SetNextAnim(EnZl4* this, s32 nextAnim) { diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c index 885c58708..8a413d1c3 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c @@ -615,6 +615,9 @@ void EnZo_Init(Actor* thisx, PlayState* play) { } void EnZo_Destroy(Actor* thisx, PlayState* play) { + EnZo* this = (EnZo*)thisx; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); } void EnZo_Standing(EnZo* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 58147efd5..bd41af963 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -11335,6 +11335,9 @@ void Player_Destroy(Actor* thisx, PlayState* play) { func_800876C8(play); gSaveContext.linkAge = play->linkAgeOnLoad; + + ResourceMgr_UnregisterSkeleton(&this->skelAnime); + ResourceMgr_UnregisterSkeleton(&this->skelAnime2); } //first person manipulate player actor From f34df2f064ec086d271bfaaa86dd4509e48be5a1 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 22 May 2023 09:33:31 -0400 Subject: [PATCH 11/13] remove what i assume to be accidentally copied stuff from a diff (#2909) --- soh/soh/Enhancements/controls/GameControlEditor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp index 719edaf0e..5b2d42902 100644 --- a/soh/soh/Enhancements/controls/GameControlEditor.cpp +++ b/soh/soh/Enhancements/controls/GameControlEditor.cpp @@ -267,10 +267,10 @@ namespace GameControlEditor { UIWidgets::PaddedEnhancementCheckbox("Invert Camera Y Axis", "gInvertYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); DrawHelpIcon("Inverts the Camera Y Axis in:\n-Free camera"); UIWidgets::Spacer(0); -+ UIWidgets::PaddedEnhancementSliderFloat("Third-Person Horizontal Sensitivity: %d %%", "##ThirdPersonSensitivity Horizontal", -+ "gThirdPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true, true, false, true); -+ UIWidgets::PaddedEnhancementSliderFloat("Third-Person Vertical Sensitivity: %d %%", "##ThirdPersonSensitivity Vertical", -+ "gThirdPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderFloat("Third-Person Horizontal Sensitivity: %d %%", "##ThirdPersonSensitivity Horizontal", + "gThirdPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderFloat("Third-Person Vertical Sensitivity: %d %%", "##ThirdPersonSensitivity Vertical", + "gThirdPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true, true, false, true); UIWidgets::PaddedEnhancementSliderInt("Camera Distance: %d", "##CamDist", "gFreeCameraDistMax", 100, 900, "", 185, true, false, true); UIWidgets::PaddedEnhancementSliderInt("Camera Transition Speed: %d", "##CamTranSpeed", From dddd3b14aa350ae61589a918c5b4288fa8e299de Mon Sep 17 00:00:00 2001 From: aMannus Date: Mon, 22 May 2023 16:56:44 +0200 Subject: [PATCH 12/13] Add back missing Greg timestamp (#2911) --- soh/soh/Enhancements/gameplaystats.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 5d60964bd..889b22ee0 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -618,6 +618,7 @@ void SetupDisplayNames() { strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_TWINROVA], "Twinrova Defeated: "); strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANONDORF], "Ganondorf Defeated: "); strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: "); } void SetupDisplayColors() { From e88adbe672e086cdd2911624729faa536f975f9f Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Mon, 22 May 2023 21:34:18 -0400 Subject: [PATCH 13/13] Version Bump (#2916) --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 698810a73..abb8d5fdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 7.0.1 LANGUAGES C CXX) -set(PROJECT_BUILD_NAME "Spock Bravo" CACHE STRING "") +project(Ship VERSION 7.0.2 LANGUAGES C CXX) +set(PROJECT_BUILD_NAME "Spock Charlie" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)