summaryrefslogtreecommitdiff
path: root/src/Game/UI
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-01-13 21:46:13 +0100
committerLéo Lam <leo@leolam.fr>2021-01-16 21:18:24 +0100
commit4a6f3f9786ba386878d841ffbd3492e624a3446f (patch)
treebd1d5845b9c3dfac29196a7ad38a6d8887236feb /src/Game/UI
parent2f9e3d0c322e4340a12f1cf631128b78499374c8 (diff)
uking/ui: Implement "item get" PauseMenuDataMgr function
Diffstat (limited to 'src/Game/UI')
-rw-r--r--src/Game/UI/uiPauseMenuDataMgr.cpp123
-rw-r--r--src/Game/UI/uiPauseMenuDataMgr.h37
2 files changed, 147 insertions, 13 deletions
diff --git a/src/Game/UI/uiPauseMenuDataMgr.cpp b/src/Game/UI/uiPauseMenuDataMgr.cpp
index a12fa7ca..981bbbe1 100644
--- a/src/Game/UI/uiPauseMenuDataMgr.cpp
+++ b/src/Game/UI/uiPauseMenuDataMgr.cpp
@@ -2,6 +2,7 @@
#include <container/seadBuffer.h>
#include <limits>
#include <prim/seadScopedLock.h>
+#include "Game/Actor/actWeapon.h"
#include "Game/DLC/aocManager.h"
#include "Game/UI/uiUtils.h"
#include "KingSystem/ActorSystem/Profiles/actPlayerBase.h"
@@ -9,6 +10,7 @@
#include "KingSystem/ActorSystem/actInfoData.h"
#include "KingSystem/ActorSystem/actPlayerInfo.h"
#include "KingSystem/GameData/gdtCommonFlagsUtils.h"
+#include "KingSystem/System/PlayReportMgr.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/InitTimeInfo.h"
@@ -34,10 +36,11 @@ sead::SafeArray<CookTagInfo, 11> sCookItemOrder_{{
{0, "Obj_FireWoodBundle", 0},
}};
-struct PouchConstants {
+struct PouchStaticData {
ksys::util::InitTimeInfoEx info;
- void* _18{};
+ u32 last_added_weapon_add_type{};
+ u32 last_added_weapon_add_value{};
f32 _20 = std::numeric_limits<f32>::infinity();
f32 _24 = std::numeric_limits<f32>::infinity();
f32 _28 = std::numeric_limits<f32>::infinity();
@@ -110,7 +113,7 @@ struct PouchConstants {
}};
};
-PouchConstants sValues;
+PouchStaticData sValues;
void getSameGroupActorName(sead::SafeString* group, const sead::SafeString& item,
al::ByamlIter* iter = nullptr) {
@@ -123,6 +126,9 @@ void getSameGroupActorName(sead::SafeString* group, const sead::SafeString& item
} // namespace
+int pouchItemSortPredicate(const PouchItem* lhs, const PouchItem* rhs);
+int pouchItemSortPredicateForArrow(const PouchItem* lhs, const PouchItem* rhs);
+
PauseMenuDataMgr::PauseMenuDataMgr() {
mListHeads.fill(nullptr);
for (s32 i = 0; i < NumPouch50; ++i) {
@@ -146,14 +152,23 @@ PouchItem::PouchItem() {
}
void PauseMenuDataMgr::resetItem() {
- mItem.mType = PouchItemType::Invalid;
- mItem._1c = -1;
- mItem.mValue = 0;
- mItem.mValid = false;
- mItem._25 = 0;
- mItem.mName.clear();
- mItem.mData.cook = {};
- mItem.mData.cook.mCookEffect0 = sDummyCookEffect0;
+ mNewlyAddedItem.mType = PouchItemType::Invalid;
+ mNewlyAddedItem._1c = -1;
+ mNewlyAddedItem.mValue = 0;
+ mNewlyAddedItem.mValid = false;
+ mNewlyAddedItem._25 = 0;
+ mNewlyAddedItem.mName.clear();
+ mNewlyAddedItem.mData.cook = {};
+ mNewlyAddedItem.mData.cook.mCookEffect0 = sDummyCookEffect0;
+}
+
+void PauseMenuDataMgr::setItemModifier(PouchItem& item, const act::WeaponModifierInfo* modifier) {
+ if (modifier && !modifier->flags.isZero()) {
+ item.setWeaponAddType(modifier->flags.getDirect());
+ item.setWeaponAddValue(static_cast<u32>(modifier->value));
+ } else {
+ item.setWeaponAddType(0);
+ }
}
void PauseMenuDataMgr::init(sead::Heap* heap) {}
@@ -514,6 +529,92 @@ bool PauseMenuDataMgr::isWeaponSectionFull(const sead::SafeString& weapon_type)
return false;
}
+void PauseMenuDataMgr::itemGet(const sead::SafeString& name, int value,
+ const act::WeaponModifierInfo* modifier) {
+ if (name.include("Default") || name.include("Extra"))
+ return;
+
+ const auto type = getType(name);
+
+ mNewlyAddedItem.mType = type;
+ mNewlyAddedItem.mValue = value;
+ mNewlyAddedItem._25 = 1;
+ mNewlyAddedItem.mName = name;
+ mNewlyAddedItem.mValid = false;
+
+ if (modifier) {
+ setItemModifier(mNewlyAddedItem, modifier);
+ const auto add_type = modifier->flags.getDirect();
+ const auto add_value = mNewlyAddedItem.getWeaponAddValue();
+ sValues.last_added_weapon_add_type = add_type;
+ sValues.last_added_weapon_add_value = add_value;
+ }
+
+ const auto lock = sead::makeScopedLock(mCritSection);
+ auto& items = getItems();
+ ksys::PlayReportMgr::instance()->reportDebug("PouchGet", name);
+ addToPouch(name, type, items, value, false, modifier);
+ saveToGameData(items);
+}
+
+void PauseMenuDataMgr::updateAfterAddingItem(bool only_sort) {
+ const auto lock = sead::makeScopedLock(mCritSection);
+
+ if (getItems().isEmpty())
+ return;
+
+ _44800 = PouchCategory::Invalid;
+ auto& items = getItems();
+ items.sort(pouchItemSortPredicateForArrow);
+ if (!only_sort) {
+ updateInventoryInfo(items);
+ updateListHeads();
+ saveToGameData(items);
+ }
+}
+
+void PauseMenuDataMgr::updateListHeads() {
+ mListHeads.fill(nullptr);
+ for (s32 i = 0; i < NumPouch50; ++i) {
+ auto& ptr = mArray1[i];
+ switch (mArray2[i]) {
+ case PouchItemType::Weapon:
+ if (!mListHeads[s32(PouchCategory::Weapon)])
+ mListHeads[s32(PouchCategory::Weapon)] = &ptr;
+ break;
+ case PouchItemType::Bow:
+ case PouchItemType::Arrow:
+ if (!mListHeads[s32(PouchCategory::Bow)])
+ mListHeads[s32(PouchCategory::Bow)] = &ptr;
+ break;
+ case PouchItemType::Shield:
+ if (!mListHeads[s32(PouchCategory::Shield)])
+ mListHeads[s32(PouchCategory::Shield)] = &ptr;
+ break;
+ case PouchItemType::ArmorHead:
+ case PouchItemType::ArmorUpper:
+ case PouchItemType::ArmorLower:
+ if (!mListHeads[s32(PouchCategory::Armor)])
+ mListHeads[s32(PouchCategory::Armor)] = &ptr;
+ break;
+ case PouchItemType::Material:
+ if (!mListHeads[s32(PouchCategory::Material)])
+ mListHeads[s32(PouchCategory::Material)] = &ptr;
+ break;
+ case PouchItemType::Food:
+ if (!mListHeads[s32(PouchCategory::Food)])
+ mListHeads[s32(PouchCategory::Food)] = &ptr;
+ break;
+ case PouchItemType::KeyItem:
+ if (!mListHeads[s32(PouchCategory::KeyItem)])
+ mListHeads[s32(PouchCategory::KeyItem)] = &ptr;
+ break;
+ case PouchItemType::Invalid:
+ break;
+ }
+ }
+}
+
void PauseMenuDataMgr::removeArrow(const sead::SafeString& arrow_name, int count) {
if (!ksys::act::InfoData::instance()->hasTag(arrow_name.cstr(), ksys::act::tags::Arrow))
return;
diff --git a/src/Game/UI/uiPauseMenuDataMgr.h b/src/Game/UI/uiPauseMenuDataMgr.h
index 1e4525dc..7110afcb 100644
--- a/src/Game/UI/uiPauseMenuDataMgr.h
+++ b/src/Game/UI/uiPauseMenuDataMgr.h
@@ -19,6 +19,10 @@ namespace ksys::act {
class InfoData;
}
+namespace uking::act {
+struct WeaponModifierInfo;
+}
+
namespace uking::ui {
constexpr int NumWeaponsMax = 20;
@@ -127,6 +131,8 @@ public:
u8 get25() const { return _25; }
const sead::SafeString& getName() const { return mName; }
+ bool isWeapon() const { return getType() <= PouchItemType::Shield; }
+
// This is only valid if the item is not a weapon.
s32 getCount() const { return getValue(); }
@@ -141,6 +147,22 @@ public:
WeaponData& getWeaponData() { return mData.weapon; }
const WeaponData& getWeaponData() const { return mData.weapon; }
+ u32 getWeaponAddValue() const {
+ if (!isWeapon())
+ return 0;
+ return mData.weapon.mAddValue;
+ }
+
+ void setWeaponAddType(u32 type) {
+ if (isWeapon())
+ mData.weapon.mAddType = type;
+ }
+
+ void setWeaponAddValue(u32 value) {
+ if (isWeapon())
+ mData.weapon.mAddValue = value;
+ }
+
static auto getListNodeOffset() { return offsetof(PouchItem, mListNode); }
private:
@@ -181,8 +203,9 @@ public:
static PouchItemType getType(const sead::SafeString& item, al::ByamlIter* iter = nullptr);
int countItems(PouchItemType type, bool count_any_weapon = false) const;
-
bool isWeaponSectionFull(const sead::SafeString& get_flag) const;
+
+ void itemGet(const sead::SafeString& name, int value, const act::WeaponModifierInfo* modifier);
void removeArrow(const sead::SafeString& arrow_name, int count = 1);
int getItemCount(const sead::SafeString& name, bool x = true) const;
void setWeaponItemValue(s32 value, PouchItemType type);
@@ -249,8 +272,18 @@ private:
bool isList2Empty() const { return mItemLists.list2.isEmpty(); }
void resetItem();
+ void setItemModifier(PouchItem& item, const act::WeaponModifierInfo* modifier);
+
void doLoadFromGameData();
+
void updateInventoryInfo(const sead::OffsetList<PouchItem>& list);
+ void updateListHeads();
+ void saveToGameData(const sead::OffsetList<PouchItem>& list) const;
+ void updateAfterAddingItem(bool only_sort);
+
+ void addToPouch(const sead::SafeString& name, PouchItemType type,
+ sead::OffsetList<PouchItem>& list, int value, bool x,
+ const act::WeaponModifierInfo* modifier = nullptr, bool z = false);
bool hasFreeSpaceForItem(const Lists& lists, const sead::SafeString& name, int n = 1) const;
@@ -281,7 +314,7 @@ private:
PouchItem* mZoraSoulItem{};
PouchItem* mGerudoSoulItem{};
bool _44538 = false;
- PouchItem mItem;
+ PouchItem mNewlyAddedItem;
/// Indicates if a temporary inventory ("pouch for quest") is being used.
bool mIsPouchForQuest = false;