summaryrefslogtreecommitdiff
path: root/src/Game/UI/uiPauseMenuDataMgr.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-01-17 23:41:05 +0100
committerLéo Lam <leo@leolam.fr>2021-01-18 02:08:34 +0100
commita0f67e2f7db6a89ff0d560e1e4b683e5daed42f8 (patch)
tree243e346b9a48015bad2a5c24fd6d50fad6c693b7 /src/Game/UI/uiPauseMenuDataMgr.cpp
parent36fa2b36c206911fecf1653db81a6d7ffab39781 (diff)
uking/ui: Implement PauseMenuDataMgr::addToPouch
Diffstat (limited to 'src/Game/UI/uiPauseMenuDataMgr.cpp')
-rw-r--r--src/Game/UI/uiPauseMenuDataMgr.cpp124
1 files changed, 93 insertions, 31 deletions
diff --git a/src/Game/UI/uiPauseMenuDataMgr.cpp b/src/Game/UI/uiPauseMenuDataMgr.cpp
index cfd3eb75..cd217597 100644
--- a/src/Game/UI/uiPauseMenuDataMgr.cpp
+++ b/src/Game/UI/uiPauseMenuDataMgr.cpp
@@ -1,6 +1,7 @@
#include "Game/UI/uiPauseMenuDataMgr.h"
#include <container/seadBuffer.h>
#include <limits>
+#include <math/seadMathCalcCommon.h>
#include <prim/seadScopedLock.h>
#include "Game/Actor/actWeapon.h"
#include "Game/DLC/aocManager.h"
@@ -10,6 +11,7 @@
#include "KingSystem/ActorSystem/actInfoData.h"
#include "KingSystem/ActorSystem/actPlayerInfo.h"
#include "KingSystem/GameData/gdtCommonFlagsUtils.h"
+#include "KingSystem/GameData/gdtSpecialFlags.h"
#include "KingSystem/System/PlayReportMgr.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/InitTimeInfo.h"
@@ -250,9 +252,9 @@ void PauseMenuDataMgr::loadFromGameData() {
void PauseMenuDataMgr::doLoadFromGameData() {
namespace gdt = ksys::gdt;
const auto lock = sead::makeScopedLock(mCritSection);
- auto& items = getItems();
+ auto& lists = mItemLists;
- for (auto* item = items.popFront(); item; item = items.popFront()) {
+ for (auto* item = lists.list1.popFront(); item; item = lists.list1.popFront()) {
item->~PouchItem();
new (item) PouchItem;
mItemLists.list2.pushFront(item);
@@ -293,26 +295,26 @@ void PauseMenuDataMgr::doLoadFromGameData() {
case PouchItemType::Sword: {
act::WeaponModifierInfo info{};
info.loadPorchSwordFlag(num_swords);
- addToPouch(item_name, type, items, value, equipped, &info, true);
+ addToPouch(item_name, type, lists, value, equipped, &info, true);
++num_swords;
break;
}
case PouchItemType::Bow: {
act::WeaponModifierInfo info{};
info.loadPorchBowFlag(num_bows);
- addToPouch(item_name, type, items, value, equipped, &info, true);
+ addToPouch(item_name, type, lists, value, equipped, &info, true);
++num_bows;
break;
}
case PouchItemType::Shield: {
act::WeaponModifierInfo info{};
info.loadPorchShieldFlag(num_shields);
- addToPouch(item_name, type, items, value, equipped, &info, true);
+ addToPouch(item_name, type, lists, value, equipped, &info, true);
++num_shields;
break;
}
default:
- addToPouch(item_name, type, items, value, equipped, nullptr, true);
+ addToPouch(item_name, type, lists, value, equipped, nullptr, true);
break;
}
@@ -350,7 +352,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
++num_food;
} else if (type == PouchItemType::Sword && isMasterSwordActorName(mItem_44488->getName()) &&
- gdt::getFlag_MasterSwordRecoverTime() <= std::numeric_limits<f32>::epsilon() &&
+ gdt::getFlag_MasterSwordRecoverTime() <= sead::Mathf::epsilon() &&
mItem_44488->getValue() <= 0) {
const s32 new_value = getWeaponInventoryLife(mItem_44488->getName());
mItem_44488->mValue = new_value;
@@ -361,7 +363,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
// Add the Travel Medallion (Obj_WarpDLC) to the inventory if it is missing for some reason
if (aoc::Manager::instance()->hasAoc2() &&
!(found_travel_medallion | !gdt::getFlag_IsGet_Obj_WarpDLC())) {
- addToPouch(sValues.Obj_WarpDLC.cstr(), PouchItemType::KeyItem, items, 1, false, nullptr,
+ addToPouch(sValues.Obj_WarpDLC.cstr(), PouchItemType::KeyItem, lists, 1, false, nullptr,
true);
}
@@ -374,7 +376,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
++num_cleared_beasts;
if (!mRitoSoulItem) {
was_missing_hero_soul = true;
- addToPouch(sValues.Obj_HeroSoul_Rito.cstr(), PouchItemType::KeyItem, items, 1, true,
+ addToPouch(sValues.Obj_HeroSoul_Rito.cstr(), PouchItemType::KeyItem, lists, 1, true,
nullptr, true);
gdt::setFlag_IsPlayed_Demo119_0(true);
}
@@ -384,7 +386,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
++num_cleared_beasts;
if (!mGoronSoulItem) {
was_missing_hero_soul = true;
- addToPouch(sValues.Obj_HeroSoul_Goron.cstr(), PouchItemType::KeyItem, items, 1, true,
+ addToPouch(sValues.Obj_HeroSoul_Goron.cstr(), PouchItemType::KeyItem, lists, 1, true,
nullptr, true);
gdt::setFlag_IsPlayed_Demo116_0(true);
}
@@ -394,7 +396,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
++num_cleared_beasts;
if (!mZoraSoulItem) {
was_missing_hero_soul = true;
- addToPouch(sValues.Obj_HeroSoul_Zora.cstr(), PouchItemType::KeyItem, items, 1, true,
+ addToPouch(sValues.Obj_HeroSoul_Zora.cstr(), PouchItemType::KeyItem, lists, 1, true,
nullptr, true);
gdt::setFlag_IsPlayed_Demo122_0(true);
}
@@ -404,7 +406,7 @@ void PauseMenuDataMgr::doLoadFromGameData() {
++num_cleared_beasts;
if (!mGerudoSoulItem) {
was_missing_hero_soul = true;
- addToPouch(sValues.Obj_HeroSoul_Gerudo.cstr(), PouchItemType::KeyItem, items, 1, true,
+ addToPouch(sValues.Obj_HeroSoul_Gerudo.cstr(), PouchItemType::KeyItem, lists, 1, true,
nullptr, true);
gdt::setFlag_IsPlayed_Demo125_0(true);
}
@@ -722,10 +724,10 @@ void PauseMenuDataMgr::itemGet(const sead::SafeString& name, int value,
}
const auto lock = sead::makeScopedLock(mCritSection);
- auto& items = getItems();
+ auto& lists = mItemLists;
ksys::PlayReportMgr::instance()->reportDebug("PouchGet", name);
- addToPouch(name, type, items, value, false, modifier);
- saveToGameData(items);
+ addToPouch(name, type, lists, value, false, modifier);
+ saveToGameData(lists.list1);
}
void PauseMenuDataMgr::updateAfterAddingItem(bool only_sort) {
@@ -745,40 +747,42 @@ void PauseMenuDataMgr::updateAfterAddingItem(bool only_sort) {
}
void PauseMenuDataMgr::updateListHeads() {
- mListHeads.fill(nullptr);
+ for (s32 i = 0; i < mListHeads.size(); ++i)
+ mListHeads[i] = nullptr;
+
+ const auto set_if_null = [&](PouchCategory cat, s32 i) {
+ if (!mListHeads[s32(cat)])
+ mListHeads[s32(cat)] = &mArray1[i];
+ };
+
for (s32 i = 0; i < NumPouch50; ++i) {
- auto& ptr = mArray1[i];
+ if (mArray2[i] == PouchItemType::Invalid)
+ continue;
+
switch (mArray2[i]) {
case PouchItemType::Sword:
- if (!mListHeads[s32(PouchCategory::Sword)])
- mListHeads[s32(PouchCategory::Sword)] = &ptr;
+ set_if_null(PouchCategory::Sword, i);
break;
case PouchItemType::Bow:
case PouchItemType::Arrow:
- if (!mListHeads[s32(PouchCategory::Bow)])
- mListHeads[s32(PouchCategory::Bow)] = &ptr;
+ set_if_null(PouchCategory::Bow, i);
break;
case PouchItemType::Shield:
- if (!mListHeads[s32(PouchCategory::Shield)])
- mListHeads[s32(PouchCategory::Shield)] = &ptr;
+ set_if_null(PouchCategory::Shield, i);
break;
case PouchItemType::ArmorHead:
case PouchItemType::ArmorUpper:
case PouchItemType::ArmorLower:
- if (!mListHeads[s32(PouchCategory::Armor)])
- mListHeads[s32(PouchCategory::Armor)] = &ptr;
+ set_if_null(PouchCategory::Armor, i);
break;
case PouchItemType::Material:
- if (!mListHeads[s32(PouchCategory::Material)])
- mListHeads[s32(PouchCategory::Material)] = &ptr;
+ set_if_null(PouchCategory::Material, i);
break;
case PouchItemType::Food:
- if (!mListHeads[s32(PouchCategory::Food)])
- mListHeads[s32(PouchCategory::Food)] = &ptr;
+ set_if_null(PouchCategory::Food, i);
break;
case PouchItemType::KeyItem:
- if (!mListHeads[s32(PouchCategory::KeyItem)])
- mListHeads[s32(PouchCategory::KeyItem)] = &ptr;
+ set_if_null(PouchCategory::KeyItem, i);
break;
case PouchItemType::Invalid:
break;
@@ -786,6 +790,64 @@ void PauseMenuDataMgr::updateListHeads() {
}
}
+void PauseMenuDataMgr::addToPouch(const sead::SafeString& name, PouchItemType type, Lists& lists,
+ int value, bool equipped, const act::WeaponModifierInfo* modifier,
+ bool is_inventory_load) {
+ if (ksys::act::InfoData::instance()->hasTag(name.cstr(), ksys::act::tags::CanGetCollectSet))
+ return;
+
+ if (type == PouchItemType::KeyItem) {
+ // If this is a key item and duplicates are not allowed, we need to check
+ // whether the item is already in the inventory. If it is, do not add it again.
+ if (!ksys::act::InfoData::instance()->hasTag(name.cstr(), ksys::act::tags::CanStack)) {
+ for (auto* item = getItemHead(PouchCategory::KeyItem);
+ item && item->getType() == PouchItemType::KeyItem; item = lists.list1.next(item)) {
+ if (item->get25() && item->getName() == name)
+ return;
+ }
+ }
+
+ } else if (type == PouchItemType::Sword && isMasterSwordActorName(name)) {
+ // Duplicates are not allowed for the Master Sword.
+ // Adding a second Master Sword should just refresh the item value or equipped status.
+ for (auto* item = getItemHead(PouchCategory::Sword);
+ item && item->getType() == PouchItemType::Sword; item = lists.list1.next(item)) {
+ if (!item->get25() || item->getName() != name)
+ continue;
+
+ if (ksys::gdt::getFlag_MasterSwordRecoverTime() <= sead::Mathf::epsilon()) {
+ if (item->getValue() <= 0)
+ item->mValue = value;
+ } else {
+ item->mValue = 0;
+ item->mEquipped = false;
+ }
+
+ mItem_44488 = item->mValue > 0 ? item : nullptr;
+ resetItem();
+ return;
+ }
+ }
+
+ if (type != PouchItemType::Invalid) {
+ doAddToPouch(type, name, lists, value, equipped, modifier, is_inventory_load);
+
+ updateAfterAddingItem(true);
+ updateInventoryInfo(lists.list1);
+ updateListHeads();
+
+ if (name == sValues.Obj_KorokNuts)
+ ksys::gdt::setFlag_KorokNutsNum(getItemCount(name));
+ else if (name == sValues.Obj_DungeonClearSeal)
+ ksys::gdt::setFlag_DungeonClearSealNum(getItemCount(name));
+ }
+
+ sead::SafeString same_group_actor_name;
+ ksys::act::getSameGroupActorName(&same_group_actor_name, name);
+ ksys::gdt::setIsGetItem(same_group_actor_name, true);
+ ksys::gdt::setIsGetItem2(same_group_actor_name, true);
+}
+
void PauseMenuDataMgr::saveToGameData(const sead::OffsetList<PouchItem>& list) const {
if (mIsPouchForQuest)
return;