mirror of
https://github.com/zeldaret/botw
synced 2026-08-21 22:20:28 -04:00
ksys/act: Implement Actions, Ais
This commit is contained in:
+30
-30
@@ -73442,14 +73442,14 @@
|
||||
0x0000007100d322e8,AI_Action_DemoVisibleOff::leave,160,
|
||||
0x0000007100d32388,AI_Action_DemoVisibleOff::rtti1,288,
|
||||
0x0000007100d324a8,AI_Action_DemoVisibleOff::rtti2,92,
|
||||
0x0000007100d32504,AI_Action_AreaCulling::ctor,48,
|
||||
0x0000007100d32534,AI_Action_LinkTagCountAction::enter,16,
|
||||
0x0000007100d32544,AI_Action_LinkTagCountAction::calc,4,
|
||||
0x0000007100d32548,AI_Action_LinkTagCountAction::leave,4,
|
||||
0x0000007100d3254c,AI_Action_LinkTagCountAction::loadParams,4,
|
||||
0x0000007100d32550,AI_Action_LinkTagCountAction::rtti1,288,
|
||||
0x0000007100d32670,AI_Action_LinkTagCountAction::rtti2,92,
|
||||
0x0000007100d326cc,AI_Action_LinkTagCountAction::dtorDelete,52,
|
||||
0x0000007100d32504,AI_Action_AreaCulling::ctor,48,_ZN4ksys3act2ai11DummyActionC1ERKNS1_10ActionBase7InitArgE
|
||||
0x0000007100d32534,AI_Action_LinkTagCountAction::enter,16,_ZN4ksys3act2ai11DummyAction6enter_EPNS1_15InlineParamPackE
|
||||
0x0000007100d32544,AI_Action_LinkTagCountAction::calc,4,_ZN4ksys3act2ai11DummyAction5calc_Ev
|
||||
0x0000007100d32548,AI_Action_LinkTagCountAction::leave,4,_ZN4ksys3act2ai11DummyAction6leave_Ev
|
||||
0x0000007100d3254c,AI_Action_LinkTagCountAction::loadParams,4,_ZN4ksys3act2ai11DummyAction11loadParams_Ev
|
||||
0x0000007100d32550,AI_Action_LinkTagCountAction::rtti1,288,_ZNK4ksys3act2ai11DummyAction27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100d32670,AI_Action_LinkTagCountAction::rtti2,92,_ZNK4ksys3act2ai11DummyAction18getRuntimeTypeInfoEv
|
||||
0x0000007100d326cc,AI_Action_LinkTagCountAction::dtorDelete,52,_ZN4ksys3act2ai11DummyActionD0Ev
|
||||
0x0000007100d32700,AI_Action_DummyDropTable::ctor,72,
|
||||
0x0000007100d32748,AI_Action_DummyDropTable::dtor,20,
|
||||
0x0000007100d3275c,AI_Action_DummyDropTable::dtorDelete,52,
|
||||
@@ -91920,14 +91920,14 @@
|
||||
0x00000071011c24fc,AI_ActionBase::rtti1,204,_ZNK4ksys3act2ai6Action27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x00000071011c25c8,AI_ActionBase::rtti2,92,_ZNK4ksys3act2ai6Action18getRuntimeTypeInfoEv
|
||||
0x00000071011c2624,AI_ActionBase::dtorDelete,52,_ZN4ksys3act2ai6ActionD0Ev
|
||||
0x00000071011c2658,ai::Actions::ctor,28,
|
||||
0x00000071011c2674,sub_71011C2674,4,
|
||||
0x00000071011c2678,sub_71011C2678,200,
|
||||
0x00000071011c2740,ai::Actions::init,1248,
|
||||
0x00000071011c2c20,sub_71011C2C20,32,
|
||||
0x00000071011c2c40,sub_71011C2C40,300,
|
||||
0x00000071011c2d6c,sub_71011C2D6C,96,
|
||||
0x00000071011c2dcc,sub_71011C2DCC,68,
|
||||
0x00000071011c2658,ai::Actions::ctor,28,_ZN4ksys3act2ai7ActionsC1Ev
|
||||
0x00000071011c2674,sub_71011C2674,4,_ZN4ksys3act2ai7ActionsD1Ev
|
||||
0x00000071011c2678,sub_71011C2678,200,_ZN4ksys3act2ai7Actions8finalizeEv
|
||||
0x00000071011c2740,ai::Actions::init,1248,_ZN4ksys3act2ai7Actions4initEPNS0_5ActorEPN4sead4HeapE
|
||||
0x00000071011c2c20,sub_71011C2C20,32,_ZN4ksys3act2ai7Actions12setFactoriesEiPNS1_13ActionFactoryE
|
||||
0x00000071011c2c40,sub_71011C2C40,300,_ZN4ksys3act2ai7Actions5cloneERKNS1_6ActionEPN4sead4HeapE
|
||||
0x00000071011c2d6c,sub_71011C2D6C,96,_ZNK4ksys3act2ai7Actions17onActorPreDelete2Ev
|
||||
0x00000071011c2dcc,sub_71011C2DCC,68,_ZNK4ksys3act2ai7Actions17onActorPreDelete1Ev
|
||||
0x00000071011c2e10,Dummy::construct,68,
|
||||
0x00000071011c2e54,getDummyBaseProcLink,12,
|
||||
0x00000071011c2e60,Actor::ctor,1208,
|
||||
@@ -92279,13 +92279,13 @@
|
||||
0x00000071011deec4,AI_AIBase::m23,216,
|
||||
0x00000071011def9c,AI_AIBase::rtti1,204,_ZNK4ksys3act2ai2Ai27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x00000071011df068,AI_AIBase::rtti2,92,_ZNK4ksys3act2ai2Ai18getRuntimeTypeInfoEv
|
||||
0x00000071011df0c4,ai::AIs::ctor,28,
|
||||
0x00000071011df0e0,sub_71011DF0E0,4,
|
||||
0x00000071011df0e4,sub_71011DF0E4,200,
|
||||
0x00000071011df1ac,ai::AIs::init,1276,
|
||||
0x00000071011df6a8,sub_71011DF6A8,32,
|
||||
0x00000071011df6c8,sub_71011DF6C8,96,
|
||||
0x00000071011df728,sub_71011DF728,68,
|
||||
0x00000071011df0c4,ai::AIs::ctor,28,_ZN4ksys3act2ai3AisC1Ev
|
||||
0x00000071011df0e0,sub_71011DF0E0,4,_ZN4ksys3act2ai3AisD1Ev
|
||||
0x00000071011df0e4,sub_71011DF0E4,200,_ZN4ksys3act2ai3Ais8finalizeEv
|
||||
0x00000071011df1ac,ai::AIs::init,1276,_ZN4ksys3act2ai3Ais4initEPNS0_5ActorEPN4sead4HeapE
|
||||
0x00000071011df6a8,sub_71011DF6A8,32,_ZN4ksys3act2ai3Ais12setFactoriesEiPNS1_9AiFactoryE
|
||||
0x00000071011df6c8,sub_71011DF6C8,96,_ZNK4ksys3act2ai3Ais17onActorPreDelete2Ev
|
||||
0x00000071011df728,sub_71011DF728,68,_ZNK4ksys3act2ai3Ais17onActorPreDelete1Ev
|
||||
0x00000071011df76c,sub_71011DF76C,92,_ZN4ksys10AIClassDef18SingletonDisposer_D2Ev
|
||||
0x00000071011df7c8,sub_71011DF7C8,100,_ZN4ksys10AIClassDef18SingletonDisposer_D0Ev
|
||||
0x00000071011df82c,AIClassDef::createInstance,132,_ZN4ksys10AIClassDef14createInstanceEPN4sead4HeapE
|
||||
@@ -94107,13 +94107,13 @@
|
||||
0x0000007101257018,sub_7101257018,964,
|
||||
0x00000071012573dc,sub_71012573DC,32,
|
||||
0x00000071012573fc,sub_71012573FC,616,
|
||||
0x0000007101257664,AI_AIDummy::ctor,48,
|
||||
0x0000007101257694,AI_AIDummy::enter,4,
|
||||
0x0000007101257698,AI_AIDummy::calc,4,
|
||||
0x000000710125769c,AI_AIDummy::rtti1,288,
|
||||
0x00000071012577bc,AI_AIDummy::rtti2,92,
|
||||
0x0000007101257818,AI_AIDummy::dtorDelete,36,
|
||||
0x000000710125783c,AI_AIDummy::m6,8,
|
||||
0x0000007101257664,AI_AIDummy::ctor,48,_ZN4ksys3act2ai7DummyAiC1ERKNS1_10ActionBase7InitArgE
|
||||
0x0000007101257694,AI_AIDummy::enter,4,_ZN4ksys3act2ai7DummyAi6enter_EPNS1_15InlineParamPackE
|
||||
0x0000007101257698,AI_AIDummy::calc,4,_ZN4ksys3act2ai7DummyAi5calc_Ev
|
||||
0x000000710125769c,AI_AIDummy::rtti1,288,_ZNK4ksys3act2ai7DummyAi27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x00000071012577bc,AI_AIDummy::rtti2,92,_ZNK4ksys3act2ai7DummyAi18getRuntimeTypeInfoEv
|
||||
0x0000007101257818,AI_AIDummy::dtorDelete,36,_ZN4ksys3act2ai7DummyAiD0Ev
|
||||
0x000000710125783c,AI_AIDummy::m6,8,_ZNK4ksys3act2ai7DummyAi10isFlag4SetEv
|
||||
0x0000007101257844,sub_7101257844,64,
|
||||
0x0000007101257884,sub_7101257884,156,
|
||||
0x0000007101257920,sub_7101257920,12,
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -63,4 +63,9 @@ target_sources(uking PRIVATE
|
||||
actInstParamPack.h
|
||||
actLifeRecoveryInfo.h
|
||||
actTag.h
|
||||
|
||||
actionDummyAction.cpp
|
||||
actionDummyAction.h
|
||||
aiDummyAi.cpp
|
||||
aiDummyAi.h
|
||||
)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#include "KingSystem/ActorSystem/actAiAction.h"
|
||||
#include <codec/seadHashCRC32.h>
|
||||
#include "KingSystem/ActorSystem/actActor.h"
|
||||
#include "KingSystem/ActorSystem/actActorParam.h"
|
||||
#include "KingSystem/ActorSystem/actAiRoot.h"
|
||||
#include "KingSystem/ActorSystem/actionDummyAction.h"
|
||||
#include "KingSystem/Resource/resResourceAIProgram.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
|
||||
@@ -9,4 +14,155 @@ void Action::calc() {
|
||||
calc_();
|
||||
}
|
||||
|
||||
Actions::Actions() = default;
|
||||
|
||||
Actions::~Actions() {
|
||||
finalize();
|
||||
}
|
||||
|
||||
void Actions::finalize() {
|
||||
for (s32 i = 0; i < classes.size(); ++i) {
|
||||
if (classes[i]) {
|
||||
delete classes[i];
|
||||
classes[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
predelete1_callbacks.freeBuffer();
|
||||
predelete2_callbacks.freeBuffer();
|
||||
classes.freeBuffer();
|
||||
}
|
||||
|
||||
bool Actions::init(Actor* actor, sead::Heap* heap) {
|
||||
const auto* aiprog = actor->getParam()->getRes().mAIProgram;
|
||||
|
||||
const auto num_actions = aiprog->getActions().size();
|
||||
if (num_actions == 0)
|
||||
return true;
|
||||
|
||||
if (!classes.tryAllocBuffer(num_actions, heap))
|
||||
return false;
|
||||
for (s32 i = 0; i < num_actions; ++i)
|
||||
classes(i) = nullptr;
|
||||
auto it_class = classes.begin();
|
||||
const auto it_class_end = classes.end();
|
||||
|
||||
Action::InitArg arg{};
|
||||
arg.actor = actor;
|
||||
arg.def_idx = -1;
|
||||
arg.root_idx = -1;
|
||||
s32 predelete1_callback_num = 0;
|
||||
s32 predelete2_callback_num = 0;
|
||||
for (; it_class != it_class_end; ++it_class) {
|
||||
const char* name;
|
||||
if (it_class.getIndex() >= num_actions) {
|
||||
arg.root_idx = it_class.getIndex() - num_actions;
|
||||
arg.def_idx = -1;
|
||||
name = getDefaultActionName(arg.root_idx);
|
||||
} else {
|
||||
arg.def_idx = it_class.getIndex();
|
||||
name = aiprog->getActions()[it_class.getIndex()].mClassName;
|
||||
}
|
||||
|
||||
auto* factory = getFactory(name);
|
||||
if (factory)
|
||||
*it_class = factory->create_fn(arg, heap);
|
||||
else
|
||||
*it_class = new (heap) DummyAction(arg);
|
||||
|
||||
if (!*it_class)
|
||||
return false;
|
||||
|
||||
predelete2_callback_num += (*it_class)->m8();
|
||||
predelete1_callback_num += (*it_class)->m7();
|
||||
}
|
||||
|
||||
// Allocate the callback lists.
|
||||
if (predelete1_callback_num != 0) {
|
||||
if (!predelete1_callbacks.tryAllocBuffer(predelete1_callback_num, heap))
|
||||
return false;
|
||||
for (s32 i = 0; i < predelete1_callback_num; ++i)
|
||||
predelete1_callbacks(i) = nullptr;
|
||||
}
|
||||
|
||||
if (predelete2_callback_num != 0) {
|
||||
if (!predelete2_callbacks.tryAllocBuffer(predelete2_callback_num, heap))
|
||||
return false;
|
||||
for (s32 i = 0; i < predelete2_callback_num; ++i)
|
||||
predelete2_callbacks(i) = nullptr;
|
||||
}
|
||||
|
||||
// Initialize each class.
|
||||
s32 idx_cb1 = 0, idx_cb2 = 0;
|
||||
for (auto it = classes.begin(), end = classes.end(); it != end; ++it) {
|
||||
if (!(*it)->init(heap, false))
|
||||
return false;
|
||||
|
||||
if ((*it)->m8()) {
|
||||
predelete2_callbacks[idx_cb2] = *it;
|
||||
++idx_cb2;
|
||||
}
|
||||
|
||||
if ((*it)->m7()) {
|
||||
predelete1_callbacks[idx_cb1] = *it;
|
||||
++idx_cb1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Action* Actions::clone(const Action& action, sead::Heap* heap) {
|
||||
auto* factory = getFactory(action.getClassName());
|
||||
if (!factory)
|
||||
return nullptr;
|
||||
|
||||
Action::InitArg arg;
|
||||
arg.actor = action.getActor();
|
||||
arg.def_idx = action.getDefinitionIdx();
|
||||
auto* clone = factory->create_fn(arg, heap);
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!clone->init(heap, true)) {
|
||||
delete clone;
|
||||
return nullptr;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
bool Actions::onActorPreDelete2() const {
|
||||
bool ok = true;
|
||||
for (auto* action : predelete2_callbacks) {
|
||||
if (action)
|
||||
ok &= action->m18();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Actions::onActorPreDelete1() const {
|
||||
for (auto* action : predelete1_callbacks) {
|
||||
if (action)
|
||||
action->m19();
|
||||
}
|
||||
}
|
||||
|
||||
ActionFactory* Actions::getFactory(const sead::SafeString& name) {
|
||||
const u32 name_hash = sead::HashCRC32::calcStringHash(name);
|
||||
const s32 idx = sFactories.binarySearch(
|
||||
name_hash, +[](const ActionFactory& factory, const u32& hash) {
|
||||
if (factory.hash < hash)
|
||||
return -1;
|
||||
if (factory.hash > hash)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
if (idx < 0)
|
||||
return nullptr;
|
||||
return sFactories.get(idx);
|
||||
}
|
||||
|
||||
void Actions::setFactories(int count, ActionFactory* factories) {
|
||||
sFactories.setBuffer(count, factories);
|
||||
}
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
#include <container/seadBuffer.h>
|
||||
#include "KingSystem/ActorSystem/actAiActionBase.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
@@ -19,6 +20,12 @@ protected:
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(Action, 0x20);
|
||||
|
||||
struct ActionFactory {
|
||||
using CreateFn = Action* (*)(const Action::InitArg& arg, sead::Heap* heap);
|
||||
u32 hash;
|
||||
CreateFn create_fn;
|
||||
};
|
||||
|
||||
class Actions {
|
||||
public:
|
||||
Actions();
|
||||
@@ -26,11 +33,22 @@ public:
|
||||
|
||||
void finalize();
|
||||
|
||||
bool init(Actor* actor, sead::Heap* heap);
|
||||
bool onActorPreDelete2() const;
|
||||
void onActorPreDelete1() const;
|
||||
|
||||
static Action* clone(const Action& action, sead::Heap* heap);
|
||||
static ActionFactory* getFactory(const sead::SafeString& name);
|
||||
static void setFactories(int count, ActionFactory* factories);
|
||||
|
||||
sead::Buffer<Action*> classes;
|
||||
// TODO: rename
|
||||
sead::Buffer<Action*> x;
|
||||
// TODO: rename
|
||||
sead::Buffer<Action*> y;
|
||||
// Non-owning buffer.
|
||||
sead::Buffer<Action*> predelete1_callbacks;
|
||||
// Non-owning buffer.
|
||||
sead::Buffer<Action*> predelete2_callbacks;
|
||||
|
||||
private:
|
||||
static inline sead::Buffer<ActionFactory> sFactories;
|
||||
};
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
|
||||
@@ -62,6 +62,8 @@ public:
|
||||
|
||||
Action* getCurrentAction();
|
||||
|
||||
Actor* getActor() const { return mActor; }
|
||||
s32 getDefinitionIdx() const { return mDefinitionIdx; }
|
||||
const char* getClassName() const;
|
||||
const char* getName() const;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "KingSystem/ActorSystem/actActorUtil.h"
|
||||
#include "KingSystem/ActorSystem/actAiAction.h"
|
||||
#include "KingSystem/ActorSystem/actAiRoot.h"
|
||||
#include "KingSystem/ActorSystem/aiDummyAi.h"
|
||||
#include "KingSystem/Resource/resResourceAIProgram.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
@@ -105,4 +106,161 @@ void Ai::updateChildIdx(u16 new_idx) {
|
||||
mPendingChildIdx = InvalidIdx;
|
||||
}
|
||||
|
||||
Ais::Ais() = default;
|
||||
|
||||
Ais::~Ais() {
|
||||
finalize();
|
||||
}
|
||||
|
||||
void Ais::finalize() {
|
||||
for (s32 i = 0; i < classes.size(); ++i) {
|
||||
if (classes[i]) {
|
||||
delete classes[i];
|
||||
classes[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
predelete1_callbacks.freeBuffer();
|
||||
predelete2_callbacks.freeBuffer();
|
||||
classes.freeBuffer();
|
||||
}
|
||||
|
||||
bool Ais::init(Actor* actor, sead::Heap* heap) {
|
||||
const auto* aiprog = actor->getParam()->getRes().mAIProgram;
|
||||
|
||||
const auto num_ais = aiprog->getAIs().size();
|
||||
if (num_ais < 0)
|
||||
return false;
|
||||
|
||||
if (!classes.tryAllocBuffer(num_ais + 1, heap))
|
||||
return false;
|
||||
for (s32 i = 0, n = classes.size(); i != n; ++i)
|
||||
classes(i) = nullptr;
|
||||
auto it_class = classes.begin();
|
||||
const auto it_class_end = classes.end();
|
||||
|
||||
Ai::InitArg arg{};
|
||||
arg.actor = actor;
|
||||
arg.def_idx = -1;
|
||||
arg.root_idx = -1;
|
||||
s32 predelete1_callback_num = 0;
|
||||
s32 predelete2_callback_num = 0;
|
||||
for (; it_class != it_class_end; ++it_class) {
|
||||
const char* name;
|
||||
if (it_class.getIndex() >= num_ais) {
|
||||
arg.root_idx = it_class.getIndex() - num_ais;
|
||||
arg.def_idx = -1;
|
||||
name = getDefaultAiName(arg.root_idx);
|
||||
} else {
|
||||
arg.def_idx = it_class.getIndex();
|
||||
name = aiprog->getAIs()[it_class.getIndex()].mClassName;
|
||||
}
|
||||
|
||||
auto* factory = getFactory(name);
|
||||
if (factory)
|
||||
*it_class = factory->create_fn(arg, heap);
|
||||
else
|
||||
*it_class = new (heap) DummyAi(arg);
|
||||
|
||||
if (!*it_class)
|
||||
return false;
|
||||
|
||||
predelete2_callback_num += (*it_class)->m8();
|
||||
predelete1_callback_num += (*it_class)->m7();
|
||||
}
|
||||
|
||||
// Allocate the callback lists.
|
||||
if (predelete1_callback_num != 0) {
|
||||
if (!predelete1_callbacks.tryAllocBuffer(predelete1_callback_num, heap))
|
||||
return false;
|
||||
for (s32 i = 0; i < predelete1_callback_num; ++i)
|
||||
predelete1_callbacks(i) = nullptr;
|
||||
}
|
||||
|
||||
if (predelete2_callback_num != 0) {
|
||||
if (!predelete2_callbacks.tryAllocBuffer(predelete2_callback_num, heap))
|
||||
return false;
|
||||
for (s32 i = 0; i < predelete2_callback_num; ++i)
|
||||
predelete2_callbacks(i) = nullptr;
|
||||
}
|
||||
|
||||
// Initialize each class.
|
||||
s32 idx_cb1 = 0, idx_cb2 = 0;
|
||||
for (auto it = classes.begin(), end = classes.end(); it != end; ++it) {
|
||||
if (!(*it)->init(heap, false))
|
||||
return false;
|
||||
|
||||
if ((*it)->m8()) {
|
||||
predelete2_callbacks[idx_cb2] = *it;
|
||||
++idx_cb2;
|
||||
}
|
||||
|
||||
if ((*it)->m7()) {
|
||||
predelete1_callbacks[idx_cb1] = *it;
|
||||
++idx_cb1;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* ai : classes) {
|
||||
if (!ai->gatherParamsFromChildren(heap))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Ai* Ais::clone(const Ai& action, sead::Heap* heap) {
|
||||
auto* factory = getFactory(action.getClassName());
|
||||
if (!factory)
|
||||
return nullptr;
|
||||
|
||||
Ai::InitArg arg;
|
||||
arg.actor = action.getActor();
|
||||
arg.def_idx = action.getDefinitionIdx();
|
||||
auto* clone = factory->create_fn(arg, heap);
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!clone->init(heap, true)) {
|
||||
delete clone;
|
||||
return nullptr;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
bool Ais::onActorPreDelete2() const {
|
||||
bool ok = true;
|
||||
for (auto* action : predelete2_callbacks) {
|
||||
if (action)
|
||||
ok &= action->m18();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Ais::onActorPreDelete1() const {
|
||||
for (auto* action : predelete1_callbacks) {
|
||||
if (action)
|
||||
action->m19();
|
||||
}
|
||||
}
|
||||
|
||||
AiFactory* Ais::getFactory(const sead::SafeString& name) {
|
||||
const u32 name_hash = sead::HashCRC32::calcStringHash(name);
|
||||
const s32 idx = sFactories.binarySearch(
|
||||
name_hash, +[](const AiFactory& factory, const u32& hash) {
|
||||
if (factory.hash < hash)
|
||||
return -1;
|
||||
if (factory.hash > hash)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
if (idx < 0)
|
||||
return nullptr;
|
||||
return sFactories.get(idx);
|
||||
}
|
||||
|
||||
void Ais::setFactories(int count, AiFactory* factories) {
|
||||
sFactories.setBuffer(count, factories);
|
||||
}
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
|
||||
@@ -25,6 +25,8 @@ public:
|
||||
ActionBase* getChild(s32 idx) const override { return mChildren[idx]; }
|
||||
virtual const char* getPreviousName();
|
||||
|
||||
bool gatherParamsFromChildren(sead::Heap* heap);
|
||||
|
||||
protected:
|
||||
virtual void calc_() {}
|
||||
virtual void handlePendingChildChange_() { changeChildState(mPendingChildIdx); }
|
||||
@@ -46,6 +48,12 @@ private:
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(Ai, 0x38);
|
||||
|
||||
struct AiFactory {
|
||||
using CreateFn = Ai* (*)(const Ai::InitArg& arg, sead::Heap* heap);
|
||||
u32 hash;
|
||||
CreateFn create_fn;
|
||||
};
|
||||
|
||||
class Ais {
|
||||
public:
|
||||
Ais();
|
||||
@@ -53,11 +61,22 @@ public:
|
||||
|
||||
void finalize();
|
||||
|
||||
bool init(Actor* actor, sead::Heap* heap);
|
||||
bool onActorPreDelete2() const;
|
||||
void onActorPreDelete1() const;
|
||||
|
||||
static Ai* clone(const Ai& ai, sead::Heap* heap);
|
||||
static AiFactory* getFactory(const sead::SafeString& name);
|
||||
static void setFactories(int count, AiFactory* factories);
|
||||
|
||||
sead::Buffer<Ai*> classes;
|
||||
// TODO: rename
|
||||
sead::Buffer<Ai*> x;
|
||||
// TODO: rename
|
||||
sead::Buffer<Ai*> y;
|
||||
// Non-owning buffer.
|
||||
sead::Buffer<Ai*> predelete1_callbacks;
|
||||
// Non-owning buffer.
|
||||
sead::Buffer<Ai*> predelete2_callbacks;
|
||||
|
||||
private:
|
||||
static inline sead::Buffer<AiFactory> sFactories;
|
||||
};
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "KingSystem/ActorSystem/actionDummyAction.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
|
||||
DummyAction::DummyAction(const InitArg& arg) : Action(arg) {}
|
||||
|
||||
void DummyAction::enter_(InlineParamPack* params) {
|
||||
mFlags.set(ActionBase::Flag::_4);
|
||||
}
|
||||
|
||||
void DummyAction::calc_() {}
|
||||
|
||||
void DummyAction::leave_() {}
|
||||
|
||||
void DummyAction::loadParams_() {}
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "KingSystem/ActorSystem/actAiAction.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
|
||||
class DummyAction : public Action {
|
||||
SEAD_RTTI_OVERRIDE(DummyAction, Action)
|
||||
public:
|
||||
explicit DummyAction(const InitArg& arg);
|
||||
void enter_(InlineParamPack* params) override;
|
||||
void leave_() override;
|
||||
void loadParams_() override;
|
||||
|
||||
protected:
|
||||
void calc_() override;
|
||||
};
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "KingSystem/ActorSystem/aiDummyAi.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
|
||||
DummyAi::DummyAi(const ActionBase::InitArg& arg) : Ai(arg) {}
|
||||
|
||||
void DummyAi::enter_(InlineParamPack* params) {}
|
||||
|
||||
void DummyAi::calc_() {}
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "KingSystem/ActorSystem/actAiAi.h"
|
||||
|
||||
namespace ksys::act::ai {
|
||||
|
||||
class DummyAi : public Ai {
|
||||
SEAD_RTTI_OVERRIDE(DummyAi, Ai)
|
||||
public:
|
||||
explicit DummyAi(const InitArg& arg);
|
||||
|
||||
bool isFlag4Set() const override { return true; }
|
||||
void enter_(InlineParamPack* params) override;
|
||||
|
||||
protected:
|
||||
void calc_() override;
|
||||
};
|
||||
|
||||
} // namespace ksys::act::ai
|
||||
Reference in New Issue
Block a user