diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 6a6959038..ffc128bcd 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -328,7 +328,7 @@ endif() include(FetchContent) FetchContent_Declare( Boost - URL https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.gz + URL https://sourceforge.net/projects/boost/files/boost/1.81.0/boost_1_81_0.tar.gz URL_HASH SHA256=205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6 SOURCE_SUBDIR "null" # Set to a nonexistent directory so boost is not built (we don't need to build it) DOWNLOAD_EXTRACT_TIMESTAMP false # supress timestamp warning, not needed since the url wont change diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 73b5166e2..e5f4b826d 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -132,16 +132,6 @@ typedef enum { /* 0x40 */ PLAYER_IA_MASK_GERUDO, /* 0x41 */ PLAYER_IA_MASK_TRUTH, /* 0x42 */ PLAYER_IA_LENS_OF_TRUTH, - // Upstream TODO: Document why these entries were added - /* 0x43 */ PLAYER_IA_SHIELD_DEKU, - /* 0x44 */ PLAYER_IA_SHIELD_HYLIAN, - /* 0x45 */ PLAYER_IA_SHIELD_MIRROR, - /* 0x46 */ PLAYER_IA_TUNIC_KOKIRI, - /* 0x47 */ PLAYER_IA_TUNIC_GORON, - /* 0x48 */ PLAYER_IA_TUNIC_ZORA, - /* 0x49 */ PLAYER_IA_BOOTS_KOKIRI, - /* 0x4A */ PLAYER_IA_BOOTS_IRON, - /* 0x4B */ PLAYER_IA_BOOTS_HOVER, /* 0x4C */ PLAYER_IA_MAX } PlayerItemAction; diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 6058bf274..798b11d97 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -111,8 +111,9 @@ std::map> checksByArea; bool areasFullyChecked[RCAREA_INVALID]; u32 areasSpoiled = 0; bool showVOrMQ; -s8 areaChecksGotten[32]; //| "Kokiri Forest (4/9)" -bool optCollapseAll; // A bool that will collapse all checks once +s8 areaChecksGotten[RCAREA_INVALID]; //| "Kokiri Forest (4/9)" +s8 areaCheckTotals[RCAREA_INVALID]; +bool optCollapseAll; // A bool that will collapse all checks once bool optExpandAll; // A bool that will expand all checks once RandomizerCheck lastLocationChecked = RC_UNKNOWN_CHECK; RandomizerCheckArea previousArea = RCAREA_INVALID; @@ -230,13 +231,35 @@ void TrySetAreas() { } } +void RecalculateAreaTotals() { + for (auto [rcArea, checks] : checksByArea) { + if (rcArea == RCAREA_INVALID) { + return; + } + areaChecksGotten[rcArea] = 0; + areaCheckTotals[rcArea] = 0; + for (auto rc : checks) { + if (!IsVisibleInCheckTracker(rc)) { + continue; + } + areaCheckTotals[rcArea]++; + if (gSaveContext.checkTrackerData[rc].skipped || gSaveContext.checkTrackerData[rc].status == RCSHOW_COLLECTED + || gSaveContext.checkTrackerData[rc].status == RCSHOW_SAVED) { + areaChecksGotten[rcArea]++; + } + } + } +} + void SetCheckCollected(RandomizerCheck rc) { gSaveContext.checkTrackerData[rc].status = RCSHOW_COLLECTED; Rando::Location* loc = Rando::StaticData::GetLocation(rc); - if (!gSaveContext.checkTrackerData[rc].skipped) { - areaChecksGotten[loc->GetArea()]++; - } else { - gSaveContext.checkTrackerData[rc].skipped = false; + if (IsVisibleInCheckTracker(rc)) { + if (!gSaveContext.checkTrackerData[rc].skipped) { + areaChecksGotten[loc->GetArea()]++; + } else { + gSaveContext.checkTrackerData[rc].skipped = false; + } } SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); @@ -346,6 +369,7 @@ void ClearAreaChecksAndTotals() { for (auto& [rcArea, vec] : checksByArea) { vec.clear(); areaChecksGotten[rcArea] = 0; + areaCheckTotals[rcArea] = 0; } } @@ -427,8 +451,9 @@ void CheckTrackerLoadGame(int32_t fileNum) { RandomizerCheck rc = entry.GetRandomizerCheck(); RandomizerCheckTrackerData rcTrackerData = gSaveContext.checkTrackerData[rc]; if (rc == RC_UNKNOWN_CHECK || rc == RC_MAX || rc == RC_LINKS_POCKET || - !Rando::StaticData::GetLocation(rc) != RC_UNKNOWN_CHECK) + !Rando::StaticData::GetLocation(rc) != RC_UNKNOWN_CHECK) { continue; + } Rando::Location* entry2; if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) { @@ -438,8 +463,11 @@ void CheckTrackerLoadGame(int32_t fileNum) { } checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck()); - if (rcTrackerData.status == RCSHOW_SAVED || rcTrackerData.skipped) { - areaChecksGotten[entry2->GetArea()]++; + if (IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) { + areaCheckTotals[entry2->GetArea()]++; + if (rcTrackerData.status == RCSHOW_SAVED || rcTrackerData.skipped) { + areaChecksGotten[entry2->GetArea()]++; + } } if (areaChecksGotten[entry2->GetArea()] != 0 || RandomizerCheckObjects::AreaIsOverworld(entry2->GetArea())) { @@ -463,6 +491,7 @@ void CheckTrackerLoadGame(int32_t fileNum) { checksByArea.find(startingArea)->second.push_back(RC_LINKS_POCKET); areaChecksGotten[startingArea]++; + areaCheckTotals[startingArea]++; } showVOrMQ = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_RANDOM_NUMBER || @@ -514,10 +543,6 @@ void CheckTrackerTransition(uint32_t sceneNum) { } void CheckTrackerFrame() { - if (IS_RANDO) { - hideShopRightChecks = CVarGetInteger("gCheckTrackerOptionHideRightShopChecks", 1); - alwaysShowGS = CVarGetInteger("gCheckTrackerOptionAlwaysShowGSLocs", 0); - } if (!GameInteractor::IsSaveLoaded()) { return; } @@ -788,9 +813,13 @@ void Teardown() { void UpdateCheck(uint32_t check, RandomizerCheckTrackerData data) { auto area = Rando::StaticData::GetLocation(static_cast(check))->GetArea(); - if (!gSaveContext.checkTrackerData[check].skipped && data.skipped) { + if ((!gSaveContext.checkTrackerData[check].skipped && data.skipped) || + ((gSaveContext.checkTrackerData[check].status != RCSHOW_COLLECTED && gSaveContext.checkTrackerData[check].status != RCSHOW_SAVED) && + (data.status == RCSHOW_COLLECTED || data.status == RCSHOW_SAVED))) { areaChecksGotten[area]++; - } else if (gSaveContext.checkTrackerData[check].skipped && !data.skipped) { + } else if ((gSaveContext.checkTrackerData[check].skipped && !data.skipped) || + ((gSaveContext.checkTrackerData[check].status == RCSHOW_COLLECTED || gSaveContext.checkTrackerData[check].status == RCSHOW_SAVED) && + (data.status != RCSHOW_COLLECTED && data.status != RCSHOW_SAVED))) { areaChecksGotten[area]--; } gSaveContext.checkTrackerData[check] = data; @@ -903,8 +932,7 @@ void CheckTrackerWindow::DrawElement() { for (auto& [rcArea, checks] : checksByArea) { RandomizerCheckArea thisArea = currentArea; - const int areaChecksTotal = static_cast(checks.size()); - thisAreaFullyChecked = (areaChecksGotten[rcArea] == areaChecksTotal); + thisAreaFullyChecked = (areaChecksGotten[rcArea] == areaCheckTotals[rcArea]); //Last Area needs to be cleaned up if (lastArea != RCAREA_INVALID && doDraw) { UIWidgets::PaddedSeparator(); @@ -941,10 +969,11 @@ void CheckTrackerWindow::DrawElement() { stemp = RandomizerCheckObjects::GetRCAreaName(rcArea) + "##TreeNode"; ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(mainColor.r / 255.0f, mainColor.g / 255.0f, mainColor.b / 255.0f, mainColor.a / 255.0f)); - if (doingCollapseOrExpand) + if (doingCollapseOrExpand) { ImGui::SetNextItemOpen(collapseLogic, ImGuiCond_Always); - else + } else { ImGui::SetNextItemOpen(!thisAreaFullyChecked, ImGuiCond_Once); + } doDraw = ImGui::TreeNode(stemp.c_str()); ImGui::PopStyleColor(); ImGui::SameLine(); @@ -960,11 +989,11 @@ void CheckTrackerWindow::DrawElement() { if (isThisAreaSpoiled) { if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { if (OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea))->IsMQ()) - ImGui::Text("(%d/%d) - MQ", areaChecksGotten[rcArea], areaChecksTotal); + ImGui::Text("(%d/%d) - MQ", areaChecksGotten[rcArea], areaCheckTotals[rcArea]); else - ImGui::Text("(%d/%d) - Vanilla", areaChecksGotten[rcArea], areaChecksTotal); + ImGui::Text("(%d/%d) - Vanilla", areaChecksGotten[rcArea], areaCheckTotals[rcArea]); } else { - ImGui::Text("(%d/%d)", areaChecksGotten[rcArea], areaChecksTotal); + ImGui::Text("(%d/%d)", areaChecksGotten[rcArea], areaCheckTotals[rcArea]); } } else { ImGui::Text("???"); @@ -978,11 +1007,13 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = false; } for (auto rc : checks) { - if (doDraw && isThisAreaSpoiled && IsVisibleInCheckTracker(rc)) + if (doDraw && isThisAreaSpoiled && IsVisibleInCheckTracker(rc)) { DrawLocation(rc); + } } - if (doDraw) + if (doDraw) { ImGui::TreePop(); + } } areaMask <<= 1; } @@ -1207,8 +1238,9 @@ void UpdateAreaFullyChecked(RandomizerCheckArea area) { void UpdateAreas(RandomizerCheckArea area) { areasFullyChecked[area] = areaChecksGotten[area] == checksByArea.find(area)->second.size(); - if (areaChecksGotten[area] != 0 || RandomizerCheckObjects::AreaIsOverworld(area)) + if (areaChecksGotten[area] != 0 || RandomizerCheckObjects::AreaIsOverworld(area)) { areasSpoiled |= (1 << area); + } } void UpdateAllOrdering() { @@ -1238,30 +1270,36 @@ bool CompareChecks(RandomizerCheck i, RandomizerCheck j) { bool iSaved = iShow.status == RCSHOW_SAVED; bool jCollected = jShow.status == RCSHOW_COLLECTED || jShow.status == RCSHOW_SAVED; bool jSaved = jShow.status == RCSHOW_SAVED; - if (!iCollected && jCollected) - return true; - else if (iCollected && !jCollected) - return false; - if (!iSaved && jSaved) + if (!iCollected && jCollected) { return true; - else if (iSaved && !jSaved) + } else if (iCollected && !jCollected) { return false; + } - if (!iShow.skipped && jShow.skipped) + if (!iSaved && jSaved) { return true; - else if (iShow.skipped && !jShow.skipped) + } else if (iSaved && !jSaved) { return false; + } - if (!IsEoDCheck(x->GetRCType()) && IsEoDCheck(y->GetRCType())) + if (!iShow.skipped && jShow.skipped) { return true; - else if (IsEoDCheck(x->GetRCType()) && !IsEoDCheck(y->GetRCType())) + } else if (iShow.skipped && !jShow.skipped) { return false; + } - if (x->GetRandomizerCheck() < y->GetRandomizerCheck()) + if (!IsEoDCheck(x->GetRCType()) && IsEoDCheck(y->GetRCType())) { return true; - else if (x->GetRandomizerCheck() > y->GetRandomizerCheck()) + } else if (IsEoDCheck(x->GetRCType()) && !IsEoDCheck(y->GetRCType())) { return false; + } + + if (i < j) { + return true; + } else if (i > j) { + return false; + } return false; } @@ -1281,48 +1319,54 @@ void DrawLocation(RandomizerCheck rc) { RandomizerCheckStatus status = checkData.status; bool skipped = checkData.skipped; if (status == RCSHOW_COLLECTED) { - if (!showHidden && CVarGetInteger("gCheckTrackerCollectedHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerCollectedHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerCollectedExtraColor", Color_Collected_Extra_Default) : CVarGetColor("gCheckTrackerCollectedMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerCollectedExtraColor", Color_Collected_Extra_Default); } else if (status == RCSHOW_SAVED) { - if (!showHidden && CVarGetInteger("gCheckTrackerSavedHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerSavedHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerSavedExtraColor", Color_Saved_Extra_Default) : CVarGetColor("gCheckTrackerSavedMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerSavedExtraColor", Color_Saved_Extra_Default); } else if (skipped) { - if (!showHidden && CVarGetInteger("gCheckTrackerSkippedHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerSkippedHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerSkippedExtraColor", Color_Skipped_Extra_Default) : CVarGetColor("gCheckTrackerSkippedMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerSkippedExtraColor", Color_Skipped_Extra_Default); } else if (status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED) { - if (!showHidden && CVarGetInteger("gCheckTrackerSeenHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerSeenHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerSeenExtraColor", Color_Seen_Extra_Default) : CVarGetColor("gCheckTrackerSeenMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerSeenExtraColor", Color_Seen_Extra_Default); } else if (status == RCSHOW_SCUMMED) { - if (!showHidden && CVarGetInteger("gCheckTrackerKnownHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerKnownHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerScummedExtraColor", Color_Scummed_Extra_Default) : CVarGetColor("gCheckTrackerScummedMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerScummedExtraColor", Color_Scummed_Extra_Default); } else if (status == RCSHOW_UNCHECKED) { - if (!showHidden && CVarGetInteger("gCheckTrackerUncheckedHide", 0)) + if (!showHidden && CVarGetInteger("gCheckTrackerUncheckedHide", 0)) { return; + } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO ? CVarGetColor("gCheckTrackerUncheckedExtraColor", Color_Unchecked_Extra_Default) @@ -1332,8 +1376,9 @@ void DrawLocation(RandomizerCheck rc) { //Main Text txt = loc->GetShortName(); - if (lastLocationChecked == loc->GetRandomizerCheck()) + if (lastLocationChecked == loc->GetRandomizerCheck()) { txt = "* " + txt; + } // Draw button - for Skipped/Seen/Scummed/Unchecked only if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED || skipped) { @@ -1408,8 +1453,9 @@ void DrawLocation(RandomizerCheck rc) { break; } } - if (txt == "" && skipped) - txt = "Skipped"; //TODO language + if (txt == "" && skipped) { + txt = "Skipped"; // TODO language + } if (txt != "") { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, extraColor.b / 255.0f, extraColor.a / 255.0f)); @@ -1435,8 +1481,9 @@ int hue = 0; void RainbowTick() { float freqHue = hue * 2 * M_PI / (360 * CVarGetFloat("gCosmetics.RainbowSpeed", 0.6f)); for (auto& cvar : rainbowCVars) { - if (CVarGetInteger((cvar + "RBM").c_str(), 0) == 0) + if (CVarGetInteger((cvar + "RBM").c_str(), 0) == 0) { continue; + } Color_RGBA8 newColor; newColor.r = sin(freqHue + 0) * 127 + 128; @@ -1543,9 +1590,15 @@ void CheckTrackerSettingsWindow::DrawElement() { } UIWidgets::EnhancementCheckbox("Vanilla/MQ Dungeon Spoilers", "gCheckTrackerOptionMQSpoilers"); UIWidgets::Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. Otherwise, Vanilla/MQ dungeon locations must be unlocked."); - UIWidgets::EnhancementCheckbox("Hide right-side shop item checks", "gCheckTrackerOptionHideRightShopChecks", false, "", UIWidgets::CheckboxGraphics::Cross, true); + if (UIWidgets::EnhancementCheckbox("Hide right-side shop item checks", "gCheckTrackerOptionHideRightShopChecks", false, "", UIWidgets::CheckboxGraphics::Cross, true)) { + hideShopRightChecks = !hideShopRightChecks; + RecalculateAreaTotals(); + } UIWidgets::Tooltip("If enabled, will prevent the tracker from displaying slots 1-4 in all shops."); - UIWidgets::EnhancementCheckbox("Always show gold skulltulas", "gCheckTrackerOptionAlwaysShowGSLocs", false, ""); + if (UIWidgets::EnhancementCheckbox("Always show gold skulltulas", "gCheckTrackerOptionAlwaysShowGSLocs", false, "")) { + alwaysShowGS = !alwaysShowGS; + RecalculateAreaTotals(); + } UIWidgets::Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings."); ImGui::TableNextColumn(); @@ -1600,6 +1653,9 @@ void CheckTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); + hideShopRightChecks = CVarGetInteger("gCheckTrackerOptionHideRightShopChecks", 1); + alwaysShowGS = CVarGetInteger("gCheckTrackerOptionAlwaysShowGSLocs", 0); + //LocationTable_Init(); } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 9df23f794..68ea1d40c 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -101,15 +101,6 @@ u8 sActionModelGroups[] = { PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_MASK_GERUDO PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_MASK_TRUTH PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_LENS_OF_TRUTH - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_SHIELD_DEKU - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_SHIELD_HYLIAN - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_SHIELD_MIRROR - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_TUNIC_KOKIRI - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_TUNIC_GORON - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_TUNIC_ZORA - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_BOOTS_KOKIRI - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_BOOTS_IRON - PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_BOOTS_HOVER }; TextTriggerEntry sTextTriggers[] = { 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 f192fe1ce..82a600bee 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -1074,15 +1074,6 @@ static s8 sItemActions[] = { PLAYER_IA_SWORD_KOKIRI, // ITEM_SWORD_KOKIRI PLAYER_IA_SWORD_MASTER, // ITEM_SWORD_MASTER PLAYER_IA_SWORD_BIGGORON, // ITEM_SWORD_BIGGORON - PLAYER_IA_SHIELD_DEKU, // ITEM_SHIELD_DEKU - PLAYER_IA_SHIELD_HYLIAN, // ITEM_SHIELD_HYLIAN - PLAYER_IA_SHIELD_MIRROR, // ITEM_SHIELD_MIRROR - PLAYER_IA_TUNIC_KOKIRI, // ITEM_TUNIC_KOKIRI - PLAYER_IA_TUNIC_GORON, // ITEM_TUNIC_GORON - PLAYER_IA_TUNIC_ZORA, // ITEM_TUNIC_ZORA - PLAYER_IA_BOOTS_KOKIRI, // ITEM_BOOTS_KOKIRI - PLAYER_IA_BOOTS_IRON, // ITEM_BOOTS_IRON - PLAYER_IA_BOOTS_HOVER, // ITEM_BOOTS_HOVER }; static u8 sMaskMemory; @@ -1157,15 +1148,6 @@ static s32 (*sItemActionUpdateFuncs[])(Player* this, PlayState* play) = { func_8083485C, // PLAYER_IA_MASK_GERUDO func_8083485C, // PLAYER_IA_MASK_TRUTH func_8083485C, // PLAYER_IA_LENS_OF_TRUTH - func_8083485C, // PLAYER_IA_SHIELD_DEKU - func_8083485C, // PLAYER_IA_SHIELD_HYLIAN - func_8083485C, // PLAYER_IA_SHIELD_MIRROR - func_8083485C, // PLAYER_IA_TUNIC_KOKIRI - func_8083485C, // PLAYER_IA_TUNIC_GORON - func_8083485C, // PLAYER_IA_TUNIC_ZORA - func_8083485C, // PLAYER_IA_BOOTS_KOKIRI - func_8083485C, // PLAYER_IA_BOOTS_IRON - func_8083485C, // PLAYER_IA_BOOTS_HOVER }; static void (*sItemActionInitFuncs[])(PlayState* play, Player* this) = { @@ -1236,15 +1218,6 @@ static void (*sItemActionInitFuncs[])(PlayState* play, Player* this) = { func_80833770, // PLAYER_IA_MASK_GERUDO func_80833770, // PLAYER_IA_MASK_TRUTH func_80833770, // PLAYER_IA_LENS_OF_TRUTH - func_80833770, // PLAYER_IA_SHIELD_DEKU - func_80833770, // PLAYER_IA_SHIELD_HYLIAN - func_80833770, // PLAYER_IA_SHIELD_MIRROR - func_80833770, // PLAYER_IA_TUNIC_KOKIRI - func_80833770, // PLAYER_IA_TUNIC_GORON - func_80833770, // PLAYER_IA_TUNIC_ZORA - func_80833770, // PLAYER_IA_BOOTS_KOKIRI - func_80833770, // PLAYER_IA_BOOTS_IRON - func_80833770, // PLAYER_IA_BOOTS_HOVER }; typedef enum { @@ -2037,6 +2010,10 @@ s8 Player_ItemToItemAction(s32 item) { return PLAYER_IA_LAST_USED; } else if (item == ITEM_FISHING_POLE) { return PLAYER_IA_FISHING_POLE; + // #region SOH [Enhancement] Added to prevent crashes with assignable equipment + } else if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) { + return PLAYER_IA_NONE; + // #endregion } else { return sItemActions[item]; } @@ -3167,8 +3144,7 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) { if ((itemAction == PLAYER_IA_NONE) || !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) || ((this->actor.bgCheckFlags & 1) && - ((itemAction == PLAYER_IA_HOOKSHOT) || (itemAction == PLAYER_IA_LONGSHOT))) || - ((itemAction >= PLAYER_IA_SHIELD_DEKU) && (itemAction <= PLAYER_IA_BOOTS_HOVER))) { + ((itemAction == PLAYER_IA_HOOKSHOT) || (itemAction == PLAYER_IA_LONGSHOT)))) { if ((play->bombchuBowlingStatus == 0) && (((itemAction == PLAYER_IA_DEKU_STICK) && (AMMO(ITEM_STICK) == 0)) || @@ -3180,12 +3156,6 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) { return; } - if (itemAction >= PLAYER_IA_SHIELD_DEKU) { - // Changing shields through action commands is unimplemented - // Boots and tunics handled previously - return; - } - if (itemAction == PLAYER_IA_LENS_OF_TRUTH) { if (Magic_RequestChange(play, 0, MAGIC_CONSUME_LENS)) { if (play->actorCtx.lensActive) { @@ -11000,46 +10970,39 @@ static f32 D_8085482C[] = { 0.5f, 1.0f, 3.0f }; void Player_UseTunicBoots(Player* this, PlayState* play) { // Boots and tunics equip despite state - s32 i; - s32 item; - s32 itemAction; - if (!( - this->stateFlags1 & PLAYER_STATE1_INPUT_DISABLED || - this->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || - this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE || - this->stateFlags1 & PLAYER_STATE1_TEXT_ON_SCREEN || - this->stateFlags1 & PLAYER_STATE1_DEAD || + if ( + this->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_DEAD) || this->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING - )) { - for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) { - if (CHECK_BTN_ALL(sControlInput->press.button, sItemButtons[i])) { - break; - } + ) { + return; + } + + s32 i; + for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) { + if (CHECK_BTN_ALL(sControlInput->press.button, sItemButtons[i])) { + break; } - item = Player_GetItemOnButton(play, i); - if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) { - this->heldItemButton = i; - itemAction = Player_ItemToItemAction(item); - if (itemAction >= PLAYER_IA_BOOTS_KOKIRI) { - u16 bootsValue = itemAction - PLAYER_IA_BOOTS_KOKIRI + 1; - if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) { - Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); - } else { - Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue); - } - Player_SetEquipmentData(play, this); - func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS - : NA_SE_PL_CHANGE_ARMS); - } else if (itemAction >= PLAYER_IA_TUNIC_KOKIRI) { - u16 tunicValue = itemAction - PLAYER_IA_TUNIC_KOKIRI + 1; - if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) { - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); - } else { - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue); - } - Player_SetEquipmentData(play, this); - func_808328EC(this, NA_SE_PL_CHANGE_ARMS); + } + s32 item = Player_GetItemOnButton(play, i); + if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) { + if (item >= ITEM_BOOTS_KOKIRI) { + u16 bootsValue = item - ITEM_BOOTS_KOKIRI + 1; + if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) { + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); + } else { + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue); } + Player_SetEquipmentData(play, this); + func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS); + } else { + u16 tunicValue = item - ITEM_TUNIC_KOKIRI + 1; + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) { + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); + } else { + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue); + } + Player_SetEquipmentData(play, this); + func_808328EC(this, NA_SE_PL_CHANGE_ARMS); } } }