summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-12-17 23:14:09 +0100
committerLéo Lam <leo@leolam.fr>2020-12-19 20:37:37 +0100
commit8a22f0bb50bbe3aa7973d80ff1e4cc62c369f9a3 (patch)
treed673cb1c59c98357be0779e70a69f08300ef8885 /src
parentcd6bf1e82170328a1c68c515ce438f5ed977a246 (diff)
ksys/act: Add more ActionBase, Ai and RootAi functions
Diffstat (limited to 'src')
-rw-r--r--src/Game/AI/Action/actionSetLinkTagBasic.cpp4
-rw-r--r--src/Game/AI/Action/actionSetLinkTagBasic.h2
-rw-r--r--src/KingSystem/ActorSystem/actAiActionBase.cpp151
-rw-r--r--src/KingSystem/ActorSystem/actAiActionBase.h123
-rw-r--r--src/KingSystem/ActorSystem/actAiAi.cpp60
-rw-r--r--src/KingSystem/ActorSystem/actAiAi.h4
-rw-r--r--src/KingSystem/ActorSystem/actAiParam.h16
-rw-r--r--src/KingSystem/ActorSystem/actAiQuery.cpp1
-rw-r--r--src/KingSystem/ActorSystem/actAiRoot.cpp114
-rw-r--r--src/KingSystem/ActorSystem/actAiRoot.h23
-rw-r--r--src/KingSystem/Resource/resResourceAIProgram.h4
11 files changed, 478 insertions, 24 deletions
diff --git a/src/Game/AI/Action/actionSetLinkTagBasic.cpp b/src/Game/AI/Action/actionSetLinkTagBasic.cpp
index ab334e56..19d4e40d 100644
--- a/src/Game/AI/Action/actionSetLinkTagBasic.cpp
+++ b/src/Game/AI/Action/actionSetLinkTagBasic.cpp
@@ -8,7 +8,7 @@ SetLinkTagBasicAction::SetLinkTagBasicAction(const InitArg& arg) : ksys::act::ai
SetLinkTagBasicAction::~SetLinkTagBasicAction() = default;
void SetLinkTagBasicAction::enter_(ksys::act::ai::InlineParamPack* params) {
- if (IsOn.value())
+ if (*IsOn)
mActor->emitBasicSigOn();
else
mActor->emitBasicSigOff();
@@ -17,7 +17,7 @@ void SetLinkTagBasicAction::enter_(ksys::act::ai::InlineParamPack* params) {
}
void SetLinkTagBasicAction::loadParams_() {
- getParamStatic(&IsOn, "IsOn");
+ getStaticParam(&IsOn, "IsOn");
}
} // namespace uking::action
diff --git a/src/Game/AI/Action/actionSetLinkTagBasic.h b/src/Game/AI/Action/actionSetLinkTagBasic.h
index 75fd0f03..c0bb808b 100644
--- a/src/Game/AI/Action/actionSetLinkTagBasic.h
+++ b/src/Game/AI/Action/actionSetLinkTagBasic.h
@@ -16,7 +16,7 @@ public:
void loadParams_() override;
private:
- ksys::act::ai::ParamRef<bool> IsOn;
+ const bool* IsOn{};
};
KSYS_CHECK_SIZE_NX150(SetLinkTagBasicAction, 0x28);
diff --git a/src/KingSystem/ActorSystem/actAiActionBase.cpp b/src/KingSystem/ActorSystem/actAiActionBase.cpp
index 05d7e952..6de513f2 100644
--- a/src/KingSystem/ActorSystem/actAiActionBase.cpp
+++ b/src/KingSystem/ActorSystem/actAiActionBase.cpp
@@ -1,7 +1,10 @@
#include "KingSystem/ActorSystem/actAiActionBase.h"
#include "KingSystem/ActorSystem/actActorParam.h"
+#include "KingSystem/ActorSystem/actAiAction.h"
#include "KingSystem/ActorSystem/actAiRoot.h"
#include "KingSystem/Resource/resResourceAIProgram.h"
+#include "KingSystem/Utils/InitTimeInfo.h"
+#include "KingSystem/ActorSystem/actActor.h"
namespace ksys::act::ai {
@@ -12,6 +15,10 @@ inline res::AIProgram* ActionBase::getAIProg() const {
return mActor->getParam()->getRes().mAIProgram;
}
+inline auto& ActionBase::getDef() const {
+ return getAIProg()->getAction(getType(), mDefinitionIdx);
+}
+
bool ActionBase::init(sead::Heap* heap, bool skip_loading_map_or_tree_params) {
initFlags(getAIProg(), mDefinitionIdx, getType());
@@ -60,7 +67,7 @@ const char* ActionBase::getClassName() const {
return getDefaultName(getType(), mRootIdx);
}
- return getAIProg()->getAction(getType(), mDefinitionIdx).mClassName;
+ return getDef().mClassName;
}
bool ActionBase::isRootAiParamINot5() const {
@@ -89,7 +96,7 @@ void ActionBase::enter(InlineParamPack* params, const sead::SafeString& context)
const char* ActionBase::getName() const {
if (mDefinitionIdx >= 0)
- return getAIProg()->getAction(getType(), mDefinitionIdx).mName;
+ return getDef().mName;
if (mRootIdx >= 0)
return getDefaultName(getType(), mRootIdx);
@@ -107,7 +114,7 @@ void ActionBase::updateBehaviorsOnEnter() {
return;
indices = &getAIProg()->getDemoBehaviorIndices();
} else {
- indices = &getAIProg()->getAction(getType(), mDefinitionIdx).mBehaviorIndices;
+ indices = &getDef().mBehaviorIndices;
}
auto* root = mActor->getRootAi();
@@ -166,7 +173,7 @@ void ActionBase::leave() {
postLeave();
}
-void ActionBase::setRootAiFlagBit(int bit) {
+void ActionBase::setRootAiFlagBit(int bit) const {
mActor->getRootAi()->_16c.set(RootAiFlag(1u << bit));
}
@@ -188,7 +195,7 @@ void ActionBase::updateBehaviorsOnLeave() {
return;
indices = &getAIProg()->getDemoBehaviorIndices();
} else {
- indices = &getAIProg()->getAction(getType(), mDefinitionIdx).mBehaviorIndices;
+ indices = &getDef().mBehaviorIndices;
}
auto* root = mActor->getRootAi();
@@ -202,6 +209,20 @@ bool ActionBase::oneShot(InlineParamPack* params) {
return oneShot_();
}
+res::GParamList* ActionBase::getGParamList() const {
+ return mActor->getParam()->getRes().mGParamList;
+}
+
+Action* ActionBase::getCurrentAction() {
+ auto action = std::ref(*this);
+ while (true) {
+ auto* next = action.get().getCurrentChild();
+ if (!next)
+ return sead::DynamicCast<Action>(&action.get());
+ action = *next;
+ }
+}
+
void ActionBase::setFinished() {
mFlags.set(Flag::Finished);
mFlags.reset(Flag::Failed);
@@ -212,4 +233,124 @@ void ActionBase::setFailed() {
mFlags.reset(Flag::Finished);
}
+void ActionBase::getCurrentName(sead::BufferedSafeString* name, ActionBase* last) const {
+ if (!sead::IsDerivedFrom<RootAi>(this))
+ name->appendWithFormat("/%s", getName());
+
+ if (this != last && getCurrentChild())
+ getCurrentChild()->getCurrentName(name, last);
+}
+
+void ActionBase::getParams(ParamNameTypePairs* pairs, bool update_use_count) const {
+ mParams.getPairs(pairs, update_use_count);
+}
+
+void ActionBase::resetRootAiFlagBit(int bit) const {
+ mActor->getRootAi()->_16c.reset(RootAiFlag(1u << bit));
+}
+
+bool ActionBase::testRootAiFlag2Bit(int bit) const {
+ return mActor->getRootAi()->_16e.isOn(RootAiFlag2(1u << bit));
+}
+
+template <typename T>
+bool ActionBase::getStaticParam(T* value, const sead::SafeString& key) const {
+ return getAIProg()->getSInstParam(value, getDef(), key);
+}
+
+template bool ActionBase::getStaticParam(const char**, const sead::SafeString&) const;
+template bool ActionBase::getStaticParam(sead::SafeString*, const sead::SafeString&) const;
+template bool ActionBase::getStaticParam(const int**, const sead::SafeString&) const;
+template bool ActionBase::getStaticParam(const float**, const sead::SafeString&) const;
+template bool ActionBase::getStaticParam(const sead::Vector3f**, const sead::SafeString&) const;
+template bool ActionBase::getStaticParam(const bool**, const sead::SafeString&) const;
+
+void ActionBase::logMissingParam(const sead::SafeString& param) const {
+ // Stubbed in release versions
+ const auto type = getType();
+ static_cast<void>(type);
+}
+
+template <typename T>
+bool ActionBase::getMapUnitParam(T* value, const sead::SafeString& key) const {
+ return mActor->getRootAi()->getMapUnitParam(value, key);
+}
+
+template bool ActionBase::getMapUnitParam(sead::SafeString*, const sead::SafeString&) const;
+template bool ActionBase::getMapUnitParam(const int**, const sead::SafeString&) const;
+template bool ActionBase::getMapUnitParam(const float**, const sead::SafeString&) const;
+template bool ActionBase::getMapUnitParam(const sead::Vector3f**, const sead::SafeString&) const;
+template bool ActionBase::getMapUnitParam(const bool**, const sead::SafeString&) const;
+
+template <typename T>
+bool ActionBase::getAITreeVariable(T** value, const sead::SafeString& key) const {
+ return mActor->getRootAi()->getAITreeVariable(value, key);
+}
+
+template bool ActionBase::getAITreeVariable(sead::SafeString**, const sead::SafeString&) const;
+template bool ActionBase::getAITreeVariable(s32**, const sead::SafeString&) const;
+template bool ActionBase::getAITreeVariable(f32**, const sead::SafeString&) const;
+template bool ActionBase::getAITreeVariable(sead::Vector3f**, const sead::SafeString&) const;
+template bool ActionBase::getAITreeVariable(bool**, const sead::SafeString&) const;
+template bool ActionBase::getAITreeVariable(void**, const sead::SafeString&) const;
+
+namespace {
+
+BaseProcLink sDefaultBaseProcLink;
+sead::FixedSafeString<32> sDefaultString32;
+int sDefaultInt;
+float sDefaultFloat;
+bool sDefaultBool;
+Rail* sDefaultRail;
+struct ComplexDefaults {
+ util::InitConstants init_constants;
+ BaseProcHandle* base_proc_handle;
+ sead::Vector3f vec3{0, 0, 0};
+ sead::SafeString string;
+ mes::TransceiverId transceiver_id;
+};
+ComplexDefaults sDefaults;
+
+} // namespace
+
+sead::SafeString* getDefaultString() {
+ return &sDefaults.string;
+}
+
+s32* getDefaultInt() {
+ return &sDefaultInt;
+}
+
+f32* getDefaultFloat() {
+ return &sDefaultFloat;
+}
+
+sead::Vector3f* getDefaultVec3() {
+ return &sDefaults.vec3;
+}
+
+bool* getDefaultBool() {
+ return &sDefaultBool;
+}
+
+BaseProcLink* getDefaultBaseProcLink() {
+ return &sDefaultBaseProcLink;
+}
+
+mes::TransceiverId* getDefaultMesTransceiverId() {
+ return &sDefaults.transceiver_id;
+}
+
+BaseProcHandle** getDefaultBaseProcHandle() {
+ return &sDefaults.base_proc_handle;
+}
+
+Rail** getDefaultRail() {
+ return &sDefaultRail;
+}
+
+sead::FixedSafeString<32>* getDefaultString32() {
+ return &sDefaultString32;
+}
+
} // namespace ksys::act::ai
diff --git a/src/KingSystem/ActorSystem/actAiActionBase.h b/src/KingSystem/ActorSystem/actAiActionBase.h
index b67b7c9c..bfa426a2 100644
--- a/src/KingSystem/ActorSystem/actAiActionBase.h
+++ b/src/KingSystem/ActorSystem/actAiActionBase.h
@@ -4,13 +4,13 @@
#include <math/seadMathCalcCommon.h>
#include <prim/seadRuntimeTypeInfo.h>
#include <prim/seadTypedBitFlag.h>
-#include "KingSystem/ActorSystem/actActor.h"
#include "KingSystem/ActorSystem/actAiParam.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::res {
class AIProgram;
-}
+class GParamList;
+} // namespace ksys::res
namespace ksys::act {
@@ -18,12 +18,26 @@ class Actor;
namespace ai {
+class Action;
+
enum class ActionType {
AI = 0,
Action = 1,
};
enum class RootAiFlag : u16;
+enum class RootAiFlag2 : u16;
+
+sead::SafeString* getDefaultString();
+s32* getDefaultInt();
+f32* getDefaultFloat();
+sead::Vector3f* getDefaultVec3();
+bool* getDefaultBool();
+BaseProcLink* getDefaultBaseProcLink();
+mes::TransceiverId* getDefaultMesTransceiverId();
+BaseProcHandle** getDefaultBaseProcHandle();
+Rail** getDefaultRail();
+sead::FixedSafeString<32>* getDefaultString32();
/// Base class for actions and AIs, which can be seen as looping actions.
class ActionBase {
@@ -46,6 +60,8 @@ public:
void leave();
bool oneShot(InlineParamPack* params);
+ Action* getCurrentAction();
+
const char* getClassName() const;
const char* getName() const;
@@ -67,7 +83,7 @@ public:
virtual bool m18() { return true; }
virtual void m19() {}
virtual void calc() {}
- virtual void getCurrentName(sead::BufferedSafeString* name, ActionBase* parent) const;
+ virtual void getCurrentName(sead::BufferedSafeString* name, ActionBase* last) const;
virtual void* m22() { return nullptr; }
virtual void getParams(ParamNameTypePairs* pairs, bool update_use_count) const;
virtual s32 getNumChildren() const { return 0; }
@@ -100,8 +116,17 @@ protected:
void setFinished();
void setFailed();
- void setRootAiFlagBit(int bit);
- void setRootAiFlag(RootAiFlag flag) { setRootAiFlagBit(sead::log2(u32(flag))); }
+
+ void setRootAiFlagBit(int bit) const;
+ void setRootAiFlag(RootAiFlag flag) const { setRootAiFlagBit(sead::log2(u32(flag))); }
+
+ void resetRootAiFlagBit(int bit) const;
+ void resetRootAiFlag(RootAiFlag flag) const { resetRootAiFlagBit(sead::log2(u32(flag))); }
+
+ bool testRootAiFlag2Bit(int bit) const;
+ bool testRootAiFlag2(RootAiFlag2 flag) const {
+ return testRootAiFlag2Bit(sead::log2(u32(flag)));
+ }
void resetFlags() {
mFlags.reset(Flag::Failed);
@@ -110,9 +135,95 @@ protected:
}
res::AIProgram* getAIProg() const;
+ auto& getDef() const;
+ res::GParamList* getGParamList() const;
+
+ template <typename T>
+ bool getStaticParam(T* value, const sead::SafeString& key) const;
+
+ void logMissingParam(const sead::SafeString& param) const;
template <typename T>
- void getParamStatic(ParamRef<T>* value, const sead::SafeString& key);
+ bool getMapUnitParam(T* value, const sead::SafeString& key) const;
+
+ template <typename T>
+ bool getAITreeVariable(T** value, const sead::SafeString& key) const;
+
+ template <typename T>
+ bool getDynamicParamImpl(T* value, const sead::SafeString& key,
+ bool (ParamPack::*getter)(T* value, const sead::SafeString& key) const,
+ T* default_value) const {
+ auto* action = this;
+ while (action && action->mFlags.isOff(Flag::_80)) {
+ if ((action->mParams.*getter)(value, key))
+ return true;
+ if (action->mFlags.isOff(Flag::DynamicParamChild))
+ goto fail;
+ action = action->getCurrentChild();
+ if (!action)
+ goto fail;
+ }
+
+ for (s32 i = 0, n = action->getNumChildren(); i < n; ++i) {
+ auto* child = action->getChild(i);
+ if (child->getDynamicParamImpl<T>(value, key, getter, default_value))
+ return true;
+ }
+
+ fail:
+ logMissingParam(key);
+ *value = *default_value;
+ return false;
+ }
+
+ template <AIDefParamType Type, typename T>
+ bool getDynamicParamPtrImpl(T** value, const sead::SafeString& key, T* default_value) const {
+ return getDynamicParamImpl(value, key, &ParamPack::getPtrGeneric<T, Type>, &default_value);
+ }
+
+ bool getDynamicParam(sead::SafeString* value, const sead::SafeString& key) const {
+ return getDynamicParamImpl(value, key, &ParamPack::getString, getDefaultString());
+ }
+
+ bool getDynamicParam(int** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::Int>(value, key, getDefaultInt());
+ }
+
+ bool getDynamicParam(float** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::Float>(value, key, getDefaultFloat());
+ }
+
+ bool getDynamicParam(sead::Vector3f** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::Vec3>(value, key, getDefaultVec3());
+ }
+
+ bool getDynamicParam(bool** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::Bool>(value, key, getDefaultBool());
+ }
+
+ bool getDynamicParam(BaseProcLink** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::BaseProcLink>(value, key,
+ getDefaultBaseProcLink());
+ }
+
+ bool getDynamicParam(mes::TransceiverId** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::MesTransceiverId>(
+ value, key, getDefaultMesTransceiverId());
+ }
+
+ bool getDynamicParam(BaseProcHandle*** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::BaseProcHandle>(value, key,
+ getDefaultBaseProcHandle());
+ }
+
+ bool getDynamicParam(Rail*** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::Rail>(value, key, getDefaultRail());
+ }
+
+ bool getDynamicParam(sead::SafeString** value, const sead::SafeString& key) const {
+ return getDynamicParamPtrImpl<AIDefParamType::String>(
+ value, key, static_cast<sead::SafeString*>(getDefaultString32()));
+ }
Actor* mActor;
ParamPack mParams;
diff --git a/src/KingSystem/ActorSystem/actAiAi.cpp b/src/KingSystem/ActorSystem/actAiAi.cpp
index 5dee7b68..9533981e 100644
--- a/src/KingSystem/ActorSystem/actAiAi.cpp
+++ b/src/KingSystem/ActorSystem/actAiAi.cpp
@@ -1,14 +1,74 @@
#include "KingSystem/ActorSystem/actAiAi.h"
+#include "KingSystem/ActorSystem/actActor.h"
+#include "KingSystem/ActorSystem/actActorParam.h"
+#include "KingSystem/ActorSystem/actActorUtil.h"
+#include "KingSystem/ActorSystem/actAiAction.h"
#include "KingSystem/ActorSystem/actAiRoot.h"
+#include "KingSystem/Resource/resResourceAIProgram.h"
namespace ksys::act::ai {
+inline res::AIProgram* ActionBase::getAIProg() const {
+ return mActor->getParam()->getRes().mAIProgram;
+}
+
Ai::Ai(const ActionBase::InitArg& arg) : ActionBase(arg) {}
Ai::~Ai() {
mChildren.freeBuffer();
}
+bool Ai::initChildren(const AIDefSet& set, sead::Heap* heap) {
+ if (set.num_children > 0) {
+ if (mDefinitionIdx < 0)
+ return false;
+
+ auto indices = getAIProg()->getAI(mDefinitionIdx).mChildIndices;
+ if (!initChildren_(set.num_children, nullptr, indices, heap))
+ return false;
+ }
+ return true;
+}
+
+bool Ai::initChildren_(s32 num_children, const char** names, sead::Buffer<u16>& indices,
+ sead::Heap* heap) {
+ auto* actor = mActor;
+
+ if (indices.size() != num_children && !isPlayerProfile(actor) && !isCameraProfile(actor))
+ return false;
+
+ if (num_children <= 0)
+ return false;
+
+ if (!mChildren.tryAllocBuffer(num_children, heap))
+ return false;
+
+ for (s32 i = 0; i < num_children; ++i)
+ mChildren(i) = nullptr;
+
+ auto* root_ai = actor->getRootAi();
+
+ const auto num_ais = actor->getParam()->getRes().mAIProgram->getAIs().size();
+ const bool is_root_ai = sead::IsDerivedFrom<RootAi>(this);
+ const auto effective_ai_count = is_root_ai + num_ais;
+
+ auto it_idx = indices.begin();
+ auto it_ptr = mChildren.begin();
+ const auto it_idx_end = indices.end();
+ const auto it_ptr_end = mChildren.end();
+
+ for (; it_ptr != it_ptr_end && it_idx != it_idx_end; ++it_ptr, ++it_idx) {
+ if (*it_idx < effective_ai_count)
+ *it_ptr = root_ai->getAis().classes[*it_idx];
+ else
+ *it_ptr = root_ai->getActions().classes[*it_idx - effective_ai_count];
+
+ if (*it_ptr == nullptr)
+ return false;
+ }
+ return true;
+}
+
void Ai::calc() {
calc_();
diff --git a/src/KingSystem/ActorSystem/actAiAi.h b/src/KingSystem/ActorSystem/actAiAi.h
index df476277..acb8c56b 100644
--- a/src/KingSystem/ActorSystem/actAiAi.h
+++ b/src/KingSystem/ActorSystem/actAiAi.h
@@ -39,6 +39,10 @@ protected:
u16 mPendingChildIdx = InvalidIdx;
u16 mNewChildIdx = InvalidIdx;
sead::Buffer<ActionBase*> mChildren;
+
+private:
+ bool initChildren_(s32 num_children, const char** names, sead::Buffer<u16>& indices,
+ sead::Heap* heap);
};
KSYS_CHECK_SIZE_NX150(Ai, 0x38);
diff --git a/src/KingSystem/ActorSystem/actAiParam.h b/src/KingSystem/ActorSystem/actAiParam.h
index 7c7dd232..3f3dab10 100644
--- a/src/KingSystem/ActorSystem/actAiParam.h
+++ b/src/KingSystem/ActorSystem/actAiParam.h
@@ -85,6 +85,13 @@ public:
void copy(InlineParamPack* dest, bool x) const;
void getPairs(ParamNameTypePairs* pairs, bool update_use_count) const;
+ template <typename T, AIDefParamType Type>
+ bool getPtrGeneric(T** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<T*>(getAITreeVariablePointer(key, Type));
+ *value = ptr;
+ return ptr != nullptr;
+ }
+
bool getString(sead::SafeString* value, const sead::SafeString& key) const;
bool setString(const sead::SafeString& value, const sead::SafeString& key) const;
@@ -157,15 +164,6 @@ struct InlineParamPack {
};
KSYS_CHECK_SIZE_NX150(InlineParamPack, 0xA08);
-template <typename T>
-class ParamRef {
-public:
- const T& value() const { return *mValue; }
- void setValuePtr(const T* ptr) { mValue = ptr; }
-
-private:
- const T* mValue = nullptr;
-};
} // namespace act::ai
} // namespace ksys
diff --git a/src/KingSystem/ActorSystem/actAiQuery.cpp b/src/KingSystem/ActorSystem/actAiQuery.cpp
index d2259fd8..9ba2adae 100644
--- a/src/KingSystem/ActorSystem/actAiQuery.cpp
+++ b/src/KingSystem/ActorSystem/actAiQuery.cpp
@@ -1,4 +1,5 @@
#include "KingSystem/ActorSystem/actAiQuery.h"
+#include "KingSystem/ActorSystem/actActor.h"
#include "KingSystem/ActorSystem/actActorParam.h"
#include "KingSystem/ActorSystem/actAiRoot.h"
#include "KingSystem/Resource/resResourceAIProgram.h"
diff --git a/src/KingSystem/ActorSystem/actAiRoot.cpp b/src/KingSystem/ActorSystem/actAiRoot.cpp
index 9498c151..85da4dff 100644
--- a/src/KingSystem/ActorSystem/actAiRoot.cpp
+++ b/src/KingSystem/ActorSystem/actAiRoot.cpp
@@ -1,4 +1,6 @@
#include "KingSystem/ActorSystem/actAiRoot.h"
+#include "KingSystem/ActorSystem/actActor.h"
+#include "KingSystem/Utils/InitTimeInfo.h"
namespace ksys::act::ai {
@@ -28,6 +30,118 @@ bool RootAi::isActorDeletedOrDeleting() const {
return mActor->isDeletedOrDeleting();
}
+bool RootAi::getMapUnitParam(sead::SafeString* value, const sead::SafeString& key) const {
+ sead::SafeString out;
+ if (mMapUnitParams.getString(&out, key)) {
+ *value = out.cstr();
+ return true;
+ }
+ *value = sead::SafeString::cEmptyString;
+ return false;
+}
+
+bool RootAi::getMapUnitParam(const s32** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<int*>(mMapUnitParams.getAITreeVariablePointer(key, AIDefParamType::Int));
+ static const s32 sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getMapUnitParam(const f32** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<f32*>(mMapUnitParams.getAITreeVariablePointer(key, AIDefParamType::Float));
+ static const f32 sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getMapUnitParam(const sead::Vector3f** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<sead::Vector3f*>(
+ mMapUnitParams.getAITreeVariablePointer(key, AIDefParamType::Vec3));
+ *value = ptr ? ptr : &sead::Vector3f::zero;
+ return ptr != nullptr;
+}
+
+bool RootAi::getMapUnitParam(const bool** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<bool*>(mMapUnitParams.getAITreeVariablePointer(key, AIDefParamType::Bool));
+ static const bool sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+namespace {
+sead::FixedSafeString<64> sDefaultString;
+
+struct Vec3Wrapper {
+ util::InitTimeInfoEx init_time_info_ex;
+ sead::Vector3f sDefaultVec3{0, 0, 0};
+};
+Vec3Wrapper sDefaultAITreeVariables;
+} // namespace
+
+bool RootAi::getAITreeVariable(sead::SafeString** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<sead::SafeString*>(
+ mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::String));
+ *value = ptr ? ptr : &sDefaultString;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(s32** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<s32*>(mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::Int));
+ static s32 sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(f32** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<f32*>(mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::Float));
+ static f32 sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(sead::Vector3f** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<sead::Vector3f*>(
+ mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::Vec3));
+ *value = ptr ? ptr : &sDefaultAITreeVariables.sDefaultVec3;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(bool** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<bool*>(mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::Bool));
+ static bool sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(void** value, const sead::SafeString& key) const {
+ auto* ptr = static_cast<void**>(
+ mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::AITreeVariablePointer));
+ static void* sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable(u32** value, const sead::SafeString& key) const {
+ auto* ptr =
+ static_cast<u32*>(mAiTreeParams.getAITreeVariablePointer(key, AIDefParamType::UInt));
+ static u32 sDefault{};
+ *value = ptr ? ptr : &sDefault;
+ return ptr != nullptr;
+}
+
+bool RootAi::getAITreeVariable2(sead::Vector3f** value, const sead::SafeString& key) const {
+ return getAITreeVariable(value, key);
+}
+
+bool RootAi::getAITreeVariable2(bool** value, const sead::SafeString& key) const {
+ return getAITreeVariable(value, key);
+}
+
const char* getDefaultAiName(s32 root_idx) {
static constexpr const char* names[] = {"DemoRootAI", "Root"};
if (root_idx >= 2)
diff --git a/src/KingSystem/ActorSystem/actAiRoot.h b/src/KingSystem/ActorSystem/actAiRoot.h
index 54c9efbe..160dbfca 100644
--- a/src/KingSystem/ActorSystem/actAiRoot.h
+++ b/src/KingSystem/ActorSystem/actAiRoot.h
@@ -36,6 +36,9 @@ enum class RootAiFlag : u16 {
_100 = 0x100, // 8
};
+// TODO: rename
+enum class RootAiFlag2 : u16 {};
+
class RootAi : public Ai, public IRootAi {
SEAD_RTTI_OVERRIDE(RootAi, Ai)
public:
@@ -62,6 +65,24 @@ public:
bool loadMapUnitParams(const AIDef& def, sead::Heap* heap);
bool loadAITreeParams(const AIDef& def, sead::Heap* heap);
+ bool getMapUnitParam(sead::SafeString* value, const sead::SafeString& key) const;
+ bool getMapUnitParam(const s32** value, const sead::SafeString& key) const;
+ bool getMapUnitParam(const f32** value, const sead::SafeString& key) const;
+ bool getMapUnitParam(const sead::Vector3f** value, const sead::SafeString& key) const;
+ bool getMapUnitParam(const bool** value, const sead::SafeString& key) const;
+
+ bool getAITreeVariable(sead::SafeString** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(s32** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(f32** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(sead::Vector3f** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(bool** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(void** value, const sead::SafeString& key) const;
+ bool getAITreeVariable(u32** value, const sead::SafeString& key) const;
+ // TODO: rename
+ bool getAITreeVariable2(sead::Vector3f** value, const sead::SafeString& key) const;
+ // TODO: rename
+ bool getAITreeVariable2(bool** value, const sead::SafeString& key) const;
+
void setBehavior(Behavior* behavior);
void resetBehavior(Behavior* behavior);
@@ -97,7 +118,7 @@ private:
// TODO: is this really an atomic?
sead::Atomic<f32> _168 = 1.0;
sead::TypedBitFlag<RootAiFlag> _16c;
- u16 _16e{};
+ sead::TypedBitFlag<RootAiFlag2> _16e;
ParamPack mMapUnitParams;
ParamPack mAiTreeParams;
};
diff --git a/src/KingSystem/Resource/resResourceAIProgram.h b/src/KingSystem/Resource/resResourceAIProgram.h
index 242001ce..016d903b 100644
--- a/src/KingSystem/Resource/resResourceAIProgram.h
+++ b/src/KingSystem/Resource/resResourceAIProgram.h
@@ -63,6 +63,10 @@ public:
const sead::Buffer<BehaviorDef>& getBehaviors() const { return mBehaviors; }
const sead::Buffer<QueryDef>& getQueries() const { return mQueries; }
+ const AIActionDef& getAI(s32 index) const { return mAIs[index]; }
+ const sead::Buffer<AIActionDef>& getAIs() const { return mAIs; }
+ const sead::Buffer<AIActionDef>& getActions() const { return mAIs; }
+
const AIActionDef& getAction(act::ai::ActionType type, s32 index) const {
return getActionsOrAIs(type)[index];
}