From 5912b65eff783ea45082599020b61982ad766223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Fri, 8 Jan 2021 12:44:00 +0100 Subject: [PATCH] uking/ui: Add Master Sword related inventory functions --- README.md | 2 +- data/uking_functions.csv | 8 +++---- src/Game/UI/CMakeLists.txt | 2 ++ src/Game/UI/uiPauseMenuDataMgr.cpp | 36 ++++++++++++++++++++++++++++++ src/Game/UI/uiPauseMenuDataMgr.h | 3 +++ src/Game/UI/uiUtils.cpp | 9 ++++++++ src/Game/UI/uiUtils.h | 10 +++++++++ 7 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 src/Game/UI/uiUtils.cpp create mode 100644 src/Game/UI/uiUtils.h diff --git a/README.md b/README.md index 0ef0a6b1..85657ec9 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ File names, class or function names and the file organization come from leftover The goal of this project is to better understand game internals, aid with glitch hunting and document existing knowledge in something less fragile than an IDA database. -Considering the large size of the executable (~40MB), it is not expected to reach 100% progress within a reasonable timeframe. That's actually not really a goal since the KingSystem framework represents less than 50% of the executable. Nevertheless, this project still uses the percentage of decompiled bytes to track progress for the components we are interested in. +Considering the large size of the executable (~40MB), it is not expected to reach 100% progress within a reasonable timeframe. That's actually not really an objective since the KingSystem framework represents less than 50% of the executable. Nevertheless, this project still uses the percentage of decompiled bytes to track progress for the components we are interested in. As a result, the project is unlikely to produce a working executable in the near future. It will help with understanding and reverse engineering the game even in its incomplete state, but it will NOT help with playing BotW or porting the game to other platforms, which is **explicitly a non-goal**. diff --git a/data/uking_functions.csv b/data/uking_functions.csv index fc2078bf..d7677c2d 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -56283,7 +56283,7 @@ 0x0000007100969f50,sub_7100969F50,204, 0x000000710096a01c,sub_710096A01C,92, 0x000000710096a078,sub_710096A078,204, -0x000000710096a144,sub_710096A144,92, +0x000000710096a144,sub_710096A144,92,w 0x000000710096a1a0,sub_710096A1A0,204, 0x000000710096a26c,sub_710096A26C,92, 0x000000710096a2c8,sub_710096A2C8,204, @@ -56351,8 +56351,8 @@ 0x00000071009721ec,sub_71009721EC,392, 0x0000007100972374,PauseMenuDataMgr::getPorchNum,356,_ZNK5uking2ui16PauseMenuDataMgr13getArrowCountERKN4sead14SafeStringBaseIcEE 0x00000071009724d8,PauseMenuDataMgr::getPorchNumFromSaveOrPouch,304,_ZNK5uking2ui16PauseMenuDataMgr17getRealArrowCountERKN4sead14SafeStringBaseIcEE -0x0000007100972608,sub_7100972608,212, -0x00000071009726dc,PauseMenuDataMgr::restoreMasterSwordLife,228, +0x0000007100972608,sub_7100972608,212,_ZN5uking2ui16PauseMenuDataMgr16breakMasterSwordEv +0x00000071009726dc,PauseMenuDataMgr::restoreMasterSwordLife,228,_ZN5uking2ui16PauseMenuDataMgr18restoreMasterSwordEb 0x00000071009727c0,PauseMenuDataMgr::checkWeaponFreeSlotMaybe,976, 0x0000007100972b90,PauseMenuDataMgr::increasePouchNum,4200, 0x0000007100973bf8,sub_7100973BF8,644, @@ -61702,7 +61702,7 @@ 0x0000007100aa7ac8,sub_7100AA7AC8,84, 0x0000007100aa7b1c,sub_7100AA7B1C,144, 0x0000007100aa7bac,sub_7100AA7BAC,256, -0x0000007100aa7cac,checkIsMasterSwordActorName,140, +0x0000007100aa7cac,checkIsMasterSwordActorName,140,_ZN5uking2ui22isMasterSwordActorNameERKN4sead14SafeStringBaseIcEE 0x0000007100aa7d38,sub_7100AA7D38,52, 0x0000007100aa7d6c,sub_7100AA7D6C,924, 0x0000007100aa8108,shop::setScreenType,8, diff --git a/src/Game/UI/CMakeLists.txt b/src/Game/UI/CMakeLists.txt index 7edec296..61a562d6 100644 --- a/src/Game/UI/CMakeLists.txt +++ b/src/Game/UI/CMakeLists.txt @@ -1,4 +1,6 @@ target_sources(uking PRIVATE uiPauseMenuDataMgr.cpp uiPauseMenuDataMgr.h + uiUtils.cpp + uiUtils.h ) diff --git a/src/Game/UI/uiPauseMenuDataMgr.cpp b/src/Game/UI/uiPauseMenuDataMgr.cpp index a7be9a98..e2d4e9dd 100644 --- a/src/Game/UI/uiPauseMenuDataMgr.cpp +++ b/src/Game/UI/uiPauseMenuDataMgr.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "Game/UI/uiUtils.h" #include "KingSystem/ActorSystem/actActorUtil.h" #include "KingSystem/ActorSystem/actInfoData.h" #include "KingSystem/GameData/gdtCommonFlagsUtils.h" @@ -355,6 +356,41 @@ int PauseMenuDataMgr::getRealArrowCount(const sead::SafeString& name) const { return status == 2 ? 0 : count; } +void PauseMenuDataMgr::breakMasterSword() { + const auto lock = sead::makeScopedLock(mCritSection); + s32 idx = 0; + for (auto& item : getItems()) { + if (item.getType() == PouchItemType::Weapon && isMasterSwordActorName(item.getName())) { + item.mValue = 0; + item.mValid = false; + if (!mIsPouchForQuest && idx >= 0) { + ksys::gdt::setFlag_PorchItem_Value1(0, idx); + ksys::gdt::setFlag_PorchItem_EquipFlag(false, idx); + } + break; + } + ++idx; + } +} + +void PauseMenuDataMgr::restoreMasterSword(bool only_if_broken) { + const auto lock = sead::makeScopedLock(mCritSection); + s32 idx = 0; + for (auto& item : getItems()) { + if (item.getType() == PouchItemType::Weapon && isMasterSwordActorName(item.getName())) { + if (only_if_broken && item.getValue() > 0) + break; + + item.mValue = getWeaponInventoryLife(item.getName()); + if (!mIsPouchForQuest && idx >= 0) + ksys::gdt::setFlag_PorchItem_Value1(item.mValue, idx); + + break; + } + ++idx; + } +} + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) void PauseMenuDataMgr::updateDivineBeastClearFlags(int num_cleared_beasts) { switch (num_cleared_beasts) { diff --git a/src/Game/UI/uiPauseMenuDataMgr.h b/src/Game/UI/uiPauseMenuDataMgr.h index ef131394..de49cf89 100644 --- a/src/Game/UI/uiPauseMenuDataMgr.h +++ b/src/Game/UI/uiPauseMenuDataMgr.h @@ -144,6 +144,9 @@ public: /// This was added in 1.3.1 to patch the Trial of the Sword arrow restock glitch. int getRealArrowCount(const sead::SafeString& name) const; + void breakMasterSword(); + void restoreMasterSword(bool only_if_broken); + private: // TODO: rename struct ItemInfo { diff --git a/src/Game/UI/uiUtils.cpp b/src/Game/UI/uiUtils.cpp new file mode 100644 index 00000000..fce87fb8 --- /dev/null +++ b/src/Game/UI/uiUtils.cpp @@ -0,0 +1,9 @@ +#include "Game/UI/uiUtils.h" + +namespace uking::ui { + +bool isMasterSwordActorName(const sead::SafeString& name) { + return name == "Weapon_Sword_070"; +} + +} // namespace uking::ui diff --git a/src/Game/UI/uiUtils.h b/src/Game/UI/uiUtils.h new file mode 100644 index 00000000..4330c4eb --- /dev/null +++ b/src/Game/UI/uiUtils.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace uking::ui { + +int getWeaponInventoryLife(const sead::SafeString& name); +bool isMasterSwordActorName(const sead::SafeString& name); + +} // namespace uking::ui