From 8205744abcae5784138629038976f2449269a81f Mon Sep 17 00:00:00 2001 From: theo3 Date: Sun, 8 Nov 2020 22:07:27 -0800 Subject: [PATCH] implement map::Object getters --- data/uking_functions.csv | 76 ++-- ...orEPNS_3act24ActorLinkConstDataAccessE.bin | Bin 0 -> 88 bytes src/KingSystem/ActorSystem/CMakeLists.txt | 3 +- src/KingSystem/ActorSystem/actBaseProc.h | 2 + src/KingSystem/ActorSystem/actBaseProcMgr.h | 2 + src/KingSystem/ActorSystem/actDebug.cpp | 12 + src/KingSystem/ActorSystem/actDebug.h | 24 ++ src/KingSystem/Map/CMakeLists.txt | 6 + src/KingSystem/Map/mapDebug.cpp | 3 + src/KingSystem/Map/mapDebug.h | 11 + src/KingSystem/Map/mapObject.cpp | 364 ++++++++++++++++++ src/KingSystem/Map/mapObject.h | 105 ++++- src/KingSystem/Map/mapObjectLink.cpp | 21 + src/KingSystem/Map/mapObjectLink.h | 98 +++++ src/KingSystem/Map/mapPlacementMgr.cpp | 7 + src/KingSystem/Map/mapPlacementMgr.h | 119 ++++++ 16 files changed, 801 insertions(+), 52 deletions(-) create mode 100644 expected/_ZNK4ksys3map6Object20getActorWithAccessorEPNS_3act24ActorLinkConstDataAccessE.bin create mode 100644 src/KingSystem/ActorSystem/actDebug.cpp create mode 100644 src/KingSystem/ActorSystem/actDebug.h create mode 100644 src/KingSystem/Map/mapDebug.cpp create mode 100644 src/KingSystem/Map/mapDebug.h create mode 100644 src/KingSystem/Map/mapObjectLink.cpp create mode 100644 src/KingSystem/Map/mapObjectLink.h create mode 100644 src/KingSystem/Map/mapPlacementMgr.cpp create mode 100644 src/KingSystem/Map/mapPlacementMgr.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index dafc9e24..a08b08cb 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -73164,7 +73164,7 @@ 0x0000007100d29b0c,sub_7100D29B0C,96, 0x0000007100d29b6c,sub_7100D29B6C,104, 0x0000007100d29bd4,sub_7100D29BD4,8, -0x0000007100d29bdc,ActorDebug::getNullStr,12, +0x0000007100d29bdc,ActorDebug::getNullStr,12,_ZN4ksys3act10ActorDebug10getNullStrEPNS1_10HashUnusedE 0x0000007100d29be8,sub_7100D29BE8,32, 0x0000007100d29c08,sub_7100D29C08,376, 0x0000007100d29d80,sub_7100D29D80,32, @@ -73816,51 +73816,51 @@ 0x0000007100d49b10,sub_7100D49B10,416, 0x0000007100d49cb0,sub_7100D49CB0,56, 0x0000007100d49ce8,PlacementObj::ctor,124,_ZN4ksys3map6ObjectC1Ev! -0x0000007100d49d64,PlacementObj::dtor,52, +0x0000007100d49d64,PlacementObj::dtor,52,_ZN4ksys3map6ObjectD1Ev 0x0000007100d49d98,PlacementObj::initData,380, 0x0000007100d49f14,PlacementObj::initRevivalGameDataFlagAndMiscFlags,620, -0x0000007100d4a180,PlacementObj::free,120, +0x0000007100d4a180,PlacementObj::free,120,_ZN4ksys3map6Object4freeEv 0x0000007100d4a1f8,PlacementObj::x_8,132, 0x0000007100d4a27c,PlacementObj::getActor_0,244, 0x0000007100d4a370,PlacementObj::x_10,244, -0x0000007100d4a464,PlacementObj::getActorWithAccessor,88, -0x0000007100d4a4bc,PlacementObj::getActor,140, -0x0000007100d4a548,PlacementObj::registerActor,320, -0x0000007100d4a688,PlacementObj::setActorDirect,8, -0x0000007100d4a690,PlacementObj::isEnemyOrNpcOrActiveOrMapPassive,84, -0x0000007100d4a6e4,PlacementObj::doesActorHaveNoFlag8,16, -0x0000007100d4a6f4,PlacementObj::isNpcOrActiveOrMapPassiveOrFlag1,108, -0x0000007100d4a760,PlacementObj::isMapPassive,92, -0x0000007100d4a7bc,PlacementObj::checkActorDataFlag0,60, -0x0000007100d4a7f8,PlacementObj::isEnemyOrNpc,36, -0x0000007100d4a81c,PlacementObj::getTraverseDistForGenGroup,120, -0x0000007100d4a894,PlacementObj::x_3,92, -0x0000007100d4a8f0,PlacementObj::getDispDistance,144, -0x0000007100d4a980,PlacementObj::getTraverseDist,208, -0x0000007100d4aa50,PlacementObj::getTraverseDistForLOD,200, +0x0000007100d4a464,PlacementObj::getActorWithAccessor,88,_ZNK4ksys3map6Object20getActorWithAccessorERNS_3act24ActorLinkConstDataAccessE! +0x0000007100d4a4bc,PlacementObj::getActor,140,_ZNK4ksys3map6Object8getActorEv +0x0000007100d4a548,PlacementObj::registerActor,320,_ZN4ksys3map6Object16registerBaseProcEPNS_3act8BaseProcE +0x0000007100d4a688,PlacementObj::setActorDirect,8,_ZN4ksys3map6Object17setBaseProcDirectEPNS_3act8BaseProcE +0x0000007100d4a690,PlacementObj::isEnemyOrNpcOrActiveOrMapPassive,84,_ZNK4ksys3map6Object32isEnemyOrNpcOrActiveOrMapPassiveEv +0x0000007100d4a6e4,PlacementObj::doesActorHaveNoFlag8,16,_ZNK4ksys3map6Object15isFlags8ClearedEv +0x0000007100d4a6f4,PlacementObj::isNpcOrActiveOrMapPassiveOrFlag1,108,_ZNK4ksys3map6Object32isNpcOrActiveOrMapPassiveOrFlag1Ev +0x0000007100d4a760,PlacementObj::isMapPassive,92,_ZNK4ksys3map6Object12isMapPassiveEPKNS0_15PlacementActorsE +0x0000007100d4a7bc,PlacementObj::checkActorDataFlag0,60,_ZNK4ksys3map6Object18checkActorDataFlagEPKNS0_15PlacementActorsENS0_9ActorData4FlagE +0x0000007100d4a7f8,PlacementObj::isEnemyOrNpc,36,_ZNK4ksys3map6Object12isEnemyOrNpcEPKNS0_15PlacementActorsE +0x0000007100d4a81c,PlacementObj::getTraverseDistForGenGroup,120,_ZNK4ksys3map6Object15getDispDistanceEPKNS0_15PlacementActorsEbb +0x0000007100d4a894,PlacementObj::x_3,92,_ZNK4ksys3map6Object15getDispDistanceEPKNS0_9ActorDataEbjb +0x0000007100d4a8f0,PlacementObj::getDispDistance,144,_ZNK4ksys3map6Object15getDispDistanceEbb +0x0000007100d4a980,PlacementObj::getTraverseDist,208,_ZNK4ksys3map6Object15getTraverseDistEPKNS0_9ActorDataEbjb +0x0000007100d4aa50,PlacementObj::getTraverseDistForLOD,200,_ZNK4ksys3map6Object21getTraverseDistForLODEv 0x0000007100d4ab18,PlacementObj::initTraverseDist,1016, -0x0000007100d4af10,PlacementObj::getScale,44, +0x0000007100d4af10,PlacementObj::getScale,44,_ZNK4ksys3map6Object8getScaleEv 0x0000007100d4af3c,sub_7100D4AF3C,36, 0x0000007100d4af60,PlacementObj::getLoadDistance,412, -0x0000007100d4b0fc,PlacementObj::getUnitConfigName,172, +0x0000007100d4b0fc,PlacementObj::getUnitConfigName,172,_ZNK4ksys3map6Object17getUnitConfigNameEv 0x0000007100d4b1a8,PlacementObj::x_13,4248, 0x0000007100d4c240,PlacementObj::checkYDistance,412, 0x0000007100d4c3dc,PlacementObj::getDispDistanceComplex,968, -0x0000007100d4c7a4,PlacementObj::getUnitConfigNameFromByml,92, -0x0000007100d4c800,PlacementObj::findPlacementLODLinkObject,52, -0x0000007100d4c834,PlacementObj::getPlacementLODLinkObj,52, +0x0000007100d4c7a4,PlacementObj::getUnitConfigNameFromByml,92,_ZNK4ksys3map6Object26getUnitConfigNameFromByamlEv +0x0000007100d4c800,PlacementObj::findPlacementLODLinkObject,52,_ZNK4ksys3map6Object26findPlacementLODLinkObjectEPKNS0_15PlacementActorsE +0x0000007100d4c834,PlacementObj::getPlacementLODLinkObj,52,_ZNK4ksys3map6Object26findPlacementLODLinkObjectEv 0x0000007100d4c868,PlacementObj::getPlacementLODLinkObj_0,40, 0x0000007100d4c890,PlacementLinkData::getPlacementLODLinkObj,40, -0x0000007100d4c8b8,PlacementObj::getHashIdStringDebug,108, -0x0000007100d4c924,PlacementObj::getHashIdStringDebug_0,108, +0x0000007100d4c8b8,PlacementObj::getHashIdStringDebug,108,_ZNK4ksys3map6Object20getHashIdStringDebugEv +0x0000007100d4c924,PlacementObj::getHashIdStringDebug_0,108,_ZNK4ksys3map6Object22getHashIdStringDebug_0Ev 0x0000007100d4c990,PlacementObj::unlinkActor,256, 0x0000007100d4ca90,PlacementObj::checkRevivalFlag,220, -0x0000007100d4cb6c,PlacementObj::getRails,24, -0x0000007100d4cb84,PlacementObj::getRails_0,24, -0x0000007100d4cb9c,PlacementObj::allocLinkData,60, -0x0000007100d4cbd8,PlacementObj::hasGenGroup,32, -0x0000007100d4cbf8,PlacementObj::incrementLinkNum,340, -0x0000007100d4cd4c,PlacementObj::decrementLinkNum,20, +0x0000007100d4cb6c,PlacementObj::getRails,24,_ZNK4ksys3map6Object8getRailsEv +0x0000007100d4cb84,PlacementObj::getRails_0,24,_ZNK4ksys3map6Object10getRails_0Ev +0x0000007100d4cb9c,PlacementObj::allocLinkData,60,_ZN4ksys3map6Object13allocLinkDataEPN4sead4HeapE +0x0000007100d4cbd8,PlacementObj::hasGenGroup,32,_ZNK4ksys3map6Object11hasGenGroupEv +0x0000007100d4cbf8,PlacementObj::incrementLinkNum,340,_ZN4ksys3map6Object16incrementLinkNumEv +0x0000007100d4cd4c,PlacementObj::decrementLinkNum,20,_ZN4ksys3map6Object16decrementLinkNumEv 0x0000007100d4cd60,PlacementObj::initRevivalGameDataFlag,632, 0x0000007100d4cfd8,PlacementObj::isRevivalGameDataFlagOn,124, 0x0000007100d4d054,PlacementObj::setRevivalGameDataFlagValueIf,120, @@ -73878,11 +73878,11 @@ 0x0000007100d4d998,sub_7100D4D998,288, 0x0000007100d4dab8,sub_7100D4DAB8,80, 0x0000007100d4db08,sub_7100D4DB08,428, -0x0000007100d4dcb4,PlacementObj::getRotate,44, +0x0000007100d4dcb4,PlacementObj::getRotate,44,_ZNK4ksys3map6Object9getRotateEv 0x0000007100d4dce0,PlacementObj::x_21,360, -0x0000007100d4de48,PlacementObj::getTraversePosAndLoadDistance,124, -0x0000007100d4dec4,PlacementObj::getUniqueName,104, -0x0000007100d4df2c,PlacementObj::setTranslate,28, +0x0000007100d4de48,PlacementObj::getTraversePosAndLoadDistance,124,_ZNK4ksys3map6Object29getTraversePosAndLoadDistanceEPN4sead7Vector3IfEEPf? +0x0000007100d4dec4,PlacementObj::getUniqueName,104,_ZNK4ksys3map6Object13getUniqueNameEPPKc +0x0000007100d4df2c,PlacementObj::setTranslate,28,_ZN4ksys3map6Object12setTranslateERKN4sead7Vector3IfEE 0x0000007100d4df48,PlacementObj::x_22,128, 0x0000007100d4dfc8,PlacementObj::setFieldATrue,36, 0x0000007100d4dfec,j__ZdlPv_848,4, @@ -73890,11 +73890,11 @@ 0x0000007100d4e0e0,getMapLinkDefinitionDescription,96, 0x0000007100d4e140,getMapLinkDefinitionDescription_0,96, 0x0000007100d4e1a0,getMapLinkDefinitionNum,324, -0x0000007100d4e2e4,PlacementLink::getObjActor,20, -0x0000007100d4e2f8,PlacementLink::getObjActorWithAccessor,24, +0x0000007100d4e2e4,PlacementLink::getObjActor,20,_ZNK4ksys3map10ObjectLink13getObjectProcEv +0x0000007100d4e2f8,PlacementLink::getObjActorWithAccessor,24,_ZNK4ksys3map10ObjectLink25getObjectProcWithAccessorERNS_3act24ActorLinkConstDataAccessE 0x0000007100d4e310,sub_7100D4E310,28, 0x0000007100d4e32c,isPlacementLODOrForSaleLink,24, -0x0000007100d4e344,PlacementLinkData::ctor,44, +0x0000007100d4e344,PlacementLinkData::ctor,44,_ZN4ksys3map14ObjectLinkDataC1Ev 0x0000007100d4e370,PlacementLinkData::deleteArrays,136, 0x0000007100d4e3f8,PlacementLinkData::allocLinks,556, 0x0000007100d4e624,PlacementLinkData::allocLinksToSelf,212, diff --git a/expected/_ZNK4ksys3map6Object20getActorWithAccessorEPNS_3act24ActorLinkConstDataAccessE.bin b/expected/_ZNK4ksys3map6Object20getActorWithAccessorEPNS_3act24ActorLinkConstDataAccessE.bin new file mode 100644 index 0000000000000000000000000000000000000000..796b2e843a25acf9d405e45afd65704f3466cb5e GIT binary patch literal 88 zcmV-e0H^=-Prj-BdjYBaLjaLz1OV^|DMk780|2T30YLfl0|BZa0RXh--Ts&0001_K u9zgl1006WJkwG~>2>@{cF`t?O000!>10SmWdqJt-0~4zBPr|5U%l;Q%+9Xf_ literal 0 HcmV?d00001 diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt index a54d0e02..d80bb38d 100644 --- a/src/KingSystem/ActorSystem/CMakeLists.txt +++ b/src/KingSystem/ActorSystem/CMakeLists.txt @@ -38,7 +38,8 @@ target_sources(uking PRIVATE actBaseProcMgr.h actBaseProcUnit.cpp actBaseProcUnit.h - actLifeRecoveryInfo.h + actDebug.cpp + actDebug.h actInstParamPack.cpp actInstParamPack.h actTag.h diff --git a/src/KingSystem/ActorSystem/actBaseProc.h b/src/KingSystem/ActorSystem/actBaseProc.h index c7636998..de5a1a86 100644 --- a/src/KingSystem/ActorSystem/actBaseProc.h +++ b/src/KingSystem/ActorSystem/actBaseProc.h @@ -87,6 +87,8 @@ public: void setPriority(u8 priority) { mPriority = priority; } State getState() const { return mState; } + bool isInit() const { return mState == State::Init; } + bool isCalc() const { return mState == State::Calc; } bool isDeletedOrDeleting() const { return mState == State::Delete || mStateFlags.isOn(StateFlags::RequestDelete); } diff --git a/src/KingSystem/ActorSystem/actBaseProcMgr.h b/src/KingSystem/ActorSystem/actBaseProcMgr.h index a1ce35d8..f39b8197 100644 --- a/src/KingSystem/ActorSystem/actBaseProcMgr.h +++ b/src/KingSystem/ActorSystem/actBaseProcMgr.h @@ -163,6 +163,8 @@ public: Status getStatus() const { return mStatus; } u32 getNumJobTypes() const { return mNumJobTypes; } + bool checkGetActorOk(BaseProc* proc, void* a2); + private: void doAddToUpdateStateList_(BaseProc& proc); diff --git a/src/KingSystem/ActorSystem/actDebug.cpp b/src/KingSystem/ActorSystem/actDebug.cpp new file mode 100644 index 00000000..e30ad960 --- /dev/null +++ b/src/KingSystem/ActorSystem/actDebug.cpp @@ -0,0 +1,12 @@ +#include "KingSystem/ActorSystem/actDebug.h" +#include + +namespace ksys::act { + +SEAD_SINGLETON_DISPOSER_IMPL(ActorDebug) + +const char* ActorDebug::getNullStr(HashUnused*) { + return &sead::SafeString::cNullChar; +} + +} // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actDebug.h b/src/KingSystem/ActorSystem/actDebug.h new file mode 100644 index 00000000..5342d341 --- /dev/null +++ b/src/KingSystem/ActorSystem/actDebug.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "KingSystem/Utils/Types.h" + +namespace ksys::act { + +class ActorDebug { + SEAD_SINGLETON_DISPOSER(ActorDebug) +public: + struct HashUnused { + u32 hash = 0; + u32 b; + }; + + const char* getNullStr(HashUnused* u); + + u8 TEMP1[0x2F0]; + f32 mDispDistanceMultiplier; + u8 TEMP2[0x114]; +}; +KSYS_CHECK_SIZE_NX150(ActorDebug, 0x428); + +} // namespace ksys::act diff --git a/src/KingSystem/Map/CMakeLists.txt b/src/KingSystem/Map/CMakeLists.txt index dd604dc3..858d21a3 100644 --- a/src/KingSystem/Map/CMakeLists.txt +++ b/src/KingSystem/Map/CMakeLists.txt @@ -1,7 +1,13 @@ target_sources(uking PRIVATE mapTypes.h + mapDebug.cpp + mapDebug.h mapMubinIter.cpp mapMubinIter.h mapObject.cpp mapObject.h + mapObjectLink.cpp + mapObjectLink.h + mapPlacementMgr.cpp + mapPlacementMgr.h ) diff --git a/src/KingSystem/Map/mapDebug.cpp b/src/KingSystem/Map/mapDebug.cpp new file mode 100644 index 00000000..0269169b --- /dev/null +++ b/src/KingSystem/Map/mapDebug.cpp @@ -0,0 +1,3 @@ +#include "KingSystem/Map/mapDebug.h" + +namespace ksys::map {} // namespace ksys::map diff --git a/src/KingSystem/Map/mapDebug.h b/src/KingSystem/Map/mapDebug.h new file mode 100644 index 00000000..28c8b2cc --- /dev/null +++ b/src/KingSystem/Map/mapDebug.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace ksys::map { + +class Object; + +bool printDebugMsg(Object* object, const sead::SafeString& msg, const char* config_name); + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapObject.cpp b/src/KingSystem/Map/mapObject.cpp index 0fc9714a..92cfb6af 100644 --- a/src/KingSystem/Map/mapObject.cpp +++ b/src/KingSystem/Map/mapObject.cpp @@ -1,7 +1,371 @@ #include "KingSystem/Map/mapObject.h" +#include "KingSystem/ActorSystem/actBaseProcMgr.h" +#include "KingSystem/Utils/Debug.h" namespace ksys::map { Object::Object() = default; +Object::~Object() { + if (mLinkData != nullptr) { + mLinkData->release(this, true); + mLinkData = nullptr; + } } + +void Object::free() { + mId = 0; + _10 = nullptr; + _18 = nullptr; + _20 = nullptr; + + if (mProc) + mProc = nullptr; + + // TODO: figure out what this is + mFlags0.reset(Flag0::Freed); + + mHardModeFlags.reset(HardModeFlag::ActorCreated); + + if (mFlags0.isOn(Flag0::_80000)) + mFlags0.set(Flag0::_40000); + else + mFlags0.set(Flag0::_8); + + if (mLinkData) + mLinkData->field_57 = 0; +} + +// NON_MATCHING: functionally equivalent; CSEL instruction flipped +bool Object::getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const { + act::BaseProcMgr* instance = act::BaseProcMgr::instance(); + + if (instance == nullptr || !instance->isHighPriorityThread() || mProc == nullptr) + return accessor.acquire(nullptr); + + if (mProc->isInit() || mProc->isCalc()) + return accessor.acquire(mProc); + + return accessor.acquire(nullptr); +} + +act::Actor* Object::getActor() const { + return sead::DynamicCast(mProc); +} + +void Object::registerBaseProc(act::BaseProc* proc) { + const char* sActorStateStrings[4] = {"Init", "Calc", "Sleep", "Delete"}; + + if (mProc != nullptr && mProc != proc) { + sead::FixedSafeString<1000> message; + message.format("%p (%s:%p:%s) → (%s:%p:%s) \n", this, mProc->getName().cstr(), mProc, + sActorStateStrings[static_cast(mProc->getState())], + proc->getName().cstr(), proc, + sActorStateStrings[static_cast(proc->getState())]); + util::PrintDebug(message); + } + mProc = proc; + + mFlags0.set(Flag0::_80); + mFlags0.reset(Flag0::_80000000); + mHardModeFlags.set(HardModeFlag::ActorCreated); +} + +void Object::setBaseProcDirect(act::BaseProc* proc) { + mProc = proc; +} + +bool Object::checkActorDataFlag(const PlacementActors* pa, ActorData::Flag flag) const { + return pa->mActorData[mActorDataIdx].mFlags.isOnBit(flag); +} + +bool Object::isEnemyOrNpcOrActiveOrMapPassive() const { + if (mActorFlags8.isOn(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall)) + return true; + + auto pa = PlacementMgr::instance()->mPlacementActors; + if (pa == nullptr) + return false; + + return !checkActorDataFlag(pa, ActorData::Flag::MapPassiveOrFlag1); +} + +bool Object::isNpcOrActiveOrMapPassiveOrFlag1() const { + auto actFlags = mActorFlags8; + if (actFlags.isZero()) + return true; + + auto pa = PlacementMgr::instance()->mPlacementActors; + if (pa == nullptr) + return false; + + if (checkActorDataFlag(pa, ActorData::Flag::_16) || + actFlags.isOn(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall)) + return false; + + return checkActorDataFlag(pa, ActorData::Flag::MapPassiveOrFlag1); +} + +bool Object::isMapPassive(const PlacementActors* pa) const { + if (mActorFlags8.isZero()) + return true; + + if (pa == nullptr) + return false; + + if (pa->mActorData[mActorDataIdx].mFlags.isOnBit(ActorData::Flag::_16) || + mActorFlags8.isOn(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall)) + return false; + + return checkActorDataFlag(pa, ActorData::Flag::MapPassiveOrFlag1); +} + +bool Object::isEnemyOrNpc(const PlacementActors* pa) const { + return checkActorDataFlag(pa, ActorData::Flag::EnemyOrNpc_DisableFlashback); +} + +bool Object::isFlags8Cleared() const { + return mActorFlags8.isZero(); +} + +f32 Object::getDispDistance(const ActorData* data, bool get_diameter, u32 unused, + bool ignore_radius) const { + if (data->mFlags.isOnBit(ActorData::Flag::TraverseDistReset)) + return 0.0; + + f32 dist = getTraverseDist(data, get_diameter, unused, ignore_radius); + f32 mult = getDispDistanceMultiplier(); + + if (dist > 0.0) + return dist * mult; + else + return 100.0 * mult; +} + +f32 Object::getDispDistance(const PlacementActors* pa, bool get_diameter, + bool ignore_radius) const { + auto* dat = &pa->mActorData[mActorDataIdx]; + + return getDispDistance(dat, get_diameter, 0, ignore_radius); +} + +f32 Object::getDispDistance(bool get_diameter, bool ignore_radius) const { + auto pa = PlacementMgr::instance()->mPlacementActors; + + return getDispDistance(pa, get_diameter, ignore_radius); +} + +[[gnu::noinline]] f32 Object::getTraverseDist(const ActorData* data, bool get_diameter, u32, + bool ignore_radius) const { + using DFlag = ActorData::Flag; + + f32 dist = 0.0; + + if (mFlags.isOn(Flag::HasTraversePos) && !ignore_radius) { + mMubinIter.tryGetParamFloatByKey(&dist, "TraverseRadiusXZ"); + if (get_diameter) + dist = dist * 2; + } + + // TODO: inline here? + if (data->mFlags.isOnBit(DFlag::TraverseDistReset)) + return dist + 0.0; + + if (data->mFlags.isOnBit(DFlag::TraverseDist400) || + data->mFlags.isOnBit(DFlag::TraverseDist200) || + data->mFlags.isOnBit(DFlag::TraverseDist4000) || + data->mFlags.isOnBit(DFlag::TraverseDist800)) + return mTraverseDist + dist; + + if (data->mFlags.isOffBit(DFlag::TraverseDist2000)) + return mTraverseDist + dist; + + return mTraverseDist; +} + +f32 Object::getTraverseDistForLOD() const { + using DFlag = ActorData::Flag; + + auto* data = &PlacementMgr::instance()->mPlacementActors->mActorData[mActorDataIdx]; + f32 dist = 0.0; + + if (data->mFlags.isOnBit(ActorData::Flag::TraverseDistReset)) + return 0.0; + + if (data->mFlags.isOnBit(ActorData::Flag::TraverseDistReset)) + dist = 0.0; + + else if (data->mFlags.isOnBit(DFlag::TraverseDist400) || + data->mFlags.isOnBit(DFlag::TraverseDist200) || + data->mFlags.isOnBit(DFlag::TraverseDist4000) || + data->mFlags.isOnBit(DFlag::TraverseDist800)) + dist = mTraverseDist + 0.0; + + else if (data->mFlags.isOffBit(DFlag::TraverseDist2000)) + dist = mTraverseDist + 0.0; + else + dist = mTraverseDist; + + f32 mult = getDispDistanceMultiplier(); + + if (dist > 0.0) + return dist * mult; + else + return 100.0 * mult; +} + +sead::Vector3f Object::getScale() const { + sead::Vector3f vec; + + mMubinIter.getScale(&vec); + return vec; +} + +const char* Object::getUnitConfigName() const { + auto* mgr = PlacementMgr::instance(); + + if (mgr != nullptr && mgr->mPlacementActors != nullptr) + return mgr->mPlacementActors->mActorData[mActorDataIdx].mActorName.cstr(); + + return getUnitConfigNameFromByaml(); +} + +const char* Object::getUnitConfigNameFromByaml() const { + const char* result; + if (!mMubinIter.tryGetParamStringByKey(&result, "UnitConfigName")) + result = ""; + + return result; +} + +Object* Object::findPlacementLODLinkObject(const PlacementActors*) const { + if (!mLinkData) + return nullptr; + + ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD); + if (result) + return result->other_obj; + + return nullptr; +} + +Object* Object::findPlacementLODLinkObject() const { + if (!mLinkData) + return nullptr; + + ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD); + if (result) + return result->other_obj; + + return nullptr; +} + +const char* Object::getHashIdStringDebug() const { + act::ActorDebug::HashUnused t; + + const char* terminator; + + if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId")) + terminator = act::ActorDebug::instance()->getNullStr(&t); + else + terminator = ""; + + return terminator; +} + +const char* Object::getHashIdStringDebug_0() const { + act::ActorDebug::HashUnused t; + + const char* terminator; + + if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId")) + terminator = act::ActorDebug::instance()->getNullStr(&t); + else + terminator = ""; + + return terminator; +} + +void* Object::getRails() const { + if (!mLinkData) + return nullptr; + + return mLinkData->mRails; +} + +void* Object::getRails_0() const { + if (!mLinkData) + return nullptr; + + return mLinkData->mRails; +} + +bool Object::allocLinkData(sead::Heap* heap) { + mLinkData = new (heap) ObjectLinkData; + + return mLinkData != nullptr; +} + +bool Object::hasGenGroup() const { + if (!mLinkData) + return false; + + return mLinkData->mGenGroup != nullptr; +} + +void Object::incrementLinkNum() { + if (mNumLinksPointingToMe != 0xFF) { + mNumLinksPointingToMe += 1; + return; + } + + auto name = sead::SafeString(getUnitConfigName()); + + if (name == "LinkTagNone") { + // More than 255 actors are specified in one generation group. + // If it is not a test, consult the programmer. + printDebugMsg(this, + "一つの生成グループに 255 以上のアクタが指定されています。" + "テストで無ければプログラマに相談", + nullptr); + return; + } + + // We have exceeded the expected number of links. + // If it's not a test, talk to your programmer. + printDebugMsg(this, "リンクの想定数を越えました。テストで無ければプログラマに相談", nullptr); +} + +void Object::decrementLinkNum() { + if (mNumLinksPointingToMe != 0) + --mNumLinksPointingToMe; +} + +sead::Vector3f Object::getRotate() const { + sead::Vector3f result; + mMubinIter.getRotate(&result); + + return result; +} + +// NON_MATCHING: Vec3f copy incorrect +void Object::getTraversePosAndLoadDistance(sead::Vector3f* traverse_pos, f32* load_dist) const { + if (mFlags.isOn(Flag::HasTraversePos)) { + mMubinIter.tryGetFloatArrayByKey(&traverse_pos->x, "TraversePos"); + } else { + *traverse_pos = mTranslate; + } + + *load_dist = getLoadDistance(false); +} + +void Object::getUniqueName(const char** out) const { + if (mFlags.isOff(Flag::HasUniqueName) || !mMubinIter.tryGetParamStringByKey(out, "UniqueName")) + *out = ""; +} + +void Object::setTranslate(const sead::Vector3f& translate) { + mTranslate = translate; +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapObject.h b/src/KingSystem/Map/mapObject.h index 648ad3a2..3f62b226 100644 --- a/src/KingSystem/Map/mapObject.h +++ b/src/KingSystem/Map/mapObject.h @@ -1,8 +1,15 @@ #pragma once #include +#include #include +#include "KingSystem/ActorSystem/actActor.h" +#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h" +#include "KingSystem/ActorSystem/actDebug.h" +#include "KingSystem/Map/mapDebug.h" #include "KingSystem/Map/mapMubinIter.h" +#include "KingSystem/Map/mapObjectLink.h" +#include "KingSystem/Map/mapPlacementMgr.h" #include "KingSystem/Utils/Types.h" namespace ksys::act { @@ -11,14 +18,30 @@ class BaseProc; namespace ksys::map { -class LinkData; +class Object; + +class ObjectLinkData; +struct ObjectLink; +struct ObjectLinkArray; + +class LinkTag; // FIXME: incomplete class Object { public: // TODO: rename - enum class Flag0 { - + enum class Flag0 : u32 { + _2 = 0x2, + _4 = 0x4, + _8 = 0x8, + _10 = 0x10, + _20 = 0x20, + _80 = 0x80, + _8000 = 0x8000, + _40000 = 0x40000, + _80000 = 0x80000, + Freed = 0xC65067E6, + _80000000 = 0x80000000, }; enum class Flag { @@ -39,11 +62,6 @@ public: IsTurnActorBowChargeAndHasBasicSigLink = 0x8000, }; - // TODO: rename - enum class ActorFlag8 { - - }; - enum class HardModeFlag { ActorCreated = 0x1, /// This actor only spawns in master mode (hard mode). @@ -57,6 +75,69 @@ public: Object(); ~Object(); + void free(); + + bool getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const; + act::Actor* getActor() const; + void registerBaseProc(act::BaseProc* proc); + void setBaseProcDirect(act::BaseProc* proc); + + bool isEnemyOrNpcOrActiveOrMapPassive() const; + bool isFlags8Cleared() const; + bool isNpcOrActiveOrMapPassiveOrFlag1() const; + bool isMapPassive(const PlacementActors* pa) const; + bool checkActorDataFlag(const PlacementActors* pa, ActorData::Flag flag) const; + bool isEnemyOrNpc(const PlacementActors* pa) const; + + f32 getDispDistanceMultiplier() const { + f32 mult = 1.0; + + if (act::ActorDebug::instance() != nullptr) + mult = act::ActorDebug::instance()->mDispDistanceMultiplier; + + return mult; + } + + f32 getDispDistance(const PlacementActors* pa, bool get_diameter, bool ignore_radius) const; + f32 getDispDistance(const ActorData* data, bool get_diameter, u32 unused, + bool ignore_radius) const; + f32 getDispDistance(bool get_diameter, bool ignore_radius) const; + + f32 getTraverseDist(const ActorData* data, bool get_diameter, u32 unused, + bool ignore_radius) const; + f32 getTraverseDistForLOD() const; + sead::Vector3f getScale() const; + + const char* getUnitConfigName() const; + const char* getUnitConfigNameFromByaml() const; + + Object* findPlacementLODLinkObject(const PlacementActors* unused) const; + Object* findPlacementLODLinkObject() const; + + const char* getHashIdStringDebug() const; + const char* getHashIdStringDebug_0() const; + + void* getRails() const; + void* getRails_0() const; + bool allocLinkData(sead::Heap* heap); + bool hasGenGroup() const; + void incrementLinkNum(); + void decrementLinkNum(); + + sead::Vector3f getRotate() const; + void getTraversePosAndLoadDistance(sead::Vector3f* traverse_pos, f32* load_dist) const; + void getUniqueName(const char** out) const; + void setTranslate(const sead::Vector3f& translate); + + // TODO: + void initData(MubinIter* iter, u8 idx, u32 actor_data_idx, ActorData* data); + void initRevivalGameDataFlagAndMiscFlags(ActorData* data, bool zero); + act::BaseProc* getActor_0(bool a1) const; + LinkTag* x_10(bool a1) const; + f32 getLoadDistance(bool get_diameter) const; + Object* findSrcLODLinkObject() const; + bool isRevivalGameDataFlagOn() const; + auto getFlags0() const { return mFlags0; } auto getFlags() const { return mFlags; } auto getActorFlags8() const { return mActorFlags8; } @@ -71,19 +152,17 @@ public: const MubinIter& getMubinIter() const { return mMubinIter; } act::BaseProc* getProc() const { return mProc; } - LinkData* getLinkData() const { return mLinkData; } + ObjectLinkData* getLinkData() const { return mLinkData; } u32 getRevivalGameDataFlagHash() const { return mRevivalGameDataFlagHash; } u32 getHashId() const { return mHashId; } const sead::Vector3f& getTranslate() const { return mTranslate; } - void setTranslate(const sead::Vector3f& translate); - auto getTraverseDist() const { return mTraverseDist; } auto getTraverseDistInt() const { return mTraverseDistInt; } private: - sead::TypedBitFlag mFlags0; + sead::TypedBitFlag> mFlags0; u16 mActorDataIdx = 0xffff; sead::TypedBitFlag mFlags; u8 mIdx = 0; @@ -97,7 +176,7 @@ private: void* _20 = nullptr; MubinIter mMubinIter; act::BaseProc* mProc = nullptr; - LinkData* mLinkData = nullptr; + ObjectLinkData* mLinkData = nullptr; u32 mRevivalGameDataFlagHash = 0xffffffff; void* _50 = nullptr; u32 mHashId = 0; diff --git a/src/KingSystem/Map/mapObjectLink.cpp b/src/KingSystem/Map/mapObjectLink.cpp new file mode 100644 index 00000000..b2ab0502 --- /dev/null +++ b/src/KingSystem/Map/mapObjectLink.cpp @@ -0,0 +1,21 @@ +#include "KingSystem/Map/mapObjectLink.h" + +namespace ksys::map { + +ObjectLinkData::ObjectLinkData() = default; + +act::BaseProc* ObjectLink::getObjectProc() const { + if (other_obj == nullptr) + return nullptr; + + return other_obj->getActor_0(false); +} + +bool ObjectLink::getObjectProcWithAccessor(act::ActorLinkConstDataAccess& accessor) const { + if (other_obj == nullptr) + return accessor.acquire(nullptr); + else + return other_obj->getActorWithAccessor(accessor); +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapObjectLink.h b/src/KingSystem/Map/mapObjectLink.h new file mode 100644 index 00000000..09ef72e0 --- /dev/null +++ b/src/KingSystem/Map/mapObjectLink.h @@ -0,0 +1,98 @@ +#pragma once + +#include "KingSystem/Map/mapObject.h" + +namespace ksys::map { + +class Object; + +enum class MapLinkDefType { + BasicSig = 0, + AxisX = 1, + AxisY = 2, + AxisZ = 3, + NAxisX = 4, + NAxisY = 5, + NAxisZ = 6, + GimmickSuccess = 7, + VelocityControl = 8, + BasicSigOnOnly = 9, + Remains = 10, + DeadUp = 11, + LifeZero = 12, + Stable = 13, + ChangeAtnSig = 14, + Create = 15, + Delete = 16, + MtxCopyCreate = 17, + Freeze = 18, + ForbidAttention = 19, + SyncLink = 20, + CopyWaitRevival = 21, + OffWaitRevival = 22, + Recreate = 23, + AreaCol = 24, + SensorBlind = 25, + ForSale = 26, + ModelBind = 27, + PlacementLOD = 28, + DemoMember = 29, + PhysSystemGroup = 30, + StackLink = 31, + FixedCs = 32, + HingeCs = 33, + LimitHingeCs = 34, + SliderCs = 35, + PulleyCs = 36, + BAndSCs = 37, + BAndSLimitAngYCs = 38, + CogWheelCs = 39, + RackAndPinionCs = 40, + Reference = 41, + Invalid = 42, +}; + +struct ObjectLink { + act::BaseProc* getObjectProc() const; + bool getObjectProcWithAccessor(act::ActorLinkConstDataAccess& accessor) const; + + Object* other_obj; + u32 type; + MubinIter iter; +}; +KSYS_CHECK_SIZE_NX150(ObjectLink, 0x20); + +struct ObjectLinkArray { + ObjectLink* findLinkWithType(MapLinkDefType link_type); + u32 num_links = 0; + ObjectLink* links = nullptr; +}; +KSYS_CHECK_SIZE_NX150(ObjectLinkArray, 0x10); + +class ObjectLinkData { +public: + ObjectLinkData(); + + void release(Object* obj, bool a1); + + Object* mCreateLinksSrcObj = nullptr; + Object* mDeleteLinksSrcObj = nullptr; + u32 mNumLinksReference = 0; + + void* mLinksReference = nullptr; + ObjectLinkArray mLinksOther{}; + ObjectLinkArray mLinksCs{}; + ObjectLinkArray mLinksToSelf{}; + + u32 field_50 = 0; + bool field_54 = false; + bool mAppearFade = false; + bool mNoAutoDemoMember = false; + bool field_57 = false; + + void* mGenGroup = nullptr; + void* mRails = nullptr; +}; +KSYS_CHECK_SIZE_NX150(ObjectLinkData, 0x68); + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapPlacementMgr.cpp b/src/KingSystem/Map/mapPlacementMgr.cpp new file mode 100644 index 00000000..b6114392 --- /dev/null +++ b/src/KingSystem/Map/mapPlacementMgr.cpp @@ -0,0 +1,7 @@ +#include "KingSystem/Map/mapPlacementMgr.h" + +namespace ksys::map { + +SEAD_SINGLETON_DISPOSER_IMPL(PlacementMgr) + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapPlacementMgr.h b/src/KingSystem/Map/mapPlacementMgr.h new file mode 100644 index 00000000..adac1cc2 --- /dev/null +++ b/src/KingSystem/Map/mapPlacementMgr.h @@ -0,0 +1,119 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "KingSystem/Utils/Types.h" + +namespace ksys::map { + +// TODO: rename +enum class ActorFlag8 { + EnemyOrNpcOrActiveOrAreaOrAirWall = 0x2, + MapPassiveOrFlag1 = 0x4, +}; + +class ActorData { +public: + enum class Flag { + MapPassive = 0, + _1 = 1, + _2 = 2, + _3 = 3, + _4 = 4, + _5 = 5, + _6 = 6, + _7 = 7, + MapConstActive = 8, + TraverseDist200 = 9, + TraverseDist400 = 10, + TraverseDist800 = 11, + TraverseDistReset = 12, + TraverseDist2000 = 13, + TraverseDist4000 = 14, + _15 = 15, + _16 = 16, + RevivalEnable = 17, + RevivalForUsed = 18, + RevivalForDrop = 19, + RevivalRandom = 20, + RevivalBloodyMoon = 21, + RevivalUnderGodTimeOrNoneForUsed = 22, + EnableRemainsScene = 23, + _24 = 24, + EnemyOrNpc_DisableFlashback = 25, + _26 = 26, + LimitYDiff = 27, + IsGrassCut = 28, + HasFar = 29, + Fairy = 30, + UnderGodForest = 31, + + EnemyOrNpc = 32, + MapConstPassive = 33, + RandomCreateNotRain = 34, + _35 = 35, + MessageDialogViewBoard = 36, + _37 = 37, + NpcOrNonGanonAndNonGuardianEnemy = 38, + IgnoreBoundingAtAreaCulling = 39, + _40 = 40, + EnemyHuge = 41, + Enemy = 42, + _43 = 43, + EnemyLookOrGrassCutTagOrFirePillarOrDgnWater = 44, + _45 = 45, + MapPassiveOrFlag1 = 46, + _47 = 47, + _48 = 48, + SheikSensorTargetDeadOrAlive = 49, + Dragon = 50, + TreeOrBush = 51, + GuardianC = 52, + _53 = 53, + HasStopTimerFlag = 54, + AllRadarOrZukanActor = 55, + NoCreateForStackLink = 56, + OnLowTree = 57, + _58 = 58, + _59 = 59, + _60 = 60, + _61 = 61, + _62 = 62, + _63 = 63, + }; + + sead::TypedLongBitFlag<64, Flag, sead::Atomic> mFlags; + sead::TypedBitFlag mActorFlags8; + u8 TEMP[0x13F]; + sead::FixedSafeString<64> mActorName; +}; +KSYS_CHECK_SIZE_NX150(ActorData, 0x1A0); + +class PlacementActors { +public: + u8 TEMP1[0x538]; + sead::SafeArray mActorData; + u8 TEMP2[0x46598]; +}; +KSYS_CHECK_SIZE_NX150(PlacementActors, 0x2A80D0); + +class PlacementMgr { + SEAD_SINGLETON_DISPOSER(PlacementMgr) +public: + enum class MgrFlag { + _1000000 = 0x1000000, + }; + + u8 TEMP1[0x1D0]; + PlacementActors* mPlacementActors; + u8 TEMP2[0x48C]; + sead::TypedBitFlag> mFlags; + u8 TEMP3[0x190]; +}; +KSYS_CHECK_SIZE_NX150(PlacementMgr, 0x818); + +} // namespace ksys::map