summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-03-18 15:13:37 +0100
committerLéo Lam <leo@leolam.fr>2021-03-19 01:20:18 +0100
commitc181eb05b792ca6422d3ace7e26eea6ab33a4829 (patch)
tree8fce7eff9aaaf646e84a58afc070b1796b94ab0b /src/KingSystem/ActorSystem
parentfd7e47c1d9ef09cb042f5b292a6539306161ef81 (diff)
ksys/act: Add some ActorCreator functions
Diffstat (limited to 'src/KingSystem/ActorSystem')
-rw-r--r--src/KingSystem/ActorSystem/actActor.h21
-rw-r--r--src/KingSystem/ActorSystem/actActorCreator.cpp224
-rw-r--r--src/KingSystem/ActorSystem/actActorCreator.h67
-rw-r--r--src/KingSystem/ActorSystem/actInstParamPack.cpp2
-rw-r--r--src/KingSystem/ActorSystem/actInstParamPack.h21
5 files changed, 317 insertions, 18 deletions
diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h
index f5e4a822..e4d1ae95 100644
--- a/src/KingSystem/ActorSystem/actActor.h
+++ b/src/KingSystem/ActorSystem/actActor.h
@@ -19,6 +19,7 @@ class RootAi;
}
class LifeRecoverInfo;
+class ActorCreator;
class ActorParam;
class Actor : public BaseProc {
@@ -36,6 +37,10 @@ public:
_2e = 0x2e,
};
+ enum class ActorFlag2 {
+ NoDistanceCheck = 0x80,
+ };
+
enum class DeleteType {
_1 = 1,
_2 = 2,
@@ -71,12 +76,21 @@ public:
void nullsub_4649(); // Some kind of logging which has been excluded from the build?
+ sead::TypedBitFlag<ActorFlag2>& getActorFlags2() { return mActorFlags2; }
+ const sead::TypedBitFlag<ActorFlag2>& getActorFlags2() const { return mActorFlags2; }
+
const sead::TypedBitFlag<StasisFlag>& getStasisFlags() const { return mStasisFlags; }
void onAiEnter(const char* name, const char* context);
+ static constexpr size_t getCreatorListNodeOffset() { return offsetof(Actor, mCreatorListNode); }
+
protected:
- /* 0x180 */ u8 TEMP_0x180[0x3D8]; // FIXME
+ friend class ActorCreator;
+
+ /* 0x17c */ u8 TEMP_0x17c[0x518 - 0x17c]; // FIXME
+ /* 0x518 */ sead::TypedBitFlag<ActorFlag2> mActorFlags2;
+ /* 0x51c */ u8 TEMP_0x51c[0x558 - 0x51c];
/* 0x558 */ ai::RootAi* mRootAi;
/* 0x560 */ void* mASList; // FIXME
/* 0x568 */ void* mEffects; // FIXME
@@ -86,12 +100,13 @@ protected:
/* 0x658 */ u8 TEMP_0x650[0x710 - 0x658];
/* ..... */ // The name could be incorrect.
/* 0x710 */ sead::TypedBitFlag<StasisFlag> mStasisFlags;
- /* 0x714 */ u8 TEMP_0x714[0x7c8 - 0x714]; // FIXME
+ /* 0x714 */ u8 TEMP_0x714[0x7b0 - 0x714]; // FIXME
+ /* 0x7b0 */ ActorCreator* mCreator{};
+ /* 0x7b8 */ sead::ListNode mCreatorListNode;
/* 0x7c8 */ map::Object* mMapObject;
/* 0x7d0 */ u8 TEMP_0x7d0[0x838 - 0x7d0];
};
KSYS_CHECK_SIZE_NX150(Actor, 0x838);
-
} // namespace act
} // namespace ksys
diff --git a/src/KingSystem/ActorSystem/actActorCreator.cpp b/src/KingSystem/ActorSystem/actActorCreator.cpp
index be6c43b4..e3203b5e 100644
--- a/src/KingSystem/ActorSystem/actActorCreator.cpp
+++ b/src/KingSystem/ActorSystem/actActorCreator.cpp
@@ -1,7 +1,231 @@
#include "KingSystem/ActorSystem/actActorCreator.h"
+#include <prim/seadScopedLock.h>
+#include "KingSystem/ActorSystem/actActor.h"
+#include "KingSystem/ActorSystem/actActorTemplate.h"
+#include "KingSystem/ActorSystem/actActorUtil.h"
+#include "KingSystem/ActorSystem/actBaseProcCreateTask.h"
+#include "KingSystem/ActorSystem/actBaseProcMgr.h"
+#include "KingSystem/ActorSystem/actInfoData.h"
+#include "KingSystem/Resource/resResourceMgrTask.h"
+#include "KingSystem/Utils/HeapUtil.h"
namespace ksys::act {
SEAD_SINGLETON_DISPOSER_IMPL(ActorCreator)
+ActorCreator::ActorCreator() {
+ mActorList.initOffset(Actor::getCreatorListNodeOffset());
+ mActorFactory = nullptr;
+ mEnableDistanceChecks = false;
+ mBlockSpawns = false;
+ _5a = true;
+ mForBaseProcDualHeap = nullptr;
+ mPlacementMgrHeap = nullptr;
}
+
+void ActorCreator::onTaskRemoved(const util::TaskRemoveCallbackContext& context) {
+ if (!context.mTask)
+ return;
+
+ auto* task = sead::DynamicCast<BaseProcCreateTask>(context.mTask);
+ if (task)
+ task->onBaseProcCreationFailed(nullptr, true);
+}
+
+ActorCreator::~ActorCreator() = default;
+
+bool ActorCreator::requestCreateMapActor(const char* name, sead::Heap* heap,
+ map::MubinIter* mubin_iter, map::Object* map_object,
+ BaseProcHandle* handle, int task_lane_id,
+ InstParamPack* params) {
+ const char* actor_profile;
+ if (!InfoData::instance()->getActorProfile(&actor_profile, name))
+ return false;
+
+ const char* actor_class;
+ ActorTemplate::instance()->getActorClass(&actor_class, actor_profile);
+
+ return requestCreateActor_(actor_class, name, heap, mubin_iter, map_object, handle,
+ task_lane_id, params);
+}
+
+BaseProc* ActorCreator::createActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ InstParamPack* params, bool sleep_after_init, bool) {
+ auto* debug_heap = util::getDebugHeap();
+ bool has_debug_heap = false;
+ if (debug_heap && (debug_heap == heap || debug_heap->isInclude(heap))) {
+ res::ResourceMgrTask::instance()->controlField9c0d88(false);
+ has_debug_heap = true;
+ }
+
+ const bool is_high_priority_thread = BaseProcMgr::instance()->isHighPriorityThread();
+ SEAD_ASSERT(is_high_priority_thread);
+
+ BaseProcCreateTaskData data;
+ data.mHeap = heap;
+ data.mProcClass = actor_class;
+ data.mProcName = name;
+ data.mCreateDelegate = &mCreateProcDelegate;
+ data.mSleepAfterInit = sleep_after_init;
+ if (params) {
+ data.mParams = &params->getBuffer();
+ data.mOtherProc = params->getProc();
+ }
+
+ BaseProcCreateRequest req;
+ req.task_remove_callback = nullptr;
+ req.task_lane_id = static_cast<u32>(BaseProcCreateTask::LaneId::_1);
+ req.task_data = &data;
+ auto* actor = BaseProcMgr::instance()->createProc(req);
+ if (has_debug_heap)
+ res::ResourceMgrTask::instance()->controlField9c0d88(true);
+ return actor;
+}
+
+Actor* ActorCreator::createActor(const char* name, sead::Heap* heap, InstParamPack* params,
+ bool sleep_after_init, bool block_other_synchronous_spawns) {
+ BaseProc* proc = nullptr;
+ if (block_other_synchronous_spawns)
+ mBlockSpawns = true;
+
+ if (block_other_synchronous_spawns || !mBlockSpawns) {
+ const char* profile;
+ if (InfoData::instance()->getActorProfile(&profile, name)) {
+ const char* actor_class;
+ ActorTemplate::instance()->getActorClass(&actor_class, profile);
+ proc = createActor_(actor_class, name, heap, params, sleep_after_init);
+ }
+ }
+
+ auto* actor = sead::DynamicCast<Actor>(proc);
+ if (!actor && proc)
+ proc->deleteLater(BaseProc::DeleteReason::_0);
+
+ return actor;
+}
+
+bool ActorCreator::requestCreateActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ map::MubinIter* mubin_iter, map::Object* map_object,
+ BaseProcHandle* handle, int task_lane_id,
+ InstParamPack* params) {
+ BaseProcCreateTaskData data;
+ data.mHeap = heap;
+ data.mProcClass = actor_class;
+ data.mProcName = name;
+ data.mMubinIter = mubin_iter;
+ data.mMapObject = map_object;
+ data.mCreateDelegate = &mCreateProcDelegate;
+ data.mProcHandle = handle;
+ if (params) {
+ data.mParams = &params->getBuffer();
+ data.mOtherProc = params->getProc();
+ }
+
+ BaseProcCreateRequest req;
+ req.task_lane_id = task_lane_id;
+ req.task_data = &data;
+ req.task_remove_callback = &mTaskRemovedDelegate;
+ return BaseProcMgr::instance()->requestCreateProc(req);
+}
+
+bool ActorCreator::requestCreateActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ map::Object* map_object, BaseProcHandle* handle,
+ int task_lane_id, InstParamPack* params) {
+ BaseProcCreateTaskData data;
+ data.mHeap = heap;
+ data.mProcClass = actor_class;
+ data.mProcName = name;
+ data.mCreateDelegate = &mCreateProcDelegate;
+ data.mMapObject = map_object;
+ data.mProcHandle = handle;
+ if (params) {
+ data.mParams = &params->getBuffer();
+ data.mOtherProc = params->getProc();
+ }
+
+ BaseProcCreateRequest req;
+ req.task_lane_id = task_lane_id;
+ req.task_data = &data;
+ req.task_remove_callback = &mTaskRemovedDelegate;
+ return BaseProcMgr::instance()->requestCreateProc(req);
+}
+
+bool ActorCreator::requestCreateActor(const char* name, sead::Heap* heap, BaseProcHandle* handle,
+ InstParamPack* params, map::Object* map_object,
+ int task_lane_id) {
+ const char* actor_profile;
+ if (!InfoData::instance()->getActorProfile(&actor_profile, name))
+ return false;
+
+ const char* actor_class;
+ ActorTemplate::instance()->getActorClass(&actor_class, actor_profile);
+
+ if (mBlockSpawns)
+ return false;
+
+ return requestCreateActor_(actor_class, name, heap, map_object, handle, task_lane_id, params);
+}
+
+// NON_MATCHING: OffsetList iteration
+void ActorCreator::enableDistanceUnloadChecks() {
+ const auto lock = sead::makeScopedLock(mActorListCS);
+ for (auto it = mActorList.robustBegin(); it != mActorList.robustEnd(); ++it) {
+ auto& actor = *it;
+ if (!isWeaponOrArmor(&actor) || actor.getProfile().include("ArmorExtra"))
+ actor.getActorFlags2().set(Actor::ActorFlag2::NoDistanceCheck);
+ }
+ mEnableDistanceChecks = true;
+}
+
+void ActorCreator::eraseActor(Actor* actor) {
+ const auto lock = sead::makeScopedLock(mActorListCS);
+ mActorList.erase(actor);
+ actor->mCreator = nullptr;
+}
+
+void ActorCreator::addScale(InstParamPack& pack, float scale) {
+ addScale(pack, {scale, scale, scale});
+}
+
+void ActorCreator::addScale(InstParamPack& pack, const sead::Vector3f& scale) {
+ sead::SafeString key = "@S";
+ pack.getBuffer().add(scale, key);
+}
+
+bool ActorCreator::isAITreeParam(const InstParamPack::Entry& entry) {
+ return sead::SafeString("=AT") == entry.key;
+}
+
+void ActorCreator::addAITreeParam(InstParamPack& pack, const sead::SafeString& value,
+ const sead::SafeString& name) {
+ pack.getBuffer().add(true, "=AT");
+ pack.getBuffer().add(value, name);
+}
+
+void ActorCreator::addAITreeParam(InstParamPack& pack, int value, const sead::SafeString& name) {
+ pack.getBuffer().add(true, "=AT");
+ pack.getBuffer().add(value, name);
+}
+
+void ActorCreator::addAITreeParam(InstParamPack& pack, u32 value, const sead::SafeString& name) {
+ pack.getBuffer().add(true, "=AT");
+ pack.getBuffer().add(value, name);
+}
+
+void ActorCreator::addAITreeParam(InstParamPack& pack, bool value, const sead::SafeString& name) {
+ pack.getBuffer().add(true, "=AT");
+ pack.getBuffer().add(value, name);
+}
+
+void ActorCreator::setCreatePriorityState1(InstParamPack& pack, BaseProc* proc) {
+ pack.setProc(proc);
+ proc->setCreatePriorityState1();
+}
+
+void ActorCreator::setCreatePriorityState2(InstParamPack& pack, BaseProc* proc) {
+ pack.setProc(proc);
+ proc->setCreatePriorityState2();
+ pack.getBuffer().add(true, "@W");
+}
+
+} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actActorCreator.h b/src/KingSystem/ActorSystem/actActorCreator.h
index ef6c229a..d25e745f 100644
--- a/src/KingSystem/ActorSystem/actActorCreator.h
+++ b/src/KingSystem/ActorSystem/actActorCreator.h
@@ -2,14 +2,26 @@
#include <container/seadOffsetList.h>
#include <heap/seadDisposer.h>
+#include <math/seadVector.h>
#include <prim/seadDelegate.h>
#include <thread/seadCriticalSection.h>
+#include "KingSystem/ActorSystem/actInstParamPack.h"
+#include "KingSystem/Utils/Thread/Task.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::map {
+class MubinIter;
+class Object;
+;
+} // namespace ksys::map
namespace ksys::act {
class Actor;
-struct ActorCreateArg;
class ActorFactory;
+class BaseProc;
+struct BaseProcCreateArg;
+class BaseProcHandle;
class ActorCreator {
SEAD_SINGLETON_DISPOSER(ActorCreator)
@@ -17,24 +29,59 @@ class ActorCreator {
virtual ~ActorCreator();
public:
- void setActorFactory(ActorFactory* factory) { mActorFactory = factory; }
+ bool requestCreateMapActor(const char* name, sead::Heap* heap, map::MubinIter* mubin_iter,
+ map::Object* map_object, BaseProcHandle* handle, int task_lane_id,
+ InstParamPack* params);
+ Actor* createActor(const char* name, sead::Heap* heap, InstParamPack* params,
+ bool sleep_after_init, bool block_other_synchronous_spawns);
+ bool requestCreateActor(const char* name, sead::Heap* heap, BaseProcHandle* handle,
+ InstParamPack* params, map::Object* map_object, int task_lane_id);
+ void enableDistanceUnloadChecks();
+ void eraseActor(Actor* actor);
+
+ void setActorFactory(ActorFactory* factory) { mActorFactory = factory; }
bool get5a() const { return _5a; }
+ static void addScale(InstParamPack& pack, float scale);
+ static void addScale(InstParamPack& pack, const sead::Vector3f& scale);
+ static bool isAITreeParam(const InstParamPack::Entry& entry);
+ static void addAITreeParam(InstParamPack& pack, const sead::SafeString& value,
+ const sead::SafeString& name);
+ static void addAITreeParam(InstParamPack& pack, int value, const sead::SafeString& name);
+ static void addAITreeParam(InstParamPack& pack, u32 value, const sead::SafeString& name);
+ static void addAITreeParam(InstParamPack& pack, bool value, const sead::SafeString& name);
+ static void setCreatePriorityState1(InstParamPack& pack, BaseProc* proc);
+ static void setCreatePriorityState2(InstParamPack& pack, BaseProc* proc);
+
private:
- sead::Heap* forBaseProcDualHeap;
- sead::Heap* placementMgrHeap;
+ bool requestCreateActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ map::MubinIter* mubin_iter, map::Object* map_object,
+ BaseProcHandle* handle, int task_lane_id, InstParamPack* params);
+ bool requestCreateActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ map::Object* map_object, BaseProcHandle* handle, int task_lane_id,
+ InstParamPack* params);
+ BaseProc* createActor_(const char* actor_class, const char* name, sead::Heap* heap,
+ InstParamPack* params, bool sleep_after_init, bool = false);
+
+ BaseProc* doCreateProc(BaseProcCreateArg& arg);
+ void onTaskRemoved(const util::TaskRemoveCallbackContext& context);
+
+ sead::Heap* mForBaseProcDualHeap;
+ sead::Heap* mPlacementMgrHeap;
sead::OffsetList<Actor> mActorList;
- void* _50;
+ void* _50{};
bool mEnableDistanceChecks;
- bool _59;
+ bool mBlockSpawns;
bool _5a;
- void* _60;
- sead::Delegate1<ActorCreator, ActorCreateArg&> mCreateActorDelegate;
- // FIXME: argument type
- sead::Delegate1<ActorCreator, void*> mCleanUpDelegate;
+ void* _60{};
+ sead::Delegate1R<ActorCreator, BaseProcCreateArg&, BaseProc*> mCreateProcDelegate{
+ this, &ActorCreator::doCreateProc};
+ util::TaskRemoveCallbackT<ActorCreator> mTaskRemovedDelegate{this,
+ &ActorCreator::onTaskRemoved};
sead::CriticalSection mActorListCS;
ActorFactory* mActorFactory;
};
+KSYS_CHECK_SIZE_NX150(ActorCreator, 0xf0);
} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actInstParamPack.cpp b/src/KingSystem/ActorSystem/actInstParamPack.cpp
index 566cb7be..a943cd06 100644
--- a/src/KingSystem/ActorSystem/actInstParamPack.cpp
+++ b/src/KingSystem/ActorSystem/actInstParamPack.cpp
@@ -39,7 +39,7 @@ bool InstParamPack::Buffer::pop(s32* position, InstParamPack::Entry* out_entry)
switch (out_entry->type) {
case EntryType::Int:
return read(out_entry->data.i, position);
- case EntryType::_1:
+ case EntryType::UInt:
return read(out_entry->data.type1, position);
case EntryType::Float:
return read(out_entry->data.f, position);
diff --git a/src/KingSystem/ActorSystem/actInstParamPack.h b/src/KingSystem/ActorSystem/actInstParamPack.h
index bbfdc74d..b5a8c61d 100644
--- a/src/KingSystem/ActorSystem/actInstParamPack.h
+++ b/src/KingSystem/ActorSystem/actInstParamPack.h
@@ -17,10 +17,10 @@ class BaseProc;
class InstParamPack {
public:
enum class EntryType {
- /// Signed(?) 32-bit integer.
+ /// Signed 32-bit integer.
Int = 0,
- /// Unknown.
- _1 = 1,
+ /// Unsigned 32-bit integer.
+ UInt = 1,
/// Single-precision float.
Float = 2,
/// Boolean.
@@ -73,7 +73,9 @@ public:
add(&data, name, sizeof(data), EntryType::Int);
}
- void add(u32 data, const sead::SafeString& name) { add(static_cast<int>(data), name); }
+ void add(u32 data, const sead::SafeString& name) {
+ add(&data, name, sizeof(data), EntryType::UInt);
+ }
void add(float data, const sead::SafeString& name) {
add(&data, name, sizeof(data), EntryType::Float);
@@ -83,6 +85,14 @@ public:
add(&data, name, sizeof(data), EntryType::Bool);
}
+ void add(const sead::Vector3f& data, const sead::SafeString& name) {
+ add(&data, name, sizeof(data), EntryType::Vec3);
+ }
+
+ void add(const sead::SafeString& data, const sead::SafeString& name) {
+ add(data.cstr(), name, data.calcLength() + 1, EntryType::String);
+ }
+
void add(const sead::Matrix34f& data, const sead::SafeString& name) {
add(&data, name, sizeof(data), EntryType::Matrix34);
}
@@ -122,6 +132,9 @@ public:
Buffer& getBuffer() { return mBuffer; }
const Buffer& getBuffer() const { return mBuffer; }
+ BaseProc* getProc() const { return mProc; }
+ void setProc(BaseProc* proc) { mProc = proc; }
+
Buffer* operator->() { return &mBuffer; }
const Buffer* operator->() const { return &mBuffer; }