diff --git a/data/uking_functions.csv b/data/uking_functions.csv index c1c1ab98..d70256f3 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -73750,30 +73750,30 @@ Address,Quality,Size,Name 0x0000007100d407cc,O,000092,_ZNK4ksys3act14PhysicsUserTag18getRuntimeTypeInfoEv 0x0000007100d40828,O,000360,_ZN4ksys3map12PlacementMapC1Ev 0x0000007100d40990,O,000644,_ZN4ksys3map12PlacementMapD1Ev -0x0000007100d40c14,U,000072,PlacementMap::loadStaticMap_ +0x0000007100d40c14,O,000072,_ZN4ksys3map12PlacementMap14loadStaticMap_Eb 0x0000007100d40c5c,U,001692,PlacementMap::doLoadStaticMap_ -0x0000007100d412f8,U,000104,PlacementMap::parseStaticMap_ +0x0000007100d412f8,O,000104,_ZN4ksys3map12PlacementMap15parseStaticMap_EPN4sead4HeapEPh 0x0000007100d41360,U,003020,PlacementMap::parseMap_ -0x0000007100d41f2c,U,001608,PlacementMap::loadDynamicMap -0x0000007100d42574,U,000312,PlacementMap::parseDynamicMap +0x0000007100d41f2c,O,001608,_ZN4ksys3map12PlacementMap14loadDynamicMapEv +0x0000007100d42574,O,000312,_ZN4ksys3map12PlacementMap15parseDynamicMapEv 0x0000007100d426ac,U,000096,PlacementMap::resetDynamic 0x0000007100d4270c,O,000096,_ZN4ksys3map12PlacementMap6unloadEv 0x0000007100d4276c,U,000048,PlacementMap::unloadStaticMubin -0x0000007100d4279c,U,000176,PlacementMap::x_6 +0x0000007100d4279c,O,000176,_ZN4ksys3map12PlacementMap3x_6Ev 0x0000007100d4284c,U,000112,PlacementMap::x_5 0x0000007100d428bc,U,002288,PlacementMap::traverseStuff 0x0000007100d431ac,O,000212,_ZN4ksys3map12PlacementMap17getFieldBodyGroupEi -0x0000007100d43280,U,000588,PlacementMap::cleanupPhysics -0x0000007100d434cc,U,000424,PlacementMap::loadStaticCompound -0x0000007100d43674,U,000400,PlacementMap::x_2 -0x0000007100d43804,U,000552,PlacementMap::x +0x0000007100d43280,O,000588,_ZN4ksys3map12PlacementMap14cleanupPhysicsEv +0x0000007100d434cc,O,000424,_ZN4ksys3map12PlacementMap18loadStaticCompoundEibb +0x0000007100d43674,O,000400,_ZN4ksys3map12PlacementMap3x_2Ei +0x0000007100d43804,U,000552,PlacementMap::x_0 0x0000007100d43a2c,O,000028,_ZN4ksys3map12PlacementMap10unloadHkscEi 0x0000007100d43a48,U,000620,PlacementMap::x_4 0x0000007100d43cb4,U,000172,PlacementMap::x_1 0x0000007100d43d60,U,000248,PlacementMap::staticCompoundStuff -0x0000007100d43e58,U,000192,PlacementMap::cleanHkscMaybe -0x0000007100d43f18,U,000136, -0x0000007100d43fa0,U,000392,PlacementMap::doDisableObjStaticCompound +0x0000007100d43e58,O,000192,_ZN4ksys3map12PlacementMap25doSomethingStaticCompoundEi +0x0000007100d43f18,O,000136,_ZN4ksys3map12PlacementMap15isDynamicLoadedERKN4sead7Vector3IfEE +0x0000007100d43fa0,O,000392,_ZN4ksys3map12PlacementMap26doDisableObjStaticCompoundEPNS0_6ObjectEb 0x0000007100d44128,U,000560,PlacementMap::x_9 0x0000007100d44358,U,003208,PlacementMapMgr::ctor 0x0000007100d44fe0,U,000320,placement::getMubinPath diff --git a/src/KingSystem/Map/mapObject.h b/src/KingSystem/Map/mapObject.h index 39c35eab..cdb2092e 100644 --- a/src/KingSystem/Map/mapObject.h +++ b/src/KingSystem/Map/mapObject.h @@ -43,9 +43,11 @@ public: _2000 = 0x2000, _4000 = 0x4000, _8000 = 0x8000, + _10000 = 0x10000, _40000 = 0x40000, _80000 = 0x80000, _100000 = 0x100000, + _200000 = 0x200000, _400000 = 0x400000, _2000000 = 0x2000000, _4000000 = 0x4000000, @@ -176,6 +178,8 @@ public: Object* findSrcLODLinkObject() const; const auto& getFlags0() const { return mFlags0; } + void setFlags0(Flag0 bit) { mFlags0.set(bit); } + void resetFlags0(Flag0 bit) { mFlags0.reset(bit); } const auto& getFlags() const { return mFlags; } const auto& getActorFlags8() const { return mActorFlags8; } const auto& getHardModeFlags() const { return mHardModeFlags; } diff --git a/src/KingSystem/Map/mapPlacementActors.h b/src/KingSystem/Map/mapPlacementActors.h index d7f58946..0f34a16e 100644 --- a/src/KingSystem/Map/mapPlacementActors.h +++ b/src/KingSystem/Map/mapPlacementActors.h @@ -6,11 +6,13 @@ #include #include #include +#include "KingSystem/Map/mapPlacementMap.h" #include "KingSystem/Utils/Types.h" namespace ksys::map { class Object; +class PlacementMap; // TODO: rename enum class ActorFlag8 { @@ -114,7 +116,11 @@ public: Object* getStaticObj_2(s32 idx) const; bool sub_7100D524B4() const; void x_9(); - Object* resetGroup(int groupIdx); + Object* resetGroup(int group_idx); + int getNumObjs(int group_idx) const; + Object* getObj(int group_idx, int object_idx); + Object* getStaticObj_0(int object_idx); + u32 allocGroupForDynamicMap(PlacementMap* pmap); u8 _0[0x28 - 0x0]; sead::ReadWriteLock mLock; diff --git a/src/KingSystem/Map/mapPlacementMap.cpp b/src/KingSystem/Map/mapPlacementMap.cpp index dbadb05f..8bc0988b 100644 --- a/src/KingSystem/Map/mapPlacementMap.cpp +++ b/src/KingSystem/Map/mapPlacementMap.cpp @@ -2,6 +2,9 @@ #include "KingSystem/Map/mapPlacementMap.h" #include #include +#include "Game/DLC/aocManager.h" +#include "KingSystem/Map/mapObject.h" +#include "KingSystem/Resource/resLoadRequest.h" namespace ksys::map { @@ -37,17 +40,240 @@ PlacementMap::~PlacementMap() { r.cleanup(); } } +bool PlacementMap::parseStaticMap_(sead::Heap* heap, u8* data) { + if (!mMubinPath.isEmpty()) { + if (!mSkipLoadStaticMap) { + parseMap_(heap, data, 0, mIdx); + } + mStaticMapLoaded = true; + mStaticMapParsed = false; + return true; + } + mStaticMapLoaded = true; + return false; +} + +int PlacementMap::getStaticCompoundIdFromPosition(const sead::Vector3f& pos) const { + if (mMgr->isShrineOrDivineBeast()) { + return 0; + } + float dx = (pos.x - (1000 * mCol - 5000)); + float dz = (pos.z - (1000 * mRow - 4000)); + return (2 * (dz > 500.0)) + (dx > 500.0); +} + +bool PlacementMap::isDynamicLoaded(const sead::Vector3f& pos) { + int idx = getStaticCompoundIdFromPosition(pos); + return mRes[idx].mStatus == HkscRes::Status::_3; // Likely InitStatus::DynamicLoaded +} + +bool PlacementMap::x_6() { + if (mDynamicGroupIdx < 0) { + return true; + } + bool ret = true; + int num_objs = mPa->getNumObjs(mDynamicGroupIdx); + + for (int i = 0; i < num_objs; i++) { + Object* obj = mPa->getObj(mDynamicGroupIdx, i); + obj->setFlags0(Object::Flag0::_4000); + + const auto& flags = obj->getFlags0(); + if (flags.isOn(Object::Flag0::_2) || flags.isOn(Object::Flag0::_4)) { + ret &= flags.isOn(Object::Flag0::_80); + } + if (flags.isOn(Object::Flag0::_10000) || flags.isOn(Object::Flag0::_80000000)) { + ret = false; + } + } + + return ret; +} + +bool PlacementMap::loadDynamicMap() { + if (mDynamicGroupIdx >= 0) { + return true; + } -void PlacementMap::unload() { sead::ReadWriteLock* lock = &mPa->mLock; lock->writeLock(); - mPa->resetGroup(mDynamicGroupIdx); - mDynamicGroupIdx = 0xFFFFFFFF; + mDynamicGroupIdx = mPa->allocGroupForDynamicMap(this); lock->writeUnlock(); - mCs.lock(); + if (mDynamicGroupIdx < 0) { + return false; + } + + res::LoadRequest arg; + arg.mRequester = "PlacementMap"; + arg._22 = 1; + + sead::FixedSafeString<128> path; + + int path_len = mMubinPath.findIndex("."); + path.copy(mMubinPath, path_len); + if (act::ActorDebug::instance() && + (act::ActorDebug::instance()->hasFlag(act::ActorDebug::Flag::_10000000))) { + path.append("_DynamicPast.mubin"); + } else if (Patrol::instance() && Patrol::instance()->mLoadStaticPhysUnstableMapUnit) { + path.append("_Dynamic_PhysUnstable.mubin"); + } else if (PlacementMgr::instance()->isGrudgeMerge() || mMgr->isShrineOrDivineBeast()) { + path.append("_Dynamic.mubin"); + } else { + path.append("_Dynamic_NoGrudgeMerge.mubin"); + } + if (uking::aoc::Manager::instance()) { + arg.mAocFileDevice = uking::aoc::Manager::instance()->getFileDeviceForMapFile(path); + } + return mDynamicMubinRes.requestLoad(path, &arg, 0); +} + +// Objects: Static and Dynamic +PlacementMap::MapObjStatus PlacementMap::x_2(int hksc_idx) { + res::Handle* handle = &mRes[hksc_idx].mRes; + if (!handle->isReadyOrNeedsParse()) { + return MapObjStatus::NotReady; + } + handle->parseResource(nullptr); + if (handle->checkLoadStatus()) { + return MapObjStatus::Ready; + } + + auto* resource = handle->getResource(); + auto* sc = sead::DynamicCast(resource); + + sc->sub_7100FCAD0C(mMat); + for (int i = mParsedNumStaticObjs; i <= mNumStaticObjs; i++) { + x_0(hksc_idx, mPa->getStaticObj_0(i)); + } + const int gid = mDynamicGroupIdx; + if (gid >= 0) { + int n = mPa->getNumObjs(gid); + for (int i = 0; i < n; i++) { + x_0(hksc_idx, mPa->getObj(gid, i)); + } + } + return MapObjStatus::Loading; +} + +void PlacementMap::doDisableObjStaticCompound(Object* obj, bool disable) { + if ((s16)obj->getStaticCompoundId() < 0) { + return; + } + const auto lock = sead::makeScopedLock(mCs); + + // Is Flag0::_200000 a flag to disable an object? + if (disable == obj->getFlags0().isOn(Object::Flag0::_200000)) { + return; + } + if (disable) { + obj->setFlags0(Object::Flag0::_200000); + } else { + obj->resetFlags0(Object::Flag0::_200000); + } + + int idx = getStaticCompoundIdFromPosition(obj->getTranslate()); + auto* resource = mRes[idx].mRes.getResource(); + if (auto* sc = sead::DynamicCast(resource)) { + s16 sc_id = obj->getStaticCompoundId(); + sc->disableCollision(sc_id, disable); + } +} + +// Should this be renamed to what x_3() and/or x_4() does +int PlacementMap::doSomethingStaticCompound(int hksc_idx) { + auto* resource = mRes[hksc_idx].mRes.getResource(); + if (auto* sc = sead::DynamicCast(resource)) { + if (!sc->calledFromMapDtor() && !sc->x_3()) { + sc->x_4(); + } + } + return 1; +} +bool PlacementMap::loadStaticCompound(int hksc_idx, bool auto_gen_mu, bool req_arg_8) { + sead::FixedSafeString<0x100> path; + res::LoadRequest arg; + + arg.mRequester = "PlacementMgr"; + arg._8 = req_arg_8; + arg._22 = 1; + + const auto lock = sead::makeScopedLock(mCs); + + if (auto_gen_mu) { + path.format("Physics/StaticCompoundForAutoGenMU/%s-%d.hksc", mFolderAndFile.cstr(), + hksc_idx); + } else { + if (mMgr->isShrineOrDivineBeast()) { + path.format("Physics/StaticCompound/%d.hksc", mFolderAndFile.cstr()); + } else { + path.format("Physics/StaticCompound/%s-%d.hksc", mFolderAndFile.cstr(), hksc_idx); + } + } + if (uking::aoc::Manager::instance()) { + arg.mAocFileDevice = uking::aoc::Manager::instance()->getFileDeviceForStaticCompound(path); + } + + return mRes[hksc_idx].mRes.requestLoad(path, &arg, 0); +} + +// Should this be cleanupStaticCompound, unloadStaticCompound +void PlacementMap::cleanupPhysics() { + const auto lock = sead::makeScopedLock(mCs); + + for (int i = 0; i < 4; i++) { + auto resource = mRes[i].mRes.getResource(); + if (auto* sc = sead::DynamicCast(resource)) { + sc->cleanUp(); + } + mRes[i].mRes.requestUnload2(); + mRes[i].mStatus = HkscRes::Status::_0; + } + mInitStatus = InitStatus::StaticLoaded; +} + +PlacementMap::MapObjStatus PlacementMap::parseDynamicMap() { + if (!mDynamicMubinRes.isReadyOrNeedsParse()) { + return MapObjStatus::NotReady; + } + mDynamicMubinRes.parseResource(nullptr); + if (mDynamicMubinRes.checkLoadStatus()) { + sead::ReadWriteLock* lock = &mPa->mLock; + lock->writeLock(); + mPa->resetGroup(mDynamicGroupIdx); + mDynamicGroupIdx = 0xFFFFFFFF; + lock->writeUnlock(); + return MapObjStatus::Ready; + } + auto* r = mDynamicMubinRes.getResource(); + auto* resource = sead::DynamicCast(r); + + sead::ReadWriteLock* lock = &mPa->mLock; + lock->writeLock(); + parseMap_(0, resource->getRawData(), mDynamicGroupIdx, mIdx); + lock->writeUnlock(); + return MapObjStatus::Loading; +} + +bool PlacementMap::loadStaticMap_(bool load) { + if (!mMubinPath.isEmpty()) { + mStaticMapParsed = true; + if (!mSkipLoadStaticMap) { + doLoadStaticMap_(load); + } + } + return true; +} + +void PlacementMap::unload() { + sead::ReadWriteLock* rw_lock = &mPa->mLock; + rw_lock->writeLock(); + mPa->resetGroup(mDynamicGroupIdx); + mDynamicGroupIdx = 0xFFFFFFFF; + rw_lock->writeUnlock(); + + const auto lock = sead::makeScopedLock(mCs); mDynamicMubinRes.requestUnload(); - mCs.unlock(); } phys::BodyGroup* PlacementMap::getFieldBodyGroup(int field_group_idx) { diff --git a/src/KingSystem/Map/mapPlacementMap.h b/src/KingSystem/Map/mapPlacementMap.h index 264889fa..c5dcf62f 100644 --- a/src/KingSystem/Map/mapPlacementMap.h +++ b/src/KingSystem/Map/mapPlacementMap.h @@ -11,11 +11,14 @@ #include "KingSystem/Map/mapPlacementMapMgr.h" #include "KingSystem/Physics/StaticCompound/physStaticCompound.h" #include "KingSystem/Resource/resHandle.h" +#include "KingSystem/Resource/resResource.h" +#include "KingSystem/System/Patrol.h" #include "KingSystem/Utils/Types.h" namespace ksys::map { class PlacementMapMgr; +class PlacementActors; class PlacementMap { struct HkscRes { @@ -56,12 +59,19 @@ class PlacementMap { }; KSYS_CHECK_SIZE_NX150(InitStatus, 4); + // Rename when better information is available + enum class MapObjStatus : int { + Loading = 0, + Ready = 1, + NotReady = 2, + }; + public: PlacementMap(); ~PlacementMap(); private: - int loadStaticMap_(bool load); + bool loadStaticMap_(bool load); void doLoadStaticMap_(bool load); bool parseStaticMap_(sead::Heap* heap, u8* data); @@ -69,32 +79,34 @@ private: bool loadDynamicMap(); - int parseDynamicMap(); + MapObjStatus parseDynamicMap(); void resetDynamic(); void unload(); void unloadStaticMubin(); - int x_6(); + bool x_6(); void x_5(); int traverseStuff(sead::Vector3f* vec, PlacementActors* pa, int id); - phys::BodyGroup* getFieldBodyGroup(int field_body_group_index); + phys::BodyGroup* getFieldBodyGroup(int field_group_idx); void cleanupPhysics(); - bool loadStaticCompound(int index, bool is_auto_gen_mu, bool load_maybe); - int x_2(int id); - void x(int id, Object* obj); + bool loadStaticCompound(int hksc_idx, bool is_auto_gen_mu, bool req_arg_8); + MapObjStatus x_2(int hksc_idx); + void x_0(int id, Object* obj); void unloadHksc(int hksc_idx); int x_4(int id); int x_1(int id); bool staticCompoundStuff(int sc_id, bool cleanup); - int cleanHkscMaybe(int id); - bool sub_7100D43F18(const sead::Vector3f& pos); + int doSomethingStaticCompound(int hksc_idx); + bool isDynamicLoaded(const sead::Vector3f& pos); void doDisableObjStaticCompound(Object* obj, bool disable); void x_9(); void x_7(int idx, int unknown, s8 column, s8 row, const sead::SafeString& mubin_path, const sead::SafeString& folder_and_file, int map_id_maybe, bool skip_load_static_map); + int getStaticCompoundIdFromPosition(const sead::Vector3f& pos) const; + u8 _0; u8 mSkipLoadStaticMap; bool mStaticMapLoaded; diff --git a/src/KingSystem/Map/mapPlacementMapMgr.h b/src/KingSystem/Map/mapPlacementMapMgr.h index ce86eceb..913c419a 100644 --- a/src/KingSystem/Map/mapPlacementMapMgr.h +++ b/src/KingSystem/Map/mapPlacementMapMgr.h @@ -13,6 +13,7 @@ namespace ksys::map { class MapProperties; class Placement18; class FarActorMerge; +class PlacementActors; class PlacementMap; @@ -40,6 +41,8 @@ public: PlacementMapMgr() = default; ~PlacementMapMgr() = default; + bool isShrineOrDivineBeast() const { return mIsShrineOrDivineBeast; } + private: sead::Buffer mMaps; MapProperties* mMapProps; diff --git a/src/KingSystem/Map/mapPlacementMgr.h b/src/KingSystem/Map/mapPlacementMgr.h index 3cd10767..56db40ed 100644 --- a/src/KingSystem/Map/mapPlacementMgr.h +++ b/src/KingSystem/Map/mapPlacementMgr.h @@ -70,8 +70,12 @@ public: enum class MgrStaticFlags { debug = 0x1, + DemoMode = 0x4, + GrudgeMerge = 0x20, }; + bool isGrudgeMerge() const { return sFlags.isOn(MgrStaticFlags::GrudgeMerge); } + static sead::TypedBitFlag sFlags; u32 _28; diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompound.h b/src/KingSystem/Physics/StaticCompound/physStaticCompound.h index aa0615aa..e5e61505 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompound.h +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompound.h @@ -44,6 +44,9 @@ public: void cleanUp(); bool calledFromMapDtor(); int getNumFieldBodyGroups() const { return mFieldBodyGroups.size(); } + bool x_3(); + void x_4(); + StaticCompound* sub_7100FCAD0C(sead::Matrix34f& mtx); private: enum class Flag { diff --git a/src/KingSystem/System/CMakeLists.txt b/src/KingSystem/System/CMakeLists.txt index a0d1eb08..82594ea2 100644 --- a/src/KingSystem/System/CMakeLists.txt +++ b/src/KingSystem/System/CMakeLists.txt @@ -28,6 +28,8 @@ target_sources(uking PRIVATE OverlayArenaSystem.h OverlayArenaSystemS1.h OverlayArenaSystemS2.h + Patrol.cpp + Patrol.h PlayReportMgr.cpp PlayReportMgr.h ProductReporter.cpp diff --git a/src/KingSystem/System/Patrol.cpp b/src/KingSystem/System/Patrol.cpp new file mode 100644 index 00000000..75e53224 --- /dev/null +++ b/src/KingSystem/System/Patrol.cpp @@ -0,0 +1,7 @@ +#include "KingSystem/System/Patrol.h" + +namespace ksys { + +SEAD_SINGLETON_DISPOSER_IMPL(Patrol) + +} // namespace ksys diff --git a/src/KingSystem/System/Patrol.h b/src/KingSystem/System/Patrol.h new file mode 100644 index 00000000..a45fb16d --- /dev/null +++ b/src/KingSystem/System/Patrol.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include "KingSystem/Utils/Types.h" + +namespace ksys { + +class Patrol { + SEAD_SINGLETON_DISPOSER(Patrol) + +public: + Patrol() = default; + ~Patrol() = default; + + u8 _0[0x3 - 0x0]; + bool mLoadStaticPhysUnstableMapUnit; + sead::FixedSafeString<0x100> mBuildURL; + sead::ListNode _140; + u32 _150; + u32 _154; +}; +KSYS_CHECK_SIZE_NX150(Patrol, 0x158); +} // namespace ksys