diff --git a/soh/soh/Enhancements/customequipment.cpp b/soh/soh/Enhancements/customequipment.cpp index 9834836fbc8..1ce4c79048e 100644 --- a/soh/soh/Enhancements/customequipment.cpp +++ b/soh/soh/Enhancements/customequipment.cpp @@ -17,14 +17,15 @@ void DummyPlayer_Update(Actor* actor, PlayState* play); static void UpdatePatchCustomEquipmentDlists(); static void RefreshCustomEquipment(); -static bool HasDummyPlayers(); +static u8 GetEquippedSwordItem(); +static bool IsDummyPlayer(const Player* player); static const char* ResolveCustomChain(std::initializer_list paths) { const char* fallback = nullptr; for (auto path : paths) { if (path != nullptr) { fallback = path; - if (ResourceMgr_FileExists(path)) { + if (ResourceMgr_FileExists(path) || ResourceGetIsCustomByName(path)) { return path; } } @@ -57,7 +58,7 @@ static const char* GetBrokenLongswordInSheathDL() { static void UpdateCustomEquipmentSetModel(Player* player, u8 ModelGroup) { (void)ModelGroup; - if (player == nullptr || gPlayState == nullptr || player != GET_PLAYER(gPlayState)) { + if (player == nullptr || gPlayState == nullptr || player != GET_PLAYER(gPlayState) || IsDummyPlayer(player)) { return; } @@ -70,14 +71,7 @@ static void UpdateCustomEquipment() { } Player* player = GET_PLAYER(gPlayState); - if (player == nullptr || player->actor.update == DummyPlayer_Update) { - return; - } - - const bool altAssetsRuntime = ResourceMgr_IsAltAssetsEnabled(); - - // If multiplayer dummy actors are present, skip patching shared resources to avoid corrupting them. - if (HasDummyPlayers() && altAssetsRuntime) { + if (player == nullptr || IsDummyPlayer(player)) { return; } @@ -98,18 +92,35 @@ static void RefreshCustomEquipment() { return; } - const bool hasDummyPlayers = HasDummyPlayers(); - const bool altAssetsRuntime = ResourceMgr_IsAltAssetsEnabled(); - - // Keep custom patches off dummy players, but still allow unpatching when alt assets are disabled so we can - // restore vanilla display lists. - if (hasDummyPlayers && altAssetsRuntime) { + if (IsDummyPlayer(GET_PLAYER(gPlayState))) { return; } UpdatePatchCustomEquipmentDlists(); } +static u8 GetEquippedSwordItem() { + switch (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD)) { + case EQUIP_VALUE_SWORD_NONE: + return ITEM_NONE; + case EQUIP_VALUE_SWORD_KOKIRI: + return ITEM_SWORD_KOKIRI; + case EQUIP_VALUE_SWORD_MASTER: + return ITEM_SWORD_MASTER; + case EQUIP_VALUE_SWORD_BIGGORON: + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { + return ITEM_SWORD_KNIFE; + } + return ITEM_SWORD_BGS; + default: + return ITEM_NONE; + } +} + +static bool IsDummyPlayer(const Player* player) { + return player != nullptr && player->actor.update == DummyPlayer_Update; +} + void PatchOrUnpatch(const char* resource, const char* gfx, const char* dlist1, const char* dlist2, const char* dlist3, const char* alternateDL) { if (resource == NULL || gfx == NULL || dlist1 == NULL || dlist2 == NULL) { @@ -254,6 +265,9 @@ static void ApplyMasterSwordPatches() { } static void ApplyBiggoronSwordPatches() { + const bool isChild = LINK_IS_CHILD; + const char* leftHandClosed = isChild ? gLinkChildLeftFistNearDL : gLinkAdultLeftHandClosedNearDL; + if (gPlayState != nullptr && GET_PLAYER(gPlayState)->sheathType == PLAYER_MODELTYPE_SHEATH_19) { PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, gCustomLongswordSheathDL, "customDekuShieldBack1", "customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL); @@ -268,7 +282,7 @@ static void ApplyBiggoronSwordPatches() { { gLinkChildDekuShieldAndSheathNearDL, gCustomLongswordSheathDL, "customDekuShieldSheath1", "customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL }, { gLinkAdultLeftHandHoldingBgsNearDL, gCustomLongswordDL, "customBGS1", "customBGS2", "customBGS3", - gLinkAdultLeftHandClosedNearDL }, + leftHandClosed }, { gLinkAdultMasterSwordAndSheathNearDL, gCustomLongswordInSheathDL, "customMasterSwordSheath1", "customMasterSwordSheath2", nullptr, nullptr }, { gLinkChildSheathNearDL, gCustomLongswordSheathDL, "customKokiriSheath1", "customKokiriSheath2", nullptr, @@ -292,6 +306,9 @@ static void ApplyBiggoronSwordPatches() { } static void ApplyBreakableLongswordPatches() { + const bool isChild = LINK_IS_CHILD; + const char* leftHandClosed = isChild ? gLinkChildLeftFistNearDL : gLinkAdultLeftHandClosedNearDL; + if (gPlayState != nullptr && GET_PLAYER(gPlayState)->sheathType == PLAYER_MODELTYPE_SHEATH_19) { PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, GetBreakableLongswordSheathDL(), "customDekuShieldBack1", "customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL); @@ -306,7 +323,7 @@ static void ApplyBreakableLongswordPatches() { { gLinkChildDekuShieldAndSheathNearDL, GetBreakableLongswordSheathDL(), "customDekuShieldSheath1", "customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL }, { gLinkAdultLeftHandHoldingBgsNearDL, GetBreakableLongswordDL(), "customGK1", "customGK2", "customGK3", - gLinkAdultLeftHandClosedNearDL }, + leftHandClosed }, { gLinkAdultMasterSwordAndSheathNearDL, GetBreakableLongswordInSheathDL(), "customMasterSwordSheath1", "customMasterSwordSheath2", nullptr, nullptr }, { gLinkChildSheathNearDL, GetBreakableLongswordSheathDL(), "customKokiriSheath1", "customKokiriSheath2", @@ -457,34 +474,10 @@ static void ApplyCommonEquipmentPatches() { { gLinkChildRightArmStretchedSlingshotDL, gCustomSlingshotDL, "customSlingshotFPS1", "customSlingshotFPS2", "customSlingshotFPS3", fpsHand }, }); - - const bool equipmentAlwaysVisible = CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0) != 0; - - if (LINK_IS_CHILD && equipmentAlwaysVisible) { - ApplyPatchEntries({ - { gCustomAdultFPSHandDL, gCustomChildFPSHandDL, "patchChildFPSHand1", "patchChildFPSHand2", nullptr, - nullptr }, - { gLinkAdultRightHandClosedNearDL, gLinkChildRightHandClosedNearDL, "customChildRightHand1", - "customChildRightHand2", nullptr, nullptr }, - { gLinkAdultLeftHandClosedNearDL, gLinkChildLeftFistNearDL, "customChildLeftHand1", "customChildLeftHand2", - nullptr, nullptr }, - }); - } - - if (LINK_IS_ADULT && equipmentAlwaysVisible) { - ApplyPatchEntries({ - { gCustomChildFPSHandDL, gCustomAdultFPSHandDL, "patchAdultFPSHand1", "patchAdultFPSHand2", nullptr, - nullptr }, - { gLinkChildRightHandClosedNearDL, gLinkAdultRightHandClosedNearDL, "customAdultRightHand1", - "customAdultRightHand2", nullptr, nullptr }, - { gLinkChildLeftFistNearDL, gLinkAdultLeftHandClosedNearDL, "customAdultLeftHand1", "customAdultLeftHand2", - nullptr, nullptr }, - }); - } } void UpdatePatchCustomEquipmentDlists() { - const u8 equippedSword = gSaveContext.equips.buttonItems[0]; + const u8 equippedSword = GetEquippedSwordItem(); if (equippedSword == ITEM_NONE) { if (LINK_IS_CHILD) { @@ -518,19 +511,3 @@ void UpdatePatchCustomEquipmentDlists() { ApplyCommonEquipmentPatches(); } - -static bool HasDummyPlayers() { - if (gPlayState == nullptr) { - return false; - } - - Actor* actor = gPlayState->actorCtx.actorLists[ACTORCAT_NPC].head; - while (actor != nullptr) { - if (actor->id == ACTOR_EN_OE2 && actor->update == DummyPlayer_Update) { - return true; - } - actor = actor->next; - } - - return false; -}