uking/ui: Add "can get item" inventory functions

This commit is contained in:
Léo Lam 2021-01-11 16:13:41 +01:00
parent c28e7ace3d
commit ee713ab899
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
3 changed files with 125 additions and 7 deletions

View File

@ -56321,12 +56321,12 @@
0x000000710096b9c8,sub_710096B9C8,52,_ZN5uking2ui16PauseMenuDataMgrD0Ev
0x000000710096b9fc,nullsub_2782,4,_ZN5uking2ui16PauseMenuDataMgr4initEPN4sead4HeapE
0x000000710096ba00,PauseMenuDataMgr::initForNewSave,1060,_ZN5uking2ui16PauseMenuDataMgr14initForNewSaveEv
0x000000710096be24,PauseMenuDataMgr::loadFromGameData,492,
0x000000710096be24,PauseMenuDataMgr::loadFromGameData,492,_ZN5uking2ui16PauseMenuDataMgr16loadFromGameDataEv
0x000000710096c010,PauseMenuDataMgr::loadFromGameData_,2372,
0x000000710096c954,PauseMenuDataMgr::updateInventoryCategories,3544,
0x000000710096d72c,PauseMenuDataMgr::hasWeaponMaybe,1288,
0x000000710096d72c,PauseMenuDataMgr::hasWeaponMaybe,1288,_ZNK5uking2ui16PauseMenuDataMgr13cannotGetItemERKN4sead14SafeStringBaseIcEEi
0x000000710096dc34,PauseMenuDataMgr::getItemCategory,2004,_ZN5uking2ui16PauseMenuDataMgr7getTypeERKN4sead14SafeStringBaseIcEEPN2al9ByamlIterE
0x000000710096e408,sub_710096E408,1028,
0x000000710096e408,sub_710096E408,1028,_ZNK5uking2ui16PauseMenuDataMgr19hasFreeSpaceForItemERKNS1_5ListsERKN4sead14SafeStringBaseIcEEi
0x000000710096e80c,sub_710096E80C,772,_ZNK5uking2ui16PauseMenuDataMgr10countItemsENS0_13PouchItemTypeEb
0x000000710096eb10,sub_710096EB10,1192,_ZNK5uking2ui16PauseMenuDataMgr19isWeaponSectionFullERKN4sead14SafeStringBaseIcEE
0x000000710096efb8,PauseMenuDataMgr::__auto4,688,

Can't render this file because it is too large.

View File

