uking/ui: Implement weapon and bow sorting in inventory

This commit is contained in:
Léo Lam 2021-01-22 11:57:44 +01:00
parent d9f7561588
commit bb3f05e209
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
4 changed files with 96 additions and 13 deletions

View File

@ -56379,14 +56379,14 @@
0x0000007100977128,sub_7100977128,868,
0x000000710097748c,sub_710097748C,628,_ZN5uking2ui16PauseMenuDataMgr9sortItemsENS0_13PouchCategoryEb
0x0000007100977700,sub_7100977700,248,_ZN5uking2ui22pouchItemSortPredicateEPKNS0_9PouchItemES3_
0x00000071009777f8,sub_71009777F8,272,
0x0000007100977908,sub_7100977908,288,
0x00000071009777f8,sub_71009777F8,272,_ZN5uking2ui13compareWeaponEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977908,sub_7100977908,288,_ZN5uking2ui10compareBowEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977a28,sub_7100977A28,272,_ZN5uking2ui13compareShieldEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977b38,sub_7100977B38,336,_ZN5uking2ui12compareArmorEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977c88,sub_7100977C88,308,_ZN5uking2ui15compareMaterialEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977dbc,sub_7100977DBC,540,_ZN5uking2ui11compareFoodEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100977fd8,sub_7100977FD8,116,_ZN5uking2ui14compareKeyItemEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x000000710097804c,sub_710097804C,676,
0x000000710097804c,sub_710097804C,676,_ZN5uking2uiL15doCompareWeaponEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x00000071009782f0,sub_71009782F0,664,_ZN5uking2uiL15doCompareShieldEPKNS0_9PouchItemES3_PN4ksys3act8InfoDataE
0x0000007100978588,sub_7100978588,480,_ZN5uking2ui16getCookItemOrderEPKNS0_9PouchItemEPN4ksys3act8InfoDataE
0x0000007100978768,sub_7100978768,304,_ZN5uking2ui30pouchItemSortPredicateForArrowEPKNS0_9PouchItemES3_

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

View File

