summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/actAiClassDef.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-12-05 01:36:06 +0100
committerLéo Lam <leo@leolam.fr>2020-12-05 02:34:24 +0100
commitfd2f653b6ff54aa552f89c5b8daf79110d4a0e8f (patch)
tree8fd077637ef922bfe2383f7f4055ce41c4f6a3e9 /src/KingSystem/ActorSystem/actAiClassDef.cpp
parentaea46fce5e24bff47133547d9ed9f246ab8536e4 (diff)
ksys/act: Start implementing AIClassDef
Diffstat (limited to 'src/KingSystem/ActorSystem/actAiClassDef.cpp')
-rw-r--r--src/KingSystem/ActorSystem/actAiClassDef.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/KingSystem/ActorSystem/actAiClassDef.cpp b/src/KingSystem/ActorSystem/actAiClassDef.cpp
new file mode 100644
index 00000000..b9b144c9
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actAiClassDef.cpp
@@ -0,0 +1,103 @@
+#include "KingSystem/ActorSystem/actAiClassDef.h"
+#include <algorithm>
+#include <codec/seadHashCRC32.h>
+#include <prim/seadContainerIterator.h>
+#include <resource/seadResource.h>
+#include "KingSystem/Resource/resLoadRequest.h"
+
+namespace ksys {
+
+namespace {
+const char* str_AIAfter = "AIAfter";
+const char* str_ModelAfter = "ModelAfter";
+const char* str_ChangeDeleteState = "ChangeDeleteState";
+const char* str_StaticInstParams = "StaticInstParams";
+const char* str_DynamicInstParams = "DynamicInstParams";
+const char* str_MapUnitInstParams = "MapUnitInstParams";
+const char* str_AITreeVariables = "AITreeVariables";
+const char* str_AIs = "AIs";
+const char* str_Actions = "Actions";
+const char* str_Behaviors = "Behaviors";
+const char* str_Querys = "Querys";
+} // namespace
+
+SEAD_SINGLETON_DISPOSER_IMPL(AIClassDef)
+
+AIClassDef::~AIClassDef() {
+ freeData();
+}
+
+void AIClassDef::init(const sead::SafeString& aidef_file_name, sead::Heap* heap) {
+ res::LoadRequest req;
+ req.mRequester = "AIClassDef";
+ req._22 = true;
+ sead::FixedSafeString<128> path;
+ path.format("Actor/AIDef/%s", aidef_file_name.cstr());
+
+ auto* res = sead::DynamicCast<sead::DirectResource>(mResHandle.load(path, &req));
+
+ freeData();
+ mData = new (heap) Data(res->getRawData());
+ mData->load(heap);
+}
+
+// NON_MATCHING: not trying to match the heap sort. The rest should be equivalent
+bool AIClassDef::Data::load(sead::Heap* heap) {
+ root_iter.tryGetIterByKey(&iters[s32(AIDefType::AI)], str_AIs);
+ root_iter.tryGetIterByKey(&iters[s32(AIDefType::Action)], str_Actions);
+ root_iter.tryGetIterByKey(&iters[s32(AIDefType::Behavior)], str_Behaviors);
+ root_iter.tryGetIterByKey(&iters[s32(AIDefType::Query)], str_Querys);
+
+ idx_StaticInstParams = root_iter.getKeyIndex(str_StaticInstParams);
+ idx_DynamicInstParams = root_iter.getKeyIndex(str_DynamicInstParams);
+ idx_MapUnitInstParams = root_iter.getKeyIndex(str_MapUnitInstParams);
+ idx_AITreeVariables = root_iter.getKeyIndex(str_AITreeVariables);
+ idx_Childs = root_iter.getKeyIndex("childs");
+
+ static_cast<void>(heap->getFreeSize());
+
+ for (s32 type = 0; type < NumAIDefTypes; ++type) {
+ if (!iters[type].isValid())
+ continue;
+
+ const s32 count = iters[type].getSize();
+ if (count <= 0)
+ continue;
+
+ auto& buffer = defs[type];
+ buffer.allocBufferAssert(count, heap);
+
+ for (s32 i = 0; i < count; ++i) {
+ buffer[i].name_hash = 0;
+ const char* name = nullptr;
+ if (iters[type].tryGetIterAndKeyNameByIndex(&buffer[i].iter, &name, i))
+ buffer[i].name_hash = sead::HashCRC32::calcStringHash(name);
+ }
+
+ auto ct = sead::stdIterator(buffer);
+ std::sort(ct.begin(), ct.end(),
+ [](const Def& lhs, const Def& rhs) { return lhs.name_hash < rhs.name_hash; });
+ }
+
+ return true;
+}
+
+// NON_MATCHING: binary search might be a handwritten loop?
+bool AIClassDef::isSystemQuery(const sead::SafeString& query) const {
+ bool ret = false;
+ const u32 hash = sead::HashCRC32::calcStringHash(query);
+
+ if (!mData)
+ return false;
+
+ const s32 idx = mData->defs[s32(AIDefType::Query)].binarySearchC(
+ [hash](const Data::Def& def) -> s32 { return hash - def.name_hash; });
+
+ if (idx < 0)
+ return false;
+
+ mData->defs[s32(AIDefType::Query)][idx].iter.tryGetBoolByKey(&ret, "SystemQuery");
+ return ret;
+}
+
+} // namespace ksys