@ -113,7 +113,7 @@ struct PouchConstants {
PouchConstants sValues;
void getSameGroupActorName(sead::SafeString* group, const sead::SafeString& item,
al::ByamlIter* iter) {
al::ByamlIter* iter = nullptr) {
if (iter) {
ksys::act::getSameGroupActorName(group, item, iter);
} else {
@ -211,6 +211,78 @@ void PauseMenuDataMgr::initForNewSave() {
}
}
void PauseMenuDataMgr::loadFromGameData() {
doLoadFromGameData();
for (auto& x : mArray3)
x = {};
mItem_44488 = {};
mItem_444f0 = {};
_444f8 = -1;
resetItem();
_444fc = 0;
mIsPouchForQuest = false;
_447e0 = {};
_447e8 = {};
_447f0 = {};
_447f8 = {};
const auto lock = sead::makeScopedLock(mCritSection);
updateInventoryInfo(getItems());
}
bool PauseMenuDataMgr::cannotGetItem(const sead::SafeString& name, int n) const {
namespace act = ksys::act;
al::ByamlIter iter;
if (!act::InfoData::instance()->getActorIter(&iter, name.cstr()))
return true;
if (!act::InfoData::instance()->hasTag(iter, act::tags::CanGetPouch))
return true;
if (act::InfoData::instance()->getSortKey(name.cstr()) == 99999)
return true;
const auto lock = sead::makeScopedLock(mCritSection);
const auto type = getType(name);
if (act::InfoData::instance()->hasTag(iter, act::tags::CanStack))
return !hasFreeSpaceForItem(mItemLists, name, n);
if (type <= PouchItemType::Shield) {
switch (type) {
case PouchItemType::Weapon: {
const auto limit = ksys::gdt::getFlag_WeaponPorchStockNum();
return isList2Empty() || limit < countItems(PouchItemType::Weapon) + n;
}
case PouchItemType::Shield: {
const auto limit = ksys::gdt::getFlag_ShieldPorchStockNum();
return isList2Empty() || limit < countItems(PouchItemType::Shield) + n;
}
case PouchItemType::Bow: {
const auto limit = ksys::gdt::getFlag_BowPorchStockNum();
return isList2Empty() || limit < countItems(PouchItemType::Bow) + n;
}
default: {
const auto limit = ksys::gdt::getFlag_WeaponPorchStockNum();
return isList2Empty() || limit < countItems(PouchItemType::Weapon, true) + n;
}
}
}
if (type == PouchItemType::Food)
return isList2Empty() || countItems(PouchItemType::Food, true) + n > NumFoodMax;
if (type == PouchItemType::Material)
return isList2Empty() || countItems(PouchItemType::Material) + n > NumMaterialsMax;
if (type == PouchItemType::KeyItem)
return isList2Empty() || countItems(PouchItemType::KeyItem) + n > NumKeyItemsMax;
return isList2Empty() || countItems(PouchItemType::ArmorHead) + n > NumArmorsMax;
}
PouchItemType PauseMenuDataMgr::getType(const sead::SafeString& item, al::ByamlIter* iter) {
sead::SafeString group;
getSameGroupActorName(&group, item, iter);
@ -266,6 +338,42 @@ PouchItemType PauseMenuDataMgr::getType(const sead::SafeString& item, al::ByamlI
return PouchItemType::Material;
}
bool PauseMenuDataMgr::hasFreeSpaceForItem(const PauseMenuDataMgr::Lists& lists,
const sead::SafeString& name, int n) const {
sead::SafeString group_name;
getSameGroupActorName(&group_name, name);
const int count = getItemCount(group_name);
const bool is_arrow =
ksys::act::InfoData::instance()->hasTag(name.cstr(), ksys::act::tags::Arrow);
if (count == 0 && is_arrow) {
for (const auto& item : lists.list1) {
if (item.getType() == PouchItemType::Arrow && group_name == item.getName())
return true;
}
return countItems(PouchItemType::Arrow) < NumArrowItemsMax;
}
if (count == 0) {
const auto type = getType(name);
if (type == PouchItemType::Food)
return !lists.list2.isEmpty() && countItems(PouchItemType::Food, true) < NumFoodMax;
if (type == PouchItemType::Material)
return !lists.list2.isEmpty() && countItems(PouchItemType::Material) < NumMaterialsMax;
if (type == PouchItemType::KeyItem)
return !lists.list2.isEmpty() && countItems(PouchItemType::KeyItem) < NumKeyItemsMax;
return false;
}
return count + n <= ItemStackSizeMax;
}
int PauseMenuDataMgr::countItems(PouchItemType type, bool count_any_weapon) const {
if (isPouchItemInvalid(type) || getItems().isEmpty())
return 0;
@ -780,7 +888,7 @@ bool PauseMenuDataMgr::isOverCategoryLimit(PouchItemType type) const {
case PouchItemType::Bow:
return ksys::gdt::getFlag_BowPorchStockNum() <= count || count >= NumBowsMax;
case PouchItemType::Arrow:
return count >= NumArrowsMax;
return count >= NumArrowItemsMax;
case PouchItemType::Shield:
return ksys::gdt::getFlag_ShieldPorchStockNum() <= count || count >= NumShieldsMax;
case PouchItemType::ArmorHead:

View File

@ -23,18 +23,20 @@ namespace uking::ui {
constexpr int NumWeaponsMax = 20;
constexpr int NumBowsMax = 14;
constexpr int NumArrowsMax = 6;
constexpr int NumArrowItemsMax = 6;
constexpr int NumShieldsMax = 20;
constexpr int NumArmorsMax = 100;
constexpr int NumMaterialsMax = 160;
constexpr int NumFoodMax = 60;
constexpr int NumKeyItemsMax = 40;
constexpr int NumPouchItemsMax = NumWeaponsMax + NumBowsMax + NumArrowsMax + NumShieldsMax +
constexpr int NumPouchItemsMax = NumWeaponsMax + NumBowsMax + NumArrowItemsMax + NumShieldsMax +
NumArmorsMax + NumMaterialsMax + NumFoodMax + NumKeyItemsMax;
static_assert(NumPouchItemsMax == 420, "NumPouchItemsMax must be 420 for now");
constexpr int ItemStackSizeMax = 999;
// TODO: figure out what this is
constexpr int NumPouch50 = 50;
@ -172,6 +174,9 @@ class PauseMenuDataMgr {
public:
void init(sead::Heap* heap);
void initForNewSave();
void loadFromGameData();
bool cannotGetItem(const sead::SafeString& name, int n) const;
static PouchItemType getType(const sead::SafeString& item, al::ByamlIter* iter = nullptr);
@ -241,8 +246,13 @@ private:
PouchItem** getItemHeadp(PouchCategory category) const { return mListHeads[u32(category)]; }
PouchItem* nextItem(const PouchItem* item) const { return getItems().next(item); }
bool isList2Empty() const { return mItemLists.list2.isEmpty(); }
void resetItem();
void doLoadFromGameData();
void updateInventoryInfo(const sead::OffsetList<PouchItem>& list);
bool hasFreeSpaceForItem(const Lists& lists, const sead::SafeString& name, int n = 1) const;
/// @param num_cleared_beasts The number of divine beasts that have been done.
void updateDivineBeastClearFlags(int num_cleared_beasts);