summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortheo3 <arisstephenson2@gmail.com>2021-06-28 10:05:07 -0700
committertheo3 <arisstephenson2@gmail.com>2021-07-01 21:02:46 -0700
commit4cba2eb093fbc452db88e33643b3ca293ff02213 (patch)
tree581b36877d8b17b986c12a20a351b229dfd56bdf /src
parent112c1f987d3831df97f46c0f9e4ae977fba59484 (diff)
ksys::map placement classes
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/ActorSystem/actActorConstDataAccess.h1
-rw-r--r--src/KingSystem/ActorSystem/actActorCreator.h3
-rw-r--r--src/KingSystem/ActorSystem/actBaseProc.h1
-rw-r--r--src/KingSystem/ActorSystem/actInfoData.h1
-rw-r--r--src/KingSystem/Map/CMakeLists.txt10
-rw-r--r--src/KingSystem/Map/mapClusteredRenderer.cpp1
-rw-r--r--src/KingSystem/Map/mapClusteredRenderer.h10
-rw-r--r--src/KingSystem/Map/mapObject.cpp295
-rw-r--r--src/KingSystem/Map/mapObject.h84
-rw-r--r--src/KingSystem/Map/mapObjectGenGroup.cpp1
-rw-r--r--src/KingSystem/Map/mapObjectGenGroup.h7
-rw-r--r--src/KingSystem/Map/mapObjectLink.cpp235
-rw-r--r--src/KingSystem/Map/mapObjectLink.h44
-rw-r--r--src/KingSystem/Map/mapPlacementActors.cpp1
-rw-r--r--src/KingSystem/Map/mapPlacementActors.h126
-rw-r--r--src/KingSystem/Map/mapPlacementMgr.cpp126
-rw-r--r--src/KingSystem/Map/mapPlacementMgr.h236
-rw-r--r--src/KingSystem/Map/mapPlacementTree.cpp13
-rw-r--r--src/KingSystem/Map/mapPlacementTree.h39
-rw-r--r--src/KingSystem/Map/mapStagePreActorCache.cpp7
-rw-r--r--src/KingSystem/Map/mapStagePreActorCache.h25
21 files changed, 1071 insertions, 195 deletions
diff --git a/src/KingSystem/ActorSystem/actActorConstDataAccess.h b/src/KingSystem/ActorSystem/actActorConstDataAccess.h
index 0244893b..b78e9fbc 100644
--- a/src/KingSystem/ActorSystem/actActorConstDataAccess.h
+++ b/src/KingSystem/ActorSystem/actActorConstDataAccess.h
@@ -92,6 +92,7 @@ public:
f32 getAttackSpHitRatio() const;
s32 getAttackPower() const;
+ bool checkLinkTagActivated(bool a, bool b);
map::ObjectLinkData* getMapObjectLinkData() const;
map::Object* getMapObject() const;
diff --git a/src/KingSystem/ActorSystem/actActorCreator.h b/src/KingSystem/ActorSystem/actActorCreator.h
index d25e745f..ae80dd23 100644
--- a/src/KingSystem/ActorSystem/actActorCreator.h
+++ b/src/KingSystem/ActorSystem/actActorCreator.h
@@ -43,6 +43,9 @@ public:
void setActorFactory(ActorFactory* factory) { mActorFactory = factory; }
bool get5a() const { return _5a; }
+ sead::OffsetList<Actor>& getActorList() { return mActorList; }
+ sead::CriticalSection& getCS() { return mActorListCS; }
+
static void addScale(InstParamPack& pack, float scale);
static void addScale(InstParamPack& pack, const sead::Vector3f& scale);
static bool isAITreeParam(const InstParamPack::Entry& entry);
diff --git a/src/KingSystem/ActorSystem/actBaseProc.h b/src/KingSystem/ActorSystem/actBaseProc.h
index 6a55c2fb..761acd4b 100644
--- a/src/KingSystem/ActorSystem/actBaseProc.h
+++ b/src/KingSystem/ActorSystem/actBaseProc.h
@@ -102,6 +102,7 @@ public:
bool isDeletedOrDeleting() const {
return mState == State::Delete || mStateFlags.isOn(StateFlags::RequestDelete);
}
+ bool isDeleteOrInvalid() const { return mState >= act::BaseProc::State::Delete; }
/// For BaseProcLink or ActorLinkConstDataAccess.
bool acquire(ActorLinkConstDataAccess& accessor);
diff --git a/src/KingSystem/ActorSystem/actInfoData.h b/src/KingSystem/ActorSystem/actInfoData.h
index bdaf24eb..b4f20b63 100644
--- a/src/KingSystem/ActorSystem/actInfoData.h
+++ b/src/KingSystem/ActorSystem/actInfoData.h
@@ -126,6 +126,7 @@ public:
u32 getModelFlags(const char* actor) const;
bool getVariationMatAnim(const char* actor, const char** anim, f32* frame) const;
bool getName(al::ByamlIter* iter, const char** name, s32 idx) const;
+ bool sub_7100D30DF8(InvalidLifeConditions& info, const sead::Vector3f& vec);
const char* getString(const char* actor, const char* key,
const sead::SafeString& default_ = sead::SafeString::cEmptyString,
diff --git a/src/KingSystem/Map/CMakeLists.txt b/src/KingSystem/Map/CMakeLists.txt
index 858d21a3..47c18a8c 100644
--- a/src/KingSystem/Map/CMakeLists.txt
+++ b/src/KingSystem/Map/CMakeLists.txt
@@ -1,4 +1,6 @@
target_sources(uking PRIVATE
+ mapClusteredRenderer.cpp
+ mapClusteredRenderer.h
mapTypes.h
mapDebug.cpp
mapDebug.h
@@ -6,8 +8,16 @@ target_sources(uking PRIVATE
mapMubinIter.h
mapObject.cpp
mapObject.h
+ mapObjectGenGroup.cpp
+ mapObjectGenGroup.h
mapObjectLink.cpp
mapObjectLink.h
+ mapPlacementActors.cpp
+ mapPlacementActors.h
mapPlacementMgr.cpp
mapPlacementMgr.h
+ mapPlacementTree.cpp
+ mapPlacementTree.h
+ mapStagePreActorCache.cpp
+ mapStagePreActorCache.h
)
diff --git a/src/KingSystem/Map/mapClusteredRenderer.cpp b/src/KingSystem/Map/mapClusteredRenderer.cpp
new file mode 100644
index 00000000..20b3f086
--- /dev/null
+++ b/src/KingSystem/Map/mapClusteredRenderer.cpp
@@ -0,0 +1 @@
+#include "KingSystem/Map/mapClusteredRenderer.h"
diff --git a/src/KingSystem/Map/mapClusteredRenderer.h b/src/KingSystem/Map/mapClusteredRenderer.h
new file mode 100644
index 00000000..91103d68
--- /dev/null
+++ b/src/KingSystem/Map/mapClusteredRenderer.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace ksys::map {
+
+class ClusteredRenderer {
+public:
+ void startThread();
+};
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapObject.cpp b/src/KingSystem/Map/mapObject.cpp
index 6d62d9c2..d198ab44 100644
--- a/src/KingSystem/Map/mapObject.cpp
+++ b/src/KingSystem/Map/mapObject.cpp
@@ -1,11 +1,24 @@
#include "KingSystem/Map/mapObject.h"
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
+#include "KingSystem/ActorSystem/actInfoData.h"
+#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Map/mapObjectLink.h"
+#include "KingSystem/Map/mapPlacementMgr.h"
+#include "KingSystem/Map/mapStagePreActorCache.h"
+#include "KingSystem/Terrain/teraSystem.h"
#include "KingSystem/Utils/Debug.h"
namespace ksys::map {
-Object::Object() = default;
+// NON_MATCHING
+Object::Object() {
+ mHardModeFlags.makeAllZero();
+ _b = 0xFF;
+ _18 = nullptr;
+ _20 = nullptr;
+ mProc = nullptr;
+ mLinkData = nullptr;
+}
Object::~Object() {
if (mLinkData != nullptr) {
@@ -23,9 +36,7 @@ void Object::free() {
if (mProc)
mProc = nullptr;
- // TODO: figure out what this is
- mFlags0.reset(Flag0::Freed);
-
+ mFlags0.reset(Flag0::ResetOnFreed);
mHardModeFlags.reset(HardModeFlag::ActorCreated);
if (mFlags0.isOn(Flag0::_80000))
@@ -37,25 +48,99 @@ void Object::free() {
mLinkData->field_57 = 0;
}
-// NON_MATCHING: functionally equivalent; CSEL instruction flipped
-bool Object::getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const {
+// NON_MATCHING
+void Object::initData(MubinIter* iter, u8 idx, u32 actor_data_idx, ActorData* data) {
+ mActorDataIdx = 0xFFFF;
+ mFlags0.makeAllZero();
+ mRevivalGameDataFlagHash = gdt::InvalidHandle;
+ mId = 0;
+ mActorFlags8.makeAllZero();
+ mFlags.makeAllZero();
+ mIdx = 0;
+ mNumLinksPointingToMe = 0;
+ mStaticCompoundId = 0xFFFF;
+ _18 = nullptr;
+ _20 = nullptr;
+ _10 = nullptr;
+ _50 = nullptr;
+ mTraverseDist = 0.0f;
+ mTraverseDistInt = 0;
+ mHashId = 0;
+ mHardModeFlags.makeAllZero();
+ _b = 0xFF;
+ mProc = nullptr;
+ mLinkData = nullptr;
+ iter->tryGetFloatArrayByKey(&mTranslate.x, "Translate");
+ mMubinIter = *iter;
+
+ u32 hash = 0;
+ iter->tryGetParamUIntByKey(&hash, "HashId");
+ if (hash == 0)
+ hash = 0xFFFFFFFF;
+ mHashId = hash;
+
+ mIdx = idx;
+ mFlags0.setDirect(Flag0::_8);
+ mNumLinksPointingToMe = 0;
+ _10 = nullptr;
+ _18 = nullptr;
+ _20 = nullptr;
+ mStaticCompoundId = 0xFFFF;
+ mActorDataIdx = actor_data_idx;
+ mProc = nullptr;
+ mLinkData = nullptr;
+ mActorFlags8 = data->mActorFlags8;
+
+ auto* fr = StagePreActorCache::instance()->getForestRenderer();
+ if (fr != nullptr) {
+ if (fr->x_7(mTranslate) != -1) {
+ mFlags0.set(Flag0::_10);
+ }
+ }
+ initRevivalGameDataFlagAndMiscFlags(data, false);
+}
+
+act::BaseProc* Object::tryGetProc(bool force) {
+ auto* bpm = act::BaseProcMgr::instance();
+ if (bpm == nullptr || !bpm->isHighPriorityThread())
+ return nullptr;
+ if (mProc == nullptr)
+ return nullptr;
+
+ act::BaseProc* result = nullptr;
+ if (!mProc->isDeleteOrInvalid())
+ result = mProc;
+ if (mProc->isDeleteOrInvalid() || force)
+ return result;
+
+ if (!mProc->isInit())
+ bpm->isAccessingProcSafe(mProc, nullptr);
+ return mProc;
+}
+
+act::Actor* Object::tryGetActor(bool force) {
+ auto* proc = tryGetProc(force);
+ return sead::DynamicCast<act::Actor>(proc);
+}
+
+bool Object::getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) {
act::BaseProcMgr* instance = act::BaseProcMgr::instance();
if (instance == nullptr || !instance->isHighPriorityThread() || mProc == nullptr)
return accessor.acquire(nullptr);
- if (mProc->isInit() || mProc->isCalc())
+ if (!mProc->isDeleteOrInvalid())
return accessor.acquire(mProc);
return accessor.acquire(nullptr);
}
-act::Actor* Object::getActor() const {
+act::Actor* Object::getActor() {
return sead::DynamicCast<act::Actor>(mProc);
}
void Object::registerBaseProc(act::BaseProc* proc) {
- const char* sActorStateStrings[4] = {"Init", "Calc", "Sleep", "Delete"};
+ static const char* sActorStateStrings[4] = {"Init", "Calc", "Sleep", "Delete"};
if (mProc != nullptr && mProc != proc) {
sead::FixedSafeString<1000> message;
@@ -65,7 +150,7 @@ void Object::registerBaseProc(act::BaseProc* proc) {
sActorStateStrings[static_cast<s32>(proc->getState())]);
util::PrintDebug(message);
}
- mProc = proc;
+ setBaseProcDirect(proc);
mFlags0.set(Flag0::_80);
mFlags0.reset(Flag0::_80000000);
@@ -93,7 +178,7 @@ bool Object::isEnemyOrNpcOrActiveOrMapPassive() const {
bool Object::isNpcOrActiveOrMapPassiveOrFlag1() const {
auto actFlags = mActorFlags8;
- if (actFlags.isZero())
+ if (isFlags8Cleared())
return true;
auto pa = PlacementMgr::instance()->mPlacementActors;
@@ -108,13 +193,13 @@ bool Object::isNpcOrActiveOrMapPassiveOrFlag1() const {
}
bool Object::isMapPassive(const PlacementActors* pa) const {
- if (mActorFlags8.isZero())
+ if (isFlags8Cleared())
return true;
if (pa == nullptr)
return false;
- if (pa->mActorData[mActorDataIdx].mFlags.isOnBit(ActorData::Flag::_16) ||
+ if (checkActorDataFlag(pa, ActorData::Flag::_16) ||
mActorFlags8.isOn(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall))
return false;
@@ -146,20 +231,17 @@ f32 Object::getDispDistance(const ActorData* data, bool get_diameter, u32 unused
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) {
@@ -186,22 +268,18 @@ f32 Object::getDispDistance(bool get_diameter, bool ignore_radius) const {
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
@@ -217,7 +295,6 @@ f32 Object::getTraverseDistForLOD() const {
sead::Vector3f Object::getScale() const {
sead::Vector3f vec;
-
mMubinIter.getScale(&vec);
return vec;
}
@@ -235,7 +312,6 @@ const char* Object::getUnitConfigNameFromByaml() const {
const char* result;
if (!mMubinIter.tryGetParamStringByKey(&result, "UnitConfigName"))
result = "";
-
return result;
}
@@ -246,7 +322,6 @@ Object* Object::findPlacementLODLinkObject(const PlacementActors*) const {
ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD);
if (result)
return result->other_obj;
-
return nullptr;
}
@@ -254,75 +329,196 @@ Object* Object::findPlacementLODLinkObject() const {
if (!mLinkData)
return nullptr;
- ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD);
+ ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType_0(MapLinkDefType::PlacementLOD);
if (result)
return result->other_obj;
-
return nullptr;
}
const char* Object::getHashIdStringDebug() const {
- act::ActorDebug::HashUnused t;
+ return getHashIdStringDebug_0();
+}
+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;
}
-const char* Object::getHashIdStringDebug_0() const {
- act::ActorDebug::HashUnused t;
+void Object::unlinkProc(bool force) {
+ bool set = false;
+ auto flag = Flag0::ResetOnUnlinkFailed;
- const char* terminator;
+ if (!tera::checkTeraSystemStatus()) {
+ auto* thread = sead::ThreadMgr::instance()->getCurrentThread();
+ thread->getPriority();
+ }
+ static_cast<void>(mFlags0.isZero());
- if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId"))
- terminator = act::ActorDebug::instance()->getNullStr(&t);
+ if (force || mFlags0.isOn(Flag0::ActorCreated))
+ set = true;
+ else if (checkActorDataFlag(PlacementMgr::instance()->mPlacementActors,
+ ActorData::Flag::RevivalEnable))
+ set = isRevivalGameDataFlagOn();
+
+ if (set)
+ flag = Flag0::ResetOnUnlink;
+
+ mFlags0.reset(flag);
+ mProc = nullptr;
+}
+
+bool Object::checkRevivalFlag(ActorData::Flag bit) const {
+ if (bit == ActorData::Flag::RevivalEnable || bit == ActorData::Flag::RevivalForUsed ||
+ bit == ActorData::Flag::RevivalForDrop) {
+ if (getActorData().mFlags.isOffBit(bit))
+ return false;
+ return isRevivalGameDataFlagOn();
+ }
+ return false;
+}
+
+bool Object::isRevivalGameDataFlagOn() const {
+ bool x = false;
+ gdt::Manager::instance()->getBool(mRevivalGameDataFlagHash, &x, true);
+ return x;
+}
+
+void Object::setRevivalFlagValueIf(ActorData::Flag bit, bool value) {
+ if (bit == ActorData::Flag::RevivalEnable || bit == ActorData::Flag::RevivalForUsed ||
+ bit == ActorData::Flag::RevivalForDrop) {
+ if (getActorData().mFlags.isOnBit(bit)) {
+ setRevivalFlagValue(value);
+ }
+ }
+}
+
+void Object::setRevivalFlagValue(bool value) {
+ gdt::Manager::instance()->setBool(value, mRevivalGameDataFlagHash);
+}
+
+// NON_MATCHING
+bool Object::x_18() const {
+ act::InfoData::InvalidLifeConditions info;
+ const char* s;
+ auto* id = act::InfoData::instance();
+
+ if (PlacementMgr::instance() != nullptr &&
+ PlacementMgr::instance()->mPlacementActors != nullptr)
+ s = PlacementMgr::instance()->mPlacementActors->mActorData[mActorDataIdx].mActorName.cstr();
else
- terminator = "";
+ s = getUnitConfigNameFromByaml();
+ id->getInvalidLifeConditions(s, info);
- return terminator;
+ sead::Vector3f temp = mTranslate;
+ return !id->sub_7100D30DF8(info, temp);
}
-void* Object::getRails() const {
- if (!mLinkData)
- return nullptr;
+// NON_MATCHING
+bool Object::setupTargetLinks(Object* src, ObjectLink* link, sead::Heap* heap) {
+ if (mNumLinksPointingToMe == 0)
+ return false;
- return mLinkData->mRails;
+ if (mLinkData == nullptr) {
+ mLinkData = new (heap) ObjectLinkData();
+ if (mLinkData == nullptr)
+ return false;
+ }
+
+ if (mLinkData->mLinksToSelf.links != nullptr)
+ return mLinkData->sub_7100D4EC40(src, link, this);
+
+ if (!mLinkData->allocLinksToSelf(mNumLinksPointingToMe, heap))
+ return false;
+
+ return mLinkData->sub_7100D4EC40(src, link, this);
+}
+
+bool Object::checkCreateOrDeleteLinkObjRevival() const {
+ if (mLinkData != nullptr)
+ return mLinkData->checkCreateOrDeleteLinkObjRevival();
+ return false;
+}
+
+bool Object::shouldSkipSpawn() const {
+ if (checkTraverseFlags() || shouldSkipSpawn_(false))
+ return true;
+ return checkCreateOrDeleteLinkObjRevival();
+}
+
+bool Object::checkTraverseFlags() const {
+ return mFlags0.isOn(Flag0::_500400);
+}
+
+// NON_MATCHING
+bool Object::x_20() const {
+ if (getActorData().mFlags.isOffBit(ActorData::Flag::RevivalEnable))
+ return false;
+
+ if (mFlags0.isOff(Flag0::_400400))
+ return false;
+
+ if (!shouldSkipSpawn_(false)) {
+ return checkCreateOrDeleteLinkObjRevival();
+ }
+ return false;
+}
+
+void Object::onBaseProcCreated(act::BaseProc* actor) {
+ if (actor != nullptr) {
+ registerBaseProc(actor);
+ mFlags0.set(Flag0::ActorCreated);
+ } else {
+ mFlags0.reset(Flag0::_80002106);
+ }
+}
+
+void Object::spawnGenGroupActorsIfNeeded(Object* obj) {
+ if (mLinkData != nullptr)
+ mLinkData->sub_7100D4FB78(obj);
+}
+
+void Object::setFieldATrue() {
+ if (mActorFlags8.isOn(ActorFlag8::MapPassive) || mActorFlags8.isOn(ActorFlag8::_8)) {
+ mActorFlags8.reset(ActorFlag8::MapPassive);
+ mActorFlags8.reset(ActorFlag8::_8);
+ mActorFlags8.set(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall);
+ }
+}
+
+void* Object::getRails() const {
+ return getRails_0();
}
void* Object::getRails_0() const {
- if (!mLinkData)
+ if (mLinkData == nullptr)
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;
+ mNumLinksPointingToMe++;
return;
}
- auto name = sead::SafeString(getUnitConfigName());
-
- if (name == "LinkTagNone") {
+ if (sead::SafeString(getUnitConfigName()) == "LinkTagNone") {
// More than 255 actors are specified in one generation group.
// If it is not a test, consult the programmer.
printDebugMsg(this,
@@ -345,18 +541,15 @@ void Object::decrementLinkNum() {
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)) {
+ if (mFlags.isOn(Flag::HasTraversePos))
mMubinIter.tryGetFloatArrayByKey(&traverse_pos->x, "TraversePos");
- } else {
+ else
*traverse_pos = mTranslate;
- }
-
*load_dist = getLoadDistance(false);
}
diff --git a/src/KingSystem/Map/mapObject.h b/src/KingSystem/Map/mapObject.h
index 0bc7fb5e..10e9d3c5 100644
--- a/src/KingSystem/Map/mapObject.h
+++ b/src/KingSystem/Map/mapObject.h
@@ -6,26 +6,26 @@
#include "KingSystem/ActorSystem/actActor.h"
#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
#include "KingSystem/ActorSystem/actDebug.h"
+#include "KingSystem/GameData/gdtFlagHandle.h"
#include "KingSystem/Map/mapDebug.h"
#include "KingSystem/Map/mapMubinIter.h"
+#include "KingSystem/Map/mapPlacementActors.h"
#include "KingSystem/Map/mapPlacementMgr.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::act {
class BaseProc;
-}
+class BaseProcInitializer;
+class BaseProcCreateTask;
+} // namespace ksys::act
namespace ksys::map {
-class Object;
-
class ObjectLinkData;
struct ObjectLink;
struct ObjectLinkArray;
-
class LinkTag;
-// FIXME: incomplete
class Object {
public:
// TODO: rename
@@ -35,12 +35,29 @@ public:
_8 = 0x8,
_10 = 0x10,
_20 = 0x20,
+ _40 = 0x40,
_80 = 0x80,
+ _100 = 0x100,
+ ActorCreated = 0x200,
+ _400 = 0x400,
+ _2000 = 0x2000,
+ _4000 = 0x4000,
_8000 = 0x8000,
_40000 = 0x40000,
_80000 = 0x80000,
- Freed = 0xC65067E6,
+ _100000 = 0x100000,
+ _400000 = 0x400000,
+ _2000000 = 0x2000000,
+ _4000000 = 0x4000000,
+ _40000000 = 0x40000000,
_80000000 = 0x80000000,
+ ResetOnUnlinkFailed = _100 | _2000,
+ ResetOnUnlink = _2 | _4 | _80 | _100 | ActorCreated | _400 | _2000,
+ _400400 = _400 | _400000,
+ _500400 = _400400 | _100000,
+ _80002106 = _2 | _4 | _100 | _2000 | _80000000,
+ ResetOnFreed = ResetOnUnlink | _500400 | _20 | _40 | _4000 | _2000000 | _4000000 |
+ _40000000 | _80000000,
};
enum class Flag {
@@ -74,21 +91,38 @@ public:
Object();
~Object();
+ void initData(MubinIter* iter, u8 idx, u32 actor_data_idx, ActorData* data);
void free();
- void onBaseProcCreated(act::BaseProc* proc);
-
- bool getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const;
- act::Actor* getActor() const;
void registerBaseProc(act::BaseProc* proc);
void setBaseProcDirect(act::BaseProc* proc);
+ void onBaseProcCreated(act::BaseProc* proc);
+ act::BaseProc* tryGetProc(bool force);
+ void unlinkProc(bool force);
+
+ bool getActorWithAccessor(act::ActorLinkConstDataAccess& accessor);
+ act::Actor* tryGetActor(bool force);
+ act::Actor* getActor();
+
+ LinkTag* tryGetLinkTag(bool force);
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;
+ bool isRevivalGameDataFlagOn() const;
+ bool checkActorDataFlag(const PlacementActors* pa, ActorData::Flag flag) const;
+ bool checkTraverseFlags() const;
+ bool checkRevivalFlag(ActorData::Flag bit) const;
+
+ void setRevivalFlagValueIf(ActorData::Flag bit, bool value);
+ void setRevivalFlagValue(bool value);
+ void setFieldATrue();
+
+ sead::Vector3f getScale() const;
+ sead::Vector3f getRotate() const;
+ void setTranslate(const sead::Vector3f& translate);
f32 getDispDistanceMultiplier() const {
f32 mult = 1.0;
@@ -99,18 +133,18 @@ public:
return mult;
}
+ void getTraversePosAndLoadDistance(sead::Vector3f* traverse_pos, f32* load_dist) const;
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 = false, bool ignore_radius = false) 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;
+ void getUniqueName(const char** out) const;
Object* findPlacementLODLinkObject(const PlacementActors* unused) const;
Object* findPlacementLODLinkObject() const;
@@ -118,26 +152,28 @@ public:
const char* getHashIdStringDebug() const;
const char* getHashIdStringDebug_0() const;
+ bool x_18() const;
+ bool x_20() const;
+ s32 x_22() const;
+
+ bool hasGenGroup() const;
+ void spawnGenGroupActorsIfNeeded(Object* obj);
+
void* getRails() const;
void* getRails_0() const;
+ bool setupTargetLinks(Object* src, ObjectLink* link, sead::Heap* heap);
bool allocLinkData(sead::Heap* heap);
- bool hasGenGroup() const;
void incrementLinkNum();
void decrementLinkNum();
+ bool checkCreateOrDeleteLinkObjRevival() const;
- 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);
+ bool shouldSkipSpawn() const;
+ bool shouldSkipSpawn_(bool x) const;
// 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;
const auto& getFlags0() const { return mFlags0; }
const auto& getFlags() const { return mFlags; }
@@ -159,7 +195,7 @@ public:
act::BaseProc* getProc() const { return mProc; }
ObjectLinkData* getLinkData() const { return mLinkData; }
- u32 getRevivalGameDataFlagHash() const { return mRevivalGameDataFlagHash; }
+ gdt::FlagHandle getRevivalGameDataFlagHash() const { return mRevivalGameDataFlagHash; }
u32 getHashId() const { return mHashId; }
const sead::Vector3f& getTranslate() const { return mTranslate; }
@@ -182,7 +218,7 @@ private:
MubinIter mMubinIter;
act::BaseProc* mProc = nullptr;
ObjectLinkData* mLinkData = nullptr;
- u32 mRevivalGameDataFlagHash = 0xffffffff;
+ gdt::FlagHandle mRevivalGameDataFlagHash = gdt::InvalidHandle;
void* _50 = nullptr;
u32 mHashId = 0;
sead::Vector3f mTranslate;
diff --git a/src/KingSystem/Map/mapObjectGenGroup.cpp b/src/KingSystem/Map/mapObjectGenGroup.cpp
new file mode 100644
index 00000000..714dee15
--- /dev/null
+++ b/src/KingSystem/Map/mapObjectGenGroup.cpp
@@ -0,0 +1 @@
+#include "KingSystem/Map/mapObjectGenGroup.h"
diff --git a/src/KingSystem/Map/mapObjectGenGroup.h b/src/KingSystem/Map/mapObjectGenGroup.h
new file mode 100644
index 00000000..b78defec
--- /dev/null
+++ b/src/KingSystem/Map/mapObjectGenGroup.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace ksys::map {
+
+class GenGroup {};
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapObjectLink.cpp b/src/KingSystem/Map/mapObjectLink.cpp
index 8bc85335..fbfca297 100644
--- a/src/KingSystem/Map/mapObjectLink.cpp
+++ b/src/KingSystem/Map/mapObjectLink.cpp
@@ -1,15 +1,131 @@
#include "KingSystem/Map/mapObjectLink.h"
+#include <container/seadBuffer.h>
+#include "KingSystem/ActorSystem/actActorConstDataAccess.h"
#include "KingSystem/Map/mapObject.h"
+#include "KingSystem/Map/mapObjectGenGroup.h"
namespace ksys::map {
-ObjectLinkData::ObjectLinkData() = default;
+struct MapLinkDefinition {
+ const char* name;
+ const char* desc;
+ MapLinkDefType type;
+};
+
+static constexpr u32 sNumTypes = 42;
+static constexpr sead::SafeArray<MapLinkDefinition, sNumTypes> sMapLinkDefinitions{{
+ {"-AxisX", "マイナスX軸シグナル", MapLinkDefType::NAxisX},
+ {"-AxisY", "マイナスY軸シグナル", MapLinkDefType::NAxisY},
+ {"-AxisZ", "マイナスZ軸シグナル", MapLinkDefType::NAxisZ},
+ {"AreaCol", "エリア(センサ)指定", MapLinkDefType::AreaCol},
+ {"AxisX", "X軸シグナル", MapLinkDefType::AxisX},
+ {"AxisY", "Y軸シグナル", MapLinkDefType::AxisY},
+ {"AxisZ", "Z軸シグナル", MapLinkDefType::AxisZ},
+ {"BAndSCs", "ボール&ソケットCS", MapLinkDefType::BAndSCs},
+ {"BAndSLimitAngYCs", "Y角速度制限付ボール&ソケットCS", MapLinkDefType::BAndSLimitAngYCs},
+ {"BasicSig", "基本シグナル", MapLinkDefType::BasicSig},
+ {"BasicSigOnOnly", "オンのみ基本シグナル", MapLinkDefType::BasicSigOnOnly},
+ {"ChangeAtnSig", "アテンション変更時シグナル", MapLinkDefType::ChangeAtnSig},
+ {"CogWheelCs", "歯車CS", MapLinkDefType::CogWheelCs},
+ {"CopyWaitRevival", "配置自動セーブ継承", MapLinkDefType::CopyWaitRevival},
+ {"Create", "生成", MapLinkDefType::Create},
+ {"DeadUp", "死んだらオン", MapLinkDefType::DeadUp},
+ {"DemoMember", "デモ参加", MapLinkDefType::DemoMember},
+ {"FixedCs", "固定CS", MapLinkDefType::FixedCs},
+ {"ForSale", "売り物", MapLinkDefType::ForSale},
+ {"ForbidAttention", "アテンションタイプ変更", MapLinkDefType::ForbidAttention},
+ {"Freeze", "凍結", MapLinkDefType::Freeze},
+ {"GimmickSuccess", "ネタ成功シグナル", MapLinkDefType::GimmickSuccess},
+ {"HingeCs", "ヒンジCS", MapLinkDefType::HingeCs},
+ {"LifeZero", "ライフ0", MapLinkDefType::LifeZero},
+ {"LimitHingeCs", "制限付ヒンジCS", MapLinkDefType::LimitHingeCs},
+ {"ModelBind", "モデルバインド", MapLinkDefType::ModelBind},
+ {"MtxCopyCreate", "位置継承生成", MapLinkDefType::MtxCopyCreate},
+ {"OffWaitRevival", "配置自動セーブオフ", MapLinkDefType::OffWaitRevival},
+ {"PhysSystemGroup", "物理システムグループ", MapLinkDefType::PhysSystemGroup},
+ {"PlacementLOD", "配置LOD", MapLinkDefType::PlacementLOD},
+ {"PulleyCs", "滑車CS", MapLinkDefType::PulleyCs},
+ {"RackAndPinionCs", "ラック&ピニオンCS", MapLinkDefType::RackAndPinionCs},
+ {"Recreate", "再生成", MapLinkDefType::Recreate},
+ {"Reference", "参照", MapLinkDefType::Reference},
+ {"Remains", "遺物シグナル", MapLinkDefType::Remains},
+ {"SensorBind", "センサバインド", MapLinkDefType::SensorBlind},
+ {"SliderCs", "スライダーCS", MapLinkDefType::SliderCs},
+ {"Stable", "安定", MapLinkDefType::Stable},
+ {"StackLink", "スタック", MapLinkDefType::StackLink},
+ {"SyncLink", "生成グループ", MapLinkDefType::SyncLink},
+ {"VelocityControl", "速度制御シグナル", MapLinkDefType::VelocityControl},
+}};
+
+const char* ObjectLink::getDescription() const {
+ return getDescriptionForType(type);
+}
+
+const char* ObjectLink::getDescriptionForType(MapLinkDefType t) {
+ const char* desc = "不定"; // invalid
+
+ for (int i = 0; i < sMapLinkDefinitions.size(); ++i) {
+ if (sMapLinkDefinitions[i].type == t) {
+ desc = sMapLinkDefinitions[i].desc;
+ break;
+ }
+ }
+
+ return desc;
+}
+
+MapLinkDefType ObjectLink::getTypeForName(const sead::SafeString& name) {
+ sead::Buffer<const MapLinkDefinition> buf{sMapLinkDefinitions.size(),
+ sMapLinkDefinitions.getBufferPtr()};
+
+ s32 idx = buf.binarySearchC(
+ [&](const MapLinkDefinition& item) { return sead::SafeString(item.name).compare(name); });
+
+ if (idx == -1)
+ return MapLinkDefType::Invalid;
+ return buf[idx].type;
+}
-act::BaseProc* ObjectLink::getObjectProc() const {
+bool ObjectLink::sub_7100D4E310(MapLinkDefType t) {
+ switch (t) {
+ case MapLinkDefType::Create:
+ case MapLinkDefType::Delete:
+ case MapLinkDefType::MtxCopyCreate:
+ case MapLinkDefType::Freeze:
+ case MapLinkDefType::ForbidAttention:
+ return true;
+ default:
+ break;
+ case MapLinkDefType::BasicSig:
+ case MapLinkDefType::AxisX:
+ case MapLinkDefType::AxisY:
+ case MapLinkDefType::AxisZ:
+ case MapLinkDefType::NAxisX:
+ case MapLinkDefType::NAxisY:
+ case MapLinkDefType::NAxisZ:
+ case MapLinkDefType::GimmickSuccess:
+ case MapLinkDefType::VelocityControl:
+ case MapLinkDefType::BasicSigOnOnly:
+ case MapLinkDefType::Remains:
+ case MapLinkDefType::DeadUp:
+ case MapLinkDefType::LifeZero:
+ case MapLinkDefType::Stable:
+ case MapLinkDefType::ChangeAtnSig:
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectLink::isPlacementLODOrForSaleLink(MapLinkDefType t) {
+ return t == MapLinkDefType::PlacementLOD || t == MapLinkDefType::ForSale;
+}
+
+act::Actor* ObjectLink::getObjectActor() const {
if (other_obj == nullptr)
return nullptr;
- return other_obj->getActor_0(false);
+ return other_obj->tryGetActor(false);
}
bool ObjectLink::getObjectProcWithAccessor(act::ActorLinkConstDataAccess& accessor) const {
@@ -19,4 +135,117 @@ bool ObjectLink::getObjectProcWithAccessor(act::ActorLinkConstDataAccess& access
return other_obj->getActorWithAccessor(accessor);
}
+ObjectLinkData::ObjectLinkData() = default;
+
+void ObjectLinkData::deleteArrays() {
+ if (mRails) {
+ delete mRails;
+ mRails = nullptr;
+ }
+
+ if (mLinksOther.links) {
+ delete mLinksOther.links;
+ mLinksOther.links = nullptr;
+ mLinksOther.num_links = 0;
+ }
+
+ if (mLinksCs.links) {
+ delete mLinksCs.links;
+ mLinksCs.links = nullptr;
+ mLinksCs.num_links = 0;
+ }
+
+ if (mLinksReference) {
+ delete mLinksReference;
+ mLinksReference = nullptr;
+ mNumLinksReference = 0;
+ }
+
+ if (mLinksToSelf.links) {
+ delete mLinksToSelf.links;
+ mLinksToSelf.links = nullptr;
+ mLinksToSelf.num_links = 0;
+ }
+}
+
+bool ObjectLinkData::allocLinksToSelf(s32 num_links, sead::Heap* heap) {
+ if (num_links < 1)
+ return true;
+
+ mLinksToSelf.links = new (heap, std::nothrow_t()) ObjectLink[num_links]();
+ mLinksToSelf.num_links = num_links;
+
+ return mLinksToSelf.links != nullptr;
+}
+
+ObjectLink* ObjectLinkData::findLinkWithType(MapLinkDefType t) {
+ return findLinkWithType_0(t);
+}
+
+ObjectLink* ObjectLinkData::findLinkWithType_0(MapLinkDefType t) {
+ switch (t) {
+ case MapLinkDefType::FixedCs:
+ case MapLinkDefType::HingeCs:
+ case MapLinkDefType::LimitHingeCs:
+ case MapLinkDefType::SliderCs:
+ case MapLinkDefType::PulleyCs:
+ case MapLinkDefType::BAndSCs:
+ case MapLinkDefType::BAndSLimitAngYCs:
+ case MapLinkDefType::CogWheelCs:
+ case MapLinkDefType::RackAndPinionCs:
+ return mLinksCs.findLinkWithType(t);
+ default:
+ return mLinksOther.findLinkWithType(t);
+ }
+}
+
+void ObjectLinkData::setGenGroup(GenGroup* group) {
+ if (mGenGroup == nullptr)
+ mGenGroup = group;
+}
+
+// NON_MATCHING
+bool ObjectLinkArray::checkLink(MapLinkDefType t, bool b) {
+ bool x_exists;
+ ObjectLink* link = nullptr;
+
+ if (t != MapLinkDefType::BasicSig) {
+ x_exists = false;
+ } else {
+ link = findLinkWithType(MapLinkDefType::BasicSigOnOnly);
+ x_exists = link != nullptr;
+
+ if (link != nullptr)
+ goto done;
+ }
+
+ link = findLinkWithType(t);
+
+ if (link == nullptr)
+ return false;
+ if (link->type == MapLinkDefType::VelocityControl)
+ return false;
+
+done:
+ act::ActorConstDataAccess acc{};
+
+ if (link->other_obj != nullptr)
+ link->other_obj->getActorWithAccessor(acc);
+ else
+ acc.acquire(nullptr);
+ return acc.checkLinkTagActivated(b, x_exists);
+}
+
+ObjectLink* ObjectLinkArray::findLinkWithType(MapLinkDefType type) {
+ return findLinkWithType_0(type);
+}
+
+ObjectLink* ObjectLinkArray::findLinkWithType_0(MapLinkDefType type) {
+ for (int i = 0; i != num_links; ++i) {
+ if (links[i].type == type)
+ return &links[i];
+ }
+ return nullptr;
+}
+
} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapObjectLink.h b/src/KingSystem/Map/mapObjectLink.h
index b0f25f7b..d58a1c32 100644
--- a/src/KingSystem/Map/mapObjectLink.h
+++ b/src/KingSystem/Map/mapObjectLink.h
@@ -5,12 +5,13 @@
#include "KingSystem/Utils/Types.h"
namespace ksys::act {
+class Actor;
class ActorLinkConstDataAccess;
-class BaseProc;
} // namespace ksys::act
namespace ksys::map {
+class GenGroup;
class Object;
enum class MapLinkDefType {
@@ -60,18 +61,27 @@ enum class MapLinkDefType {
};
struct ObjectLink {
- act::BaseProc* getObjectProc() const;
+ act::Actor* getObjectActor() const;
bool getObjectProcWithAccessor(act::ActorLinkConstDataAccess& accessor) const;
+ const char* getDescription() const;
+ static const char* getDescriptionForType(MapLinkDefType t);
+ static MapLinkDefType getTypeForName(const sead::SafeString& name);
+ static bool sub_7100D4E310(MapLinkDefType t);
+ static bool isPlacementLODOrForSaleLink(MapLinkDefType t);
- Object* other_obj;
- u32 type;
- MubinIter iter;
+ Object* other_obj = nullptr;
+ MapLinkDefType type = MapLinkDefType::Invalid;
+ MubinIter iter{};
};
KSYS_CHECK_SIZE_NX150(ObjectLink, 0x20);
struct ObjectLinkArray {
- ObjectLink* findLinkWithType(MapLinkDefType link_type);
- u32 num_links = 0;
+ bool checkLink(MapLinkDefType t, bool b);
+
+ ObjectLink* findLinkWithType(MapLinkDefType type);
+ ObjectLink* findLinkWithType_0(MapLinkDefType type);
+
+ s32 num_links = 0;
ObjectLink* links = nullptr;
};
KSYS_CHECK_SIZE_NX150(ObjectLinkArray, 0x10);
@@ -80,7 +90,25 @@ class ObjectLinkData {
public:
ObjectLinkData();
+ void deleteArrays();
void release(Object* obj, bool a1);
+ bool allocLinksToSelf(s32 num_links, sead::Heap* heap);
+
+ bool sub_7100D4EC40(Object* src, ObjectLink* link, Object* dest);
+ void sub_7100D4FB78(Object* obj);
+ bool checkCreateLinkObjRevival() const;
+ bool checkDeleteLinkObjRevival() const;
+
+ ObjectLink* findLinkWithType(MapLinkDefType t);
+ ObjectLink* findLinkWithType_0(MapLinkDefType t);
+
+ void setGenGroup(GenGroup* group);
+
+ void x_1(act::Actor* actor, Object* obj);
+
+ bool checkCreateOrDeleteLinkObjRevival() const {
+ return checkDeleteLinkObjRevival() || checkCreateLinkObjRevival();
+ }
Object* mCreateLinksSrcObj = nullptr;
Object* mDeleteLinksSrcObj = nullptr;
@@ -97,7 +125,7 @@ public:
bool mNoAutoDemoMember = false;
bool field_57 = false;
- void* mGenGroup = nullptr;
+ GenGroup* mGenGroup = nullptr;
void* mRails = nullptr;
};
KSYS_CHECK_SIZE_NX150(ObjectLinkData, 0x68);
diff --git a/src/KingSystem/Map/mapPlacementActors.cpp b/src/KingSystem/Map/mapPlacementActors.cpp
new file mode 100644
index 00000000..dd7e81b7
--- /dev/null
+++ b/src/KingSystem/Map/mapPlacementActors.cpp
@@ -0,0 +1 @@
+#include "KingSystem/Map/mapPlacementActors.h"
diff --git a/src/KingSystem/Map/mapPlacementActors.h b/src/KingSystem/Map/mapPlacementActors.h
new file mode 100644
index 00000000..49552ae9
--- /dev/null
+++ b/src/KingSystem/Map/mapPlacementActors.h
@@ -0,0 +1,126 @@
+#pragma once
+
+#include <container/seadSafeArray.h>
+#include <prim/seadSafeString.h>
+#include <prim/seadTypedBitFlag.h>
+#include <prim/seadTypedLongBitFlag.h>
+#include <thread/seadAtomic.h>
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::map {
+
+class Object;
+
+// TODO: rename
+enum class ActorFlag8 {
+ MapPassive = 0x1,
+ EnemyOrNpcOrActiveOrAreaOrAirWall = 0x2,
+ UndispCutOrPreActorXLinkOrChemical = 0x4,
+ _8 = 0x8,
+ CanGetPouch = 0x10,
+ HasCreateOrDeleteLink = 0x20,
+ DragonDropItemTarget = 0x40,
+ TreeOrBush = 0x80,
+};
+
+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<u32>> mFlags;
+ sead::TypedBitFlag<ActorFlag8, u8> mActorFlags8;
+ u8 TEMP[0x13F];
+ sead::FixedSafeString<64> mActorName;
+};
+KSYS_CHECK_SIZE_NX150(ActorData, 0x1A0);
+
+// FIXME: incomplete
+class PlacementStruct1 {
+public:
+ sead::BitFlag16 mFlags;
+ bool mIsOneHitChallengeActive;
+};
+
+class PlacementActors {
+public:
+ u32 getNumStaticObjs() const;
+ map::Object* getStaticObj_2(s32 idx) const;
+ bool sub_7100D524B4() const;
+ void x_9();
+
+ u8 _0[0xe0 - 0x0];
+ PlacementStruct1* mStruct1;
+ u8 _e8[0x538 - 0xe8];
+ sead::SafeArray<ActorData, 6000> mActorData;
+ // u8 _261b38[0x2a80d0 - 0x261b38];
+ u32 mActorDataMapSize;
+};
+// KSYS_CHECK_SIZE_NX150(PlacementActors, 0x2A80D0);
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapPlacementMgr.cpp b/src/KingSystem/Map/mapPlacementMgr.cpp
index b6114392..6e6c3f9b 100644
--- a/src/KingSystem/Map/mapPlacementMgr.cpp
+++ b/src/KingSystem/Map/mapPlacementMgr.cpp
@@ -1,7 +1,133 @@
#include "KingSystem/Map/mapPlacementMgr.h"
+#include <thread/seadThreadUtil.h>
+#include "KingSystem/ActorSystem/actActorCreator.h"
+#include "KingSystem/ActorSystem/actInfoData.h"
+#include "KingSystem/ActorSystem/actInstParamPack.h"
+#include "KingSystem/Map/mapClusteredRenderer.h"
+#include "KingSystem/Map/mapObject.h"
+#include "KingSystem/Map/mapPlacementActors.h"
+#include "KingSystem/Map/mapPlacementTree.h"
+#include "KingSystem/System/VFR.h"
namespace ksys::map {
SEAD_SINGLETON_DISPOSER_IMPL(PlacementMgr)
+PlacementMgr::PlacementMgr() : mThreadParams(this, &PlacementMgr::threadFn) {}
+
+PlacementMgr::~PlacementMgr() {
+ mThreadHeap->destroy();
+ mDynamicHeap->destroy();
+ mVillagerHeap->destroy();
+ mTraverseResultHeap->destroy();
+}
+
+void PlacementMgr::releaseTree() {
+ if (mPlacementTree != nullptr)
+ delete mPlacementTree;
+ mPlacementTree = nullptr;
+}
+
+// NON_MATCHING
+void PlacementMgr::x_3() {
+ auto ac = act::ActorCreator::instance();
+ const auto loc = sead::makeScopedLock(ac->getCS());
+ if (mNumStaticObjs < mPlacementActors->getNumStaticObjs()) {
+ auto list = ac->getActorList();
+ for (act::Actor& node : list) {
+ if (node.getMapObject() == mPlacementActors->getStaticObj_2(mNumStaticObjs)) {
+ node.deleteLater(act::BaseProc::DeleteReason::_0);
+ }
+ }
+ }
+}
+
+void PlacementMgr::reset7F0() {
+ _7f0 = 0;
+}
+
+// NON_MATCHING
+void PlacementMgr::initClusteredRenderer() {
+ if (mThread != nullptr && mClusteredRenderer == nullptr)
+ return;
+ if (mThreadHeap == nullptr)
+ return;
+
+ mFlags.reset(MgrFlag::_40000);
+ mThread = new (mThreadHeap)
+ sead::DelegateThread("PlacementMgr", &mThreadParams, mThreadHeap,
+ sead::ThreadUtil::ConvertPrioritySeadToPlatform(0x14),
+ sead::MessageQueue::BlockType::Blocking, 0x7fffffff, 0x100000, 0x20);
+ mRequestedMsg = 0;
+ sead::CoreIdMask mask{sead::CoreId::cSub4};
+ mThread->setAffinity(mask);
+ mThread->start();
+ mFlags.reset(MgrFlag::_2);
+
+ if (mClusteredRenderer != nullptr) {
+ mClusteredRenderer->startThread();
+ }
+}
+
+void PlacementMgr::auto0() {
+ if (mThread == nullptr)
+ return;
+ mFlags.set(MgrFlag::_2);
+ _278 = 0;
+}
+
+void PlacementMgr::printDebugInfo() {
+ if (!sFlags.isOn(MgrStaticFlags::debug))
+ return;
+
+ // Actor info:%d (loaded:%d) Instance:%d
+ sead::FormatFixedSafeString<128> s1("アクタ情報:%d(ロード済み:%d) インスタンス:%d",
+ mPlacementActors->mActorDataMapSize, mLoadedActorCount,
+ mPlacementActors->getNumStaticObjs());
+ // Traverse result pre-actor:%d actor:%d
+ sead::FormatFixedSafeString<128> s2("トラバース結果 pre-actor:%d actor:%d",
+ mTraverseResults[mTraverseResultIdx].pre_actors.size(),
+ mTraverseResults[mTraverseResultIdx].actors.size());
+ // Memory preActor:%dk info:%dk result:%dk mass:%dk clustered:%d
+ sead::FormatFixedSafeString<128> s3(
+ "メモリ preActor:%dk info:%dk result:%dk mass:%dk clustered:%dk", 40468, 2437, 87,
+ mMassMemoryUsage / 1024, mClusteredMemoryUsage / 1024);
+ // Dynamic heap remaining:%dk
+ sead::FormatFixedSafeString<128> s4("動的ヒープ残り:%dk",
+ int(mDynamicHeap->getFreeSize()) / 1024);
+}
+
+void PlacementMgr::incrementCounter() {
+ _278++;
+}
+
+void PlacementMgr::x() {
+ if (mFlags.isOn(MgrFlag::_2))
+ return;
+
+ mPlacementActors->x_9();
+ mIntTime++;
+
+ f32 last_time = mTime;
+ auto* vfr = VFR::instance();
+ mTime += vfr->getDeltaTime();
+ mTimeUpdated = s32(last_time) != s32(mTime);
+}
+
+void PlacementMgr::auto5() {
+ mFlags.set(MgrFlag::_1);
+}
+
+void PlacementMgr::auto16() {
+ mFlags.set(MgrFlag::_100000);
+ mFlags.set(MgrFlag::_200000);
+ mFlags.set(MgrFlag::_400000);
+}
+
+bool PlacementMgr::someFlagCheck() const {
+ if (mFlags.isOn(MgrFlag::_80000))
+ return true;
+ return mFlags.isOn(MgrFlag::_100000);
+}
+
} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapPlacementMgr.h b/src/KingSystem/Map/mapPlacementMgr.h
index 9aa98458..40ca95d6 100644
--- a/src/KingSystem/Map/mapPlacementMgr.h
+++ b/src/KingSystem/Map/mapPlacementMgr.h
@@ -1,131 +1,149 @@
#pragma once
-#include <container/seadSafeArray.h>
+#include <container/seadObjArray.h>
#include <heap/seadDisposer.h>
-#include <prim/seadSafeString.h>
-#include <prim/seadTypedBitFlag.h>
-#include <prim/seadTypedLongBitFlag.h>
-#include <thread/seadAtomic.h>
-#include "KingSystem/Utils/Types.h"
+#include <heap/seadExpHeap.h>
+#include <thread/seadDelegateThread.h>
+#include "KingSystem/ActorSystem/actActor.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<u32>> mFlags;
- sead::TypedBitFlag<ActorFlag8, u8> mActorFlags8;
- u8 TEMP[0x13F];
- sead::FixedSafeString<64> mActorName;
-};
-KSYS_CHECK_SIZE_NX150(ActorData, 0x1A0);
+namespace ksys::act {
+class InstParamPack;
+}
-// FIXME: move this to another header and rename
-// FIXME: incomplete
-class PlacementStruct1 {
-public:
- sead::BitFlag16 mFlags;
- bool mIsOneHitChallengeActive;
-};
+namespace ksys::map {
-class PlacementActors {
-public:
- u8 _0[0xe0 - 0x0];
- PlacementStruct1* mStruct1;
- u8 _e8[0x538 - 0xe8];
- sead::SafeArray<ActorData, 6000> mActorData;
- u8 _261b38[0x2a80d0 - 0x261b38];
-};
-KSYS_CHECK_SIZE_NX150(PlacementActors, 0x2A80D0);
+class ClusteredRenderer;
+class Object;
+class PlacementTree;
+class PlacementActors;
class PlacementMgr {
SEAD_SINGLETON_DISPOSER(PlacementMgr)
PlacementMgr();
virtual ~PlacementMgr();
+ struct TraverseResults {
+ sead::PtrArray<act::Actor> pre_actors;
+ sead::PtrArray<act::Actor> actors;
+ sead::PtrArray<u32> _20;
+ sead::PtrArray<u32> _30;
+ sead::PtrArray<u32> _40;
+ sead::PtrArray<u32> _50;
+ sead::PtrArray<u32> dragon_item_drop_targets;
+ sead::PtrArray<u32> _70;
+ };
+ KSYS_CHECK_SIZE_NX150(TraverseResults, 0x80);
+
public:
+ void releaseTree();
+ void x_3();
+ void reset7F0();
+ void initClusteredRenderer();
+ void auto0();
+ bool auto1();
+ void x_0(sead::Vector3f* pos, act::InstParamPack* pack);
+ void printDebugInfo();
+ void loadModel(Object* obj);
+ void incrementCounter();
+ void x();
+ void auto5();
+ void auto16();
+ bool someFlagCheck() const;
+
+ void threadFn(sead::Thread* thread, sead::MessageQueue::Element msg);
+
enum class MgrFlag {
+ _1 = 0x1,
+ _2 = 0x2,
+ _20 = 0x20,
+ _40000 = 0x40000,
+ _80000 = 0x80000,
+ _100000 = 0x100000,
+ _200000 = 0x200000,
+ _400000 = 0x400000,
_1000000 = 0x1000000,
};
- u8 TEMP1[0x1C8];
+ enum class MgrStaticFlags {
+ debug = 0x1,
+ };
+
+ static sead::TypedBitFlag<MgrStaticFlags, u32> sFlags;
+
+ u32 _28;
+ u32 _2c = 0;
+ u32 _30 = 0;
+
+ u8 TEMP[0x108];
+ sead::Delegate2<PlacementMgr, sead::Thread*, sead::MessageQueue::Element> mThreadParams;
+ sead::DelegateThread* mThread;
+ u32 mTraverseResultIdx;
+ u16 mRequestedMsg = 0;
+
+ sead::Vector3f mCameraPos{};
+ sead::Vector3f mPlayerPos{};
+ sead::Vector3f mPrevPlayerPos{};
+ sead::ExpHeap* mDynamicHeap;
+ sead::ExpHeap* mThreadHeap;
+ sead::ExpHeap* mVillagerHeap;
+ sead::ExpHeap* mTraverseResultHeap;
+ void* mActorCreator;
+ u32 mLoadedActorCount;
+ void* mTeraSystem;
+ s32 mIntTime;
+ f32 mTime;
+ bool mTimeUpdated;
+
+ s32 mMassMemoryUsage;
+ s32 mClusteredMemoryUsage;
+ void* mDebugHeap;
PlacementActors* mPlacementActors;
- u8 TEMP2[0x48C];
+
+ void* mVillagerManager;
+
+ u32 mNumStaticObjs;
+ u32 mActorDataMapSize;
+ u8 TEMP2[0x70];
+
+ u32 _278;
+
+ u32 mPreActorNumDone;
+ u32 mLoadActorNumTotal;
+ sead::Vector3f mPrevCameraPos{};
+ f32 mDeltaCameraDistance;
+ sead::FixedSafeString<256> mStr1;
+ sead::FixedSafeString<256> mStr2;
+ sead::FixedSafeString<256> mStr3;
+ sead::CriticalSection mCS{};
+
+ u64 mStartTick;
+ u8 TEMP3[0x5c];
+
sead::TypedBitFlag<MgrFlag, sead::Atomic<u32>> mFlags;
- u8 TEMP3[0x190];
+ bool mThreadStarted = false;
+ bool _689 = false;
+ bool _68a = false;
+ u32 _68c;
+ u32 _690;
+ u32 mMessage = 0;
+ u32 mJobType = 0;
+ TraverseResults mTraverseResults[2];
+ PlacementTree* mPlacementTree = nullptr;
+ u32 _7a8;
+ void* mMassRenderer = nullptr;
+ ClusteredRenderer* mClusteredRenderer = nullptr;
+ void* mPlacementNavi = nullptr;
+ u32 mMassRendererReqCount = 0;
+ u32 mMassRendererStatus = 0;
+
+ // fix these
+ sead::DelegateFunc mInvoker{};
+ u8 TEMP4[0x10];
+
+ s32 _7f0 = -1;
+
+ sead::DelegateFunc mInvoker2{};
+ u8 TEMP5[0x10];
};
KSYS_CHECK_SIZE_NX150(PlacementMgr, 0x818);
diff --git a/src/KingSystem/Map/mapPlacementTree.cpp b/src/KingSystem/Map/mapPlacementTree.cpp
new file mode 100644
index 00000000..52eea81e
--- /dev/null
+++ b/src/KingSystem/Map/mapPlacementTree.cpp
@@ -0,0 +1,13 @@
+#include "KingSystem/Map/mapPlacementTree.h"
+
+namespace ksys::map {
+
+PlacementTree::PlacementTree() = default;
+
+PlacementTree::~PlacementTree() {
+ mBuffer.freeBuffer();
+ mObjects.freeBuffer();
+ delete[] _28;
+}
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapPlacementTree.h b/src/KingSystem/Map/mapPlacementTree.h
new file mode 100644
index 00000000..13818b34
--- /dev/null
+++ b/src/KingSystem/Map/mapPlacementTree.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <container/seadBuffer.h>
+#include <container/seadObjArray.h>
+#include <limits>
+#include <thread/seadReadWriteLock.h>
+
+using F32Limits = std::numeric_limits<f32>;
+
+namespace ksys::map {
+
+// FIXME
+class PlacementTree {
+ struct TreeObject {
+ u32 _0;
+ u32 _4;
+ u32 _8;
+ f32 _c;
+ f32 _10;
+ f32 _14;
+ };
+
+public:
+ PlacementTree();
+ ~PlacementTree();
+
+ sead::Buffer<TreeObject> mBuffer{};
+ sead::Buffer<u32*> mObjects{};
+ void* _20{};
+ void* _28{};
+ u32 _30{};
+ f32 _34 = F32Limits::max();
+ f32 _38 = F32Limits::max();
+ f32 _3c = F32Limits::max();
+ f32 _40 = F32Limits::max();
+ sead::ReadWriteLock mLock{};
+};
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapStagePreActorCache.cpp b/src/KingSystem/Map/mapStagePreActorCache.cpp
new file mode 100644
index 00000000..cc853e2a
--- /dev/null
+++ b/src/KingSystem/Map/mapStagePreActorCache.cpp
@@ -0,0 +1,7 @@
+#include "KingSystem/Map/mapStagePreActorCache.h"
+
+namespace ksys::map {
+
+SEAD_SINGLETON_DISPOSER_IMPL(StagePreActorCache)
+
+} // namespace ksys::map
diff --git a/src/KingSystem/Map/mapStagePreActorCache.h b/src/KingSystem/Map/mapStagePreActorCache.h
new file mode 100644
index 00000000..a739f1ba
--- /dev/null
+++ b/src/KingSystem/Map/mapStagePreActorCache.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <heap/seadDisposer.h>
+#include <math/seadVector.h>
+
+namespace ksys::map {
+
+class ForestRenderer {
+public:
+ s32 x_7(const sead::Vector3f& vec);
+};
+
+// TODO
+class StagePreActorCache {
+ SEAD_SINGLETON_DISPOSER(StagePreActorCache)
+ StagePreActorCache();
+
+public:
+ auto* getForestRenderer() { return mForestRenderer; }
+
+private:
+ ForestRenderer* mForestRenderer;
+};
+
+} // namespace ksys::map