@ -204,6 +204,19 @@ int getFoodSortKey(int* effect_value, const PouchItem* item) {
}
}
int getWeaponPowerSortValue(const PouchItem* item, ksys::act::InfoData* data) {
#ifdef MATCHING_HACK_NX_CLANG
__builtin_assume(data); // Force LLVM to keep data (perhaps N had an "assume not null" macro?)
#endif
WeaponStats stats;
getWeaponStats(*item, &stats);
int value = stats.power;
if (item->getType() == PouchItemType::Bow && stats.bow_add_value > 1)
value *= stats.bow_add_value;
return value;
}
} // namespace
int pouchItemSortPredicate(const PouchItem* lhs, const PouchItem* rhs);
@ -230,7 +243,7 @@ PouchItem::PouchItem() {
void PauseMenuDataMgr::resetItem() {
mNewlyAddedItem.mType = PouchItemType::Invalid;
mNewlyAddedItem._1c = -1;
mNewlyAddedItem.mItemUse = ItemUse::Invalid;
mNewlyAddedItem.mValue = 0;
mNewlyAddedItem.mEquipped = false;
mNewlyAddedItem._25 = 0;
@ -1928,6 +1941,56 @@ static s32 compareSortKeys(const PouchItem* lhs, const PouchItem* rhs, ksys::act
return 0;
}
static s32 compareItemValues(const PouchItem* lhs, const PouchItem* rhs) {
const int val1 = lhs->getValue();
const int val2 = rhs->getValue();
// Higher is better
if (val1 > val2)
return -1;
if (val1 < val2)
return 1;
return 0;
}
static int doCompareWeapon(const PouchItem* lhs, const PouchItem* rhs, ksys::act::InfoData* data) {
const auto use1 = lhs->getItemUse();
const auto use2 = rhs->getItemUse();
if (use1 < use2)
return -1;
if (use1 > use2)
return 1;
const auto power1 = getWeaponPowerSortValue(lhs, data);
const auto power2 = getWeaponPowerSortValue(rhs, data);
if (power1 > power2)
return -1;
if (power1 < power2)
return 1;
const auto mod1 = getWeaponModifierSortKey(lhs->getWeaponAddFlags());
const auto mod2 = getWeaponModifierSortKey(rhs->getWeaponAddFlags());
if (mod1 < mod2)
return -1;
if (mod1 > mod2)
return 1;
return compareItemValues(lhs, rhs);
}
static int compareWeaponType0(const PouchItem* lhs, const PouchItem* rhs,
ksys::act::InfoData* data) {
if (auto cmp = doCompareWeapon(lhs, rhs, data))
return cmp;
return compareSortKeys(lhs, rhs, data);
}
static int compareWeaponType1(const PouchItem* lhs, const PouchItem* rhs,
ksys::act::InfoData* data) {
if (auto cmp = compareSortKeys(lhs, rhs, data))
return cmp;
return doCompareWeapon(lhs, rhs, data);
}
static int getShieldGuardPower(const PouchItem* item, ksys::act::InfoData* data) {
int power = ksys::act::getWeaponCommonGuardPower(data, item->getName().cstr());
if (item->getWeaponAddFlags().isOn(act::WeaponModifier::AddGuard))
@ -1952,15 +2015,22 @@ static int doCompareShield(const PouchItem* lhs, const PouchItem* rhs, ksys::act
if (mod1 > mod2)
return 1;
const int val1 = lhs->getValue();
const int val2 = rhs->getValue();
// Higher is better
if (val1 > val2)
return -1;
if (val1 < val2)
return 1;
return compareItemValues(lhs, rhs);
}
return 0;
int compareWeapon(const PouchItem* lhs, const PouchItem* rhs, ksys::act::InfoData* data) {
if (ksys::gdt::getFlag_SortTypeWeaponPouch())
return compareWeaponType1(lhs, rhs, data);
return compareWeaponType0(lhs, rhs, data);
}
int compareBow(const PouchItem* lhs, const PouchItem* rhs, ksys::act::InfoData* data) {
if (lhs->getType() == PouchItemType::Arrow)
return compareSortKeys(lhs, rhs, data);
if (ksys::gdt::getFlag_SortTypeBowPouch())
return compareWeaponType1(lhs, rhs, data);
return compareWeaponType0(lhs, rhs, data);
}
int compareShield(const PouchItem* lhs, const PouchItem* rhs, ksys::act::InfoData* data) {

View File

@ -175,6 +175,7 @@ public:
bool isEquipped() const { return mEquipped; }
u8 get25() const { return _25; }
const sead::SafeString& getName() const { return mName; }
ItemUse getItemUse() const { return mItemUse; }
bool isWeapon() const { return getType() <= PouchItemType::Shield; }
@ -231,7 +232,7 @@ private:
sead::ListNode mListNode;
PouchItemType mType = PouchItemType::Invalid;
s32 _1c = -1;
ItemUse mItemUse = ItemUse::Invalid;
s32 mValue = 0;
bool mEquipped = false;
u8 _25 = 1;

View File

@ -1,15 +1,27 @@
#pragma once
#include <prim/seadSafeString.h>
#include "Game/Actor/actWeapon.h"
namespace uking::ui {
class PouchItem;
struct WeaponStats {
int durability{};
/// Attack power (for offensive weapons) or guard power (for shields).
int power{};
act::WeaponModifierInfo modifier{};
/// Bow modifier value ("add value") or 0 for weapons that are not bows.
int bow_add_value{};
};
bool isMasterSwordItem(const PouchItem& item);
int getItemHitPointRecover(const sead::SafeString& name);
void getWeaponStats(const PouchItem& item, WeaponStats* stats);
int getWeaponInventoryLife(const sead::SafeString& name);
bool isMasterSwordActorName(const sead::SafeString& name);