[Custom equipment] fix fallback (#6113)
This commit is contained in:
@@ -17,14 +17,15 @@ void DummyPlayer_Update(Actor* actor, PlayState* play);
|
|||||||
|
|
||||||
static void UpdatePatchCustomEquipmentDlists();
|
static void UpdatePatchCustomEquipmentDlists();
|
||||||
static void RefreshCustomEquipment();
|
static void RefreshCustomEquipment();
|
||||||
static bool HasDummyPlayers();
|
static u8 GetEquippedSwordItem();
|
||||||
|
static bool IsDummyPlayer(const Player* player);
|
||||||
|
|
||||||
static const char* ResolveCustomChain(std::initializer_list<const char*> paths) {
|
static const char* ResolveCustomChain(std::initializer_list<const char*> paths) {
|
||||||
const char* fallback = nullptr;
|
const char* fallback = nullptr;
|
||||||
for (auto path : paths) {
|
for (auto path : paths) {
|
||||||
if (path != nullptr) {
|
if (path != nullptr) {
|
||||||
fallback = path;
|
fallback = path;
|
||||||
if (ResourceMgr_FileExists(path)) {
|
if (ResourceMgr_FileExists(path) || ResourceGetIsCustomByName(path)) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +58,7 @@ static const char* GetBrokenLongswordInSheathDL() {
|
|||||||
static void UpdateCustomEquipmentSetModel(Player* player, u8 ModelGroup) {
|
static void UpdateCustomEquipmentSetModel(Player* player, u8 ModelGroup) {
|
||||||
(void)ModelGroup;
|
(void)ModelGroup;
|
||||||
|
|
||||||
if (player == nullptr || gPlayState == nullptr || player != GET_PLAYER(gPlayState)) {
|
if (player == nullptr || gPlayState == nullptr || player != GET_PLAYER(gPlayState) || IsDummyPlayer(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +71,7 @@ static void UpdateCustomEquipment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (player == nullptr || player->actor.update == DummyPlayer_Update) {
|
if (player == nullptr || IsDummyPlayer(player)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool altAssetsRuntime = ResourceMgr_IsAltAssetsEnabled();
|
|
||||||
|
|
||||||
// If multiplayer dummy actors are present, skip patching shared resources to avoid corrupting them.
|
|
||||||
if (HasDummyPlayers() && altAssetsRuntime) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,18 +92,35 @@ static void RefreshCustomEquipment() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool hasDummyPlayers = HasDummyPlayers();
|
if (IsDummyPlayer(GET_PLAYER(gPlayState))) {
|
||||||
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) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePatchCustomEquipmentDlists();
|
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,
|
void PatchOrUnpatch(const char* resource, const char* gfx, const char* dlist1, const char* dlist2, const char* dlist3,
|
||||||
const char* alternateDL) {
|
const char* alternateDL) {
|
||||||
if (resource == NULL || gfx == NULL || dlist1 == NULL || dlist2 == NULL) {
|
if (resource == NULL || gfx == NULL || dlist1 == NULL || dlist2 == NULL) {
|
||||||
@@ -254,6 +265,9 @@ static void ApplyMasterSwordPatches() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ApplyBiggoronSwordPatches() {
|
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) {
|
if (gPlayState != nullptr && GET_PLAYER(gPlayState)->sheathType == PLAYER_MODELTYPE_SHEATH_19) {
|
||||||
PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, gCustomLongswordSheathDL, "customDekuShieldBack1",
|
PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, gCustomLongswordSheathDL, "customDekuShieldBack1",
|
||||||
"customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL);
|
"customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL);
|
||||||
@@ -268,7 +282,7 @@ static void ApplyBiggoronSwordPatches() {
|
|||||||
{ gLinkChildDekuShieldAndSheathNearDL, gCustomLongswordSheathDL, "customDekuShieldSheath1",
|
{ gLinkChildDekuShieldAndSheathNearDL, gCustomLongswordSheathDL, "customDekuShieldSheath1",
|
||||||
"customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL },
|
"customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL },
|
||||||
{ gLinkAdultLeftHandHoldingBgsNearDL, gCustomLongswordDL, "customBGS1", "customBGS2", "customBGS3",
|
{ gLinkAdultLeftHandHoldingBgsNearDL, gCustomLongswordDL, "customBGS1", "customBGS2", "customBGS3",
|
||||||
gLinkAdultLeftHandClosedNearDL },
|
leftHandClosed },
|
||||||
{ gLinkAdultMasterSwordAndSheathNearDL, gCustomLongswordInSheathDL, "customMasterSwordSheath1",
|
{ gLinkAdultMasterSwordAndSheathNearDL, gCustomLongswordInSheathDL, "customMasterSwordSheath1",
|
||||||
"customMasterSwordSheath2", nullptr, nullptr },
|
"customMasterSwordSheath2", nullptr, nullptr },
|
||||||
{ gLinkChildSheathNearDL, gCustomLongswordSheathDL, "customKokiriSheath1", "customKokiriSheath2", nullptr,
|
{ gLinkChildSheathNearDL, gCustomLongswordSheathDL, "customKokiriSheath1", "customKokiriSheath2", nullptr,
|
||||||
@@ -292,6 +306,9 @@ static void ApplyBiggoronSwordPatches() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ApplyBreakableLongswordPatches() {
|
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) {
|
if (gPlayState != nullptr && GET_PLAYER(gPlayState)->sheathType == PLAYER_MODELTYPE_SHEATH_19) {
|
||||||
PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, GetBreakableLongswordSheathDL(), "customDekuShieldBack1",
|
PatchOrUnpatch(gLinkChildDekuShieldWithMatrixDL, GetBreakableLongswordSheathDL(), "customDekuShieldBack1",
|
||||||
"customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL);
|
"customDekuShieldBack2", "customDekuShieldBack2", gCustomDekuShieldOnBackDL);
|
||||||
@@ -306,7 +323,7 @@ static void ApplyBreakableLongswordPatches() {
|
|||||||
{ gLinkChildDekuShieldAndSheathNearDL, GetBreakableLongswordSheathDL(), "customDekuShieldSheath1",
|
{ gLinkChildDekuShieldAndSheathNearDL, GetBreakableLongswordSheathDL(), "customDekuShieldSheath1",
|
||||||
"customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL },
|
"customDekuShieldSheath2", "customDekuShieldSheath3", gCustomDekuShieldOnBackDL },
|
||||||
{ gLinkAdultLeftHandHoldingBgsNearDL, GetBreakableLongswordDL(), "customGK1", "customGK2", "customGK3",
|
{ gLinkAdultLeftHandHoldingBgsNearDL, GetBreakableLongswordDL(), "customGK1", "customGK2", "customGK3",
|
||||||
gLinkAdultLeftHandClosedNearDL },
|
leftHandClosed },
|
||||||
{ gLinkAdultMasterSwordAndSheathNearDL, GetBreakableLongswordInSheathDL(), "customMasterSwordSheath1",
|
{ gLinkAdultMasterSwordAndSheathNearDL, GetBreakableLongswordInSheathDL(), "customMasterSwordSheath1",
|
||||||
"customMasterSwordSheath2", nullptr, nullptr },
|
"customMasterSwordSheath2", nullptr, nullptr },
|
||||||
{ gLinkChildSheathNearDL, GetBreakableLongswordSheathDL(), "customKokiriSheath1", "customKokiriSheath2",
|
{ gLinkChildSheathNearDL, GetBreakableLongswordSheathDL(), "customKokiriSheath1", "customKokiriSheath2",
|
||||||
@@ -457,34 +474,10 @@ static void ApplyCommonEquipmentPatches() {
|
|||||||
{ gLinkChildRightArmStretchedSlingshotDL, gCustomSlingshotDL, "customSlingshotFPS1", "customSlingshotFPS2",
|
{ gLinkChildRightArmStretchedSlingshotDL, gCustomSlingshotDL, "customSlingshotFPS1", "customSlingshotFPS2",
|
||||||
"customSlingshotFPS3", fpsHand },
|
"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() {
|
void UpdatePatchCustomEquipmentDlists() {
|
||||||
const u8 equippedSword = gSaveContext.equips.buttonItems[0];
|
const u8 equippedSword = GetEquippedSwordItem();
|
||||||
|
|
||||||
if (equippedSword == ITEM_NONE) {
|
if (equippedSword == ITEM_NONE) {
|
||||||
if (LINK_IS_CHILD) {
|
if (LINK_IS_CHILD) {
|
||||||
@@ -518,19 +511,3 @@ void UpdatePatchCustomEquipmentDlists() {
|
|||||||
|
|
||||||
ApplyCommonEquipmentPatches();
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user