diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 3c52570ea..f3b3e6d93 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -73595,10 +73595,10 @@ Address,Quality,Size,Name 0x0000007100d36ee0,U,000176, 0x0000007100d36f90,U,000016, 0x0000007100d36fa0,U,000320, -0x0000007100d370e0,U,001284,LazyTraverseList::ctor -0x0000007100d375e4,U,000076,LazyTraverseList::dtor -0x0000007100d37630,U,000132,LazyTraverseList::updateFlags -0x0000007100d376b4,U,000216, +0x0000007100d370e0,O,001284,_ZN4ksys3map16LazyTraverseListC1EPN4sead4HeapE +0x0000007100d375e4,O,000076,_ZN4ksys3map16LazyTraverseListD1Ev +0x0000007100d37630,O,000132,_ZN4ksys3map16LazyTraverseList11updateFlagsEv +0x0000007100d376b4,O,000216,_ZN4ksys3map16LazyTraverseList16wereFlagsUpdatedEv 0x0000007100d3778c,U,000204,LinkTag::construct 0x0000007100d37858,U,000280,LinkTag::calc 0x0000007100d37970,U,000064,LinkTag::dtor diff --git a/src/KingSystem/Map/CMakeLists.txt b/src/KingSystem/Map/CMakeLists.txt index 7336bfd10..9bf05203a 100644 --- a/src/KingSystem/Map/CMakeLists.txt +++ b/src/KingSystem/Map/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(uking PRIVATE mapTypes.h mapDebug.cpp mapDebug.h + mapLazyTraverseList.cpp + mapLazyTraverseList.h mapMubinIter.cpp mapMubinIter.h mapObject.cpp diff --git a/src/KingSystem/Map/mapLazyTraverseList.cpp b/src/KingSystem/Map/mapLazyTraverseList.cpp new file mode 100644 index 000000000..a87d2b940 --- /dev/null +++ b/src/KingSystem/Map/mapLazyTraverseList.cpp @@ -0,0 +1,112 @@ +#include "KingSystem/Map/mapLazyTraverseList.h" + +#include "Game/DLC/aocManager.h" +#include "KingSystem/GameData/gdtManager.h" + +namespace ksys::map { + +LazyTraverseList::LazyTraverseList(sead::Heap* heap) { + ksys::res::Handle handle; + sead::SafeString path = "Map/MainField/LazyTraverseList.mubin"; + ksys::res::LoadRequest request; + + if (uking::aoc::Manager::instance()) + uking::aoc::Manager::instance()->getFileDeviceForMap(&request.mAocFileDevice, + &request.mPackHandle, path); + + handle.load(path, &request); + + if (handle.checkLoadStatus()) { + mHasEntries = false; + } else { + auto* direct_res = sead::DynamicCast(handle.getResource()); + if (!direct_res) { + mHasEntries = false; + } else { + auto* entryIter = new (heap) al::ByamlIter(direct_res->getRawData()); + if (entryIter && entryIter->getSize() >= 1) { + mHasEntries = true; + + mEntries.allocBufferAssert(entryIter->getSize(), heap); + + int objectCount = 0; + for (int entryIdx = 0; entryIdx < entryIter->getSize(); ++entryIdx) { + const char* key; + entryIter->getKeyName(&key, entryIdx); + + mEntries[entryIdx].flag_name = key; + mEntries[entryIdx].flag_value = 0; + + al::ByamlIter objectIter; + if (entryIter->tryGetIterByIndex(&objectIter, entryIdx)) { + objectCount += objectIter.getSize(); + } + } + + mObjects.allocBufferAssert(objectCount, heap); + + for (int object = 0, entryIdx = 0; entryIdx < entryIter->getSize(); ++entryIdx) { + al::ByamlIter objectIter; + const char* entryName; + entryIter->getKeyName(&entryName, entryIdx); // debug log? + + if (!entryIter->tryGetIterByIndex(&objectIter, entryIdx)) + continue; + + for (int objectIdx = 0; objectIdx < objectIter.getSize(); ++objectIdx) { + al::ByamlIter kvIter; + if (!objectIter.tryGetIterByIndex(&kvIter, objectIdx)) + continue; + + const char* configName; + kvIter.tryGetStringByKey(&configName, "UnitConfigName"); // debug log? + + kvIter.tryGetUIntByKey(&mObjects[object].hash_id, "HashId"); + mObjects[object].entry_idx = entryIdx; + ++object; + } + } + } else { + mHasEntries = false; + } + + if (entryIter) { + heap->free(entryIter); + } + } + } + + handle.requestUnload(); +} + +LazyTraverseList::~LazyTraverseList() { + mEntries.freeBuffer(); + mObjects.freeBuffer(); + mHasEntries = false; +} + +void LazyTraverseList::updateFlags() { + for (int i = 0; i < u8(mEntries.size()); ++i) { + ksys::gdt::Manager::instance()->getParamBypassPerm().get().getBool(&mEntries[i].flag_value, + mEntries[i].flag_name); + } +} + +bool LazyTraverseList::wereFlagsUpdated() { + auto* mgr = ksys::gdt::Manager::instance(); + + bool updated = false; + for (int i = 0; i < mEntries.size(); ++i) { + if (mgr->wasFlagNotCopied(mEntries[i].flag_name)) { + updated = true; + mEntries[i].flag_value = false; + } else if (mgr->wasFlagCopied(mEntries[i].flag_name)) { + updated = true; + mEntries[i].flag_value = true; + } + } + + return updated; +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapLazyTraverseList.h b/src/KingSystem/Map/mapLazyTraverseList.h new file mode 100644 index 000000000..12afcd7ee --- /dev/null +++ b/src/KingSystem/Map/mapLazyTraverseList.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include "KingSystem/Resource/resHandle.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::map { + +class LazyTraverseList { +public: + explicit LazyTraverseList(sead::Heap* heap); + ~LazyTraverseList(); + void updateFlags(); + bool wereFlagsUpdated(); + +private: + struct Entry { + sead::FixedSafeString<0x40> flag_name; + bool flag_value; + }; + KSYS_CHECK_SIZE_NX150(Entry, 0x60); + + struct Object { + u32 hash_id; + u32 entry_idx; + }; + KSYS_CHECK_SIZE_NX150(Object, 0x8); + + sead::Buffer mEntries; + sead::Buffer mObjects; + bool mHasEntries = false; +}; +KSYS_CHECK_SIZE_NX150(LazyTraverseList, 0x28); + +} // namespace ksys::map