mirror of https://github.com/zeldaret/botw.git
ksys/act: Start implementing AIClassDef
This commit is contained in:
parent
aea46fce5e
commit
fd2f653b6f
|
@ -92285,16 +92285,16 @@
|
||||||
0x00000071011df6a8,sub_71011DF6A8,32,
|
0x00000071011df6a8,sub_71011DF6A8,32,
|
||||||
0x00000071011df6c8,sub_71011DF6C8,96,
|
0x00000071011df6c8,sub_71011DF6C8,96,
|
||||||
0x00000071011df728,sub_71011DF728,68,
|
0x00000071011df728,sub_71011DF728,68,
|
||||||
0x00000071011df76c,sub_71011DF76C,92,
|
0x00000071011df76c,sub_71011DF76C,92,_ZN4ksys10AIClassDef18SingletonDisposer_D2Ev
|
||||||
0x00000071011df7c8,sub_71011DF7C8,100,
|
0x00000071011df7c8,sub_71011DF7C8,100,_ZN4ksys10AIClassDef18SingletonDisposer_D0Ev
|
||||||
0x00000071011df82c,AIClassDef::createInstance,132,
|
0x00000071011df82c,AIClassDef::createInstance,132,_ZN4ksys10AIClassDef14createInstanceEPN4sead4HeapE
|
||||||
0x00000071011df8b0,sub_71011DF8B0,136,
|
0x00000071011df8b0,sub_71011DF8B0,136,_ZN4ksys10AIClassDefD1Ev
|
||||||
0x00000071011df938,AIClassDef::init,608,
|
0x00000071011df938,AIClassDef::init,608,_ZN4ksys10AIClassDef4initERKN4sead14SafeStringBaseIcEEPNS1_4HeapE
|
||||||
0x00000071011dfb98,AIClassDef::Data::load,1124,
|
0x00000071011dfb98,AIClassDef::Data::load,1124,_ZN4ksys10AIClassDef4Data4loadEPN4sead4HeapE!
|
||||||
0x00000071011dfffc,AIClassDef::getInfo,540,
|
0x00000071011dfffc,AIClassDef::getInfo,540,
|
||||||
0x00000071011e0218,ai::doGetClassDef,4284,
|
0x00000071011e0218,ai::doGetClassDef,4284,
|
||||||
0x00000071011e12d4,AIClassDef::getClassDef,320,
|
0x00000071011e12d4,AIClassDef::getClassDef,320,
|
||||||
0x00000071011e1414,AIClassDef::isSystemQuery,264,
|
0x00000071011e1414,AIClassDef::isSystemQuery,264,_ZNK4ksys10AIClassDef13isSystemQueryERKN4sead14SafeStringBaseIcEE!
|
||||||
0x00000071011e151c,MassRenderer::ctor,376,
|
0x00000071011e151c,MassRenderer::ctor,376,
|
||||||
0x00000071011e1694,sub_71011E1694,244,
|
0x00000071011e1694,sub_71011E1694,244,
|
||||||
0x00000071011e1788,sub_71011E1788,380,
|
0x00000071011e1788,sub_71011E1788,380,
|
||||||
|
|
Can't render this file because it is too large.
|
2
lib/sead
2
lib/sead
|
@ -1 +1 @@
|
||||||
Subproject commit dfe17af36555e553d9e18f2d7bc81d66d0c1236d
|
Subproject commit d7bf1a5232dd68886126ae9ca68698a5e07a0193
|
|
@ -25,6 +25,8 @@ target_sources(uking PRIVATE
|
||||||
actAiAction.h
|
actAiAction.h
|
||||||
actAiClass.cpp
|
actAiClass.cpp
|
||||||
actAiClass.h
|
actAiClass.h
|
||||||
|
actAiClassDef.cpp
|
||||||
|
actAiClassDef.h
|
||||||
actAiParam.cpp
|
actAiParam.cpp
|
||||||
actAiParam.h
|
actAiParam.h
|
||||||
actAiQuery.cpp
|
actAiQuery.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
|
|
@ -1,8 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <container/seadBuffer.h>
|
||||||
|
#include <container/seadSafeArray.h>
|
||||||
#include <heap/seadDisposer.h>
|
#include <heap/seadDisposer.h>
|
||||||
#include <prim/seadSafeString.h>
|
#include <prim/seadSafeString.h>
|
||||||
#include <prim/seadSizedEnum.h>
|
#include <prim/seadSizedEnum.h>
|
||||||
|
#include "KingSystem/Resource/resHandle.h"
|
||||||
|
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||||
|
#include "KingSystem/Utils/SafeDelete.h"
|
||||||
#include "KingSystem/Utils/Types.h"
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
namespace ksys {
|
namespace ksys {
|
||||||
|
@ -14,6 +19,8 @@ enum class AIDefType {
|
||||||
Query = 3,
|
Query = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr s32 NumAIDefTypes = 4;
|
||||||
|
|
||||||
enum class AIDefInstParamKind {
|
enum class AIDefInstParamKind {
|
||||||
Static = 0,
|
Static = 0,
|
||||||
Dynamic = 1,
|
Dynamic = 1,
|
||||||
|
@ -56,21 +63,53 @@ struct AIDef {
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(AIDef, 0x650);
|
KSYS_CHECK_SIZE_NX150(AIDef, 0x650);
|
||||||
|
|
||||||
// FIXME
|
|
||||||
class AIClassDef {
|
class AIClassDef {
|
||||||
SEAD_SINGLETON_DISPOSER(AIClassDef)
|
SEAD_SINGLETON_DISPOSER(AIClassDef)
|
||||||
|
AIClassDef() = default;
|
||||||
|
~AIClassDef();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(const sead::SafeString& aidef_file_name, sead::Heap* heap);
|
void init(const sead::SafeString& aidef_file_name, sead::Heap* heap);
|
||||||
|
|
||||||
void getDef(AIDef* def, const sead::SafeString& class_name, AIDefInstParamKind param_kind,
|
void getDef(AIDef* def, const sead::SafeString& class_name, AIDefInstParamKind param_kind,
|
||||||
AIDefType class_type);
|
AIDefType class_type);
|
||||||
|
|
||||||
private:
|
bool isSystemQuery(const sead::SafeString& query) const;
|
||||||
class Data;
|
|
||||||
|
|
||||||
Data* mData;
|
private:
|
||||||
// res::Handle mResHandle;
|
struct Data {
|
||||||
|
struct Def {
|
||||||
|
u32 name_hash;
|
||||||
|
al::ByamlIter iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit Data(const u8* root) : root_iter(root) {}
|
||||||
|
bool load(sead::Heap* heap);
|
||||||
|
|
||||||
|
sead::SafeArray<al::ByamlIter, NumAIDefTypes> iters;
|
||||||
|
sead::SafeArray<sead::Buffer<Def>, NumAIDefTypes> defs;
|
||||||
|
s32 idx_StaticInstParams;
|
||||||
|
s32 idx_DynamicInstParams;
|
||||||
|
s32 idx_MapUnitInstParams;
|
||||||
|
s32 idx_AITreeVariables;
|
||||||
|
s32 idx_Childs = -1;
|
||||||
|
al::ByamlIter root_iter;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(Data, 0xa8);
|
||||||
|
|
||||||
|
inline void freeData() {
|
||||||
|
if (!mData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& defs : mData->defs)
|
||||||
|
defs.freeBuffer();
|
||||||
|
|
||||||
|
util::safeDelete(mData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data* mData = nullptr;
|
||||||
|
res::Handle mResHandle;
|
||||||
};
|
};
|
||||||
// KSYS_CHECK_SIZE_NX150(AIClassDef, 0x78);
|
KSYS_CHECK_SIZE_NX150(AIClassDef, 0x78);
|
||||||
|
|
||||||
} // namespace ksys
|
} // namespace ksys
|
||||||
|
|
Loading…
Reference in New Issue