diff --git a/soh/soh/resource/type/Skeleton.cpp b/soh/soh/resource/type/Skeleton.cpp index f2541dd06..d28c59812 100644 --- a/soh/soh/resource/type/Skeleton.cpp +++ b/soh/soh/resource/type/Skeleton.cpp @@ -5,6 +5,14 @@ #include #include #include +#include "macros.h" + +extern "C" { +#include "variables.h" +#include "z64.h" +#include "z64player.h" +extern PlayState* gPlayState; +} extern "C" SaveContext gSaveContext; extern "C" u16 gEquipMasks[4]; @@ -30,12 +38,32 @@ size_t Skeleton::GetPointerSize() { std::vector SkeletonPatcher::skeletons; +bool SkeletonPatcher::IsLinkSkeletonPath(const std::string& path) { + return (sOtr + path == std::string(gLinkAdultSkel)) || (sOtr + path == std::string(gLinkChildSkel)); +} + +bool SkeletonPatcher::IsLocalPlayerSkelAnime(SkelAnime* skelAnime) { + if (gPlayState == nullptr) { + return false; + } + + Player* player = GET_PLAYER(gPlayState); + + if (player == nullptr) { + return false; + } + + PauseContext* pauseCtx = &gPlayState->pauseCtx; + + return (skelAnime == &player->skelAnime) || (skelAnime == &player->upperSkelAnime) || + (skelAnime == &pauseCtx->playerSkelAnime); +} + void SkeletonPatcher::RegisterSkeleton(std::string& path, SkelAnime* skelAnime) { SkeletonPatchInfo info; info.skelAnime = skelAnime; - - static const std::string sOtr = "__OTR__"; + info.isLocalPlayer = false; if (path.starts_with(sOtr)) { path = path.substr(sOtr.length()); @@ -49,6 +77,15 @@ void SkeletonPatcher::RegisterSkeleton(std::string& path, SkelAnime* skelAnime) info.vanillaSkeletonPath = path; } + if (IsLinkSkeletonPath(info.vanillaSkeletonPath)) { + info.isLocalPlayer = IsLocalPlayerSkelAnime(skelAnime); + + // Skip registering skeletons that do not belong to the local player (e.g. Anchor dummy actors) + if (!info.isLocalPlayer) { + return; + } + } + skeletons.push_back(info); } @@ -88,6 +125,10 @@ void SkeletonPatcher::UpdateSkeletons() { void SkeletonPatcher::UpdateCustomSkeletons() { for (auto skel : skeletons) { + if (!skel.isLocalPlayer) { + continue; + } + UpdateTunicSkeletons(skel); } } diff --git a/soh/soh/resource/type/Skeleton.h b/soh/soh/resource/type/Skeleton.h index c3fd6f181..3ae5d743f 100644 --- a/soh/soh/resource/type/Skeleton.h +++ b/soh/soh/resource/type/Skeleton.h @@ -78,6 +78,7 @@ class Skeleton : public Ship::Resource { struct SkeletonPatchInfo { SkelAnime* skelAnime; std::string vanillaSkeletonPath; + bool isLocalPlayer; }; class SkeletonPatcher { @@ -92,8 +93,10 @@ class SkeletonPatcher { private: inline static const std::string sOtr = "__OTR__"; + static bool IsLinkSkeletonPath(const std::string& path); + static bool IsLocalPlayerSkelAnime(SkelAnime* skelAnime); static void UpdateTunicSkeletons(SkeletonPatchInfo& skel); static void UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel); }; -} // namespace SOH \ No newline at end of file +} // namespace SOH