mirror of https://github.com/zeldaret/botw.git
ksys/res: Add AIProgram
This commit is contained in:
parent
2857102a43
commit
5ab4e15967
|
@ -59,6 +59,8 @@ add_executable(uking
|
||||||
src/KingSystem/Resource/resResource.h
|
src/KingSystem/Resource/resResource.h
|
||||||
src/KingSystem/Resource/resResourceActorLink.cpp
|
src/KingSystem/Resource/resResourceActorLink.cpp
|
||||||
src/KingSystem/Resource/resResourceActorLink.h
|
src/KingSystem/Resource/resResourceActorLink.h
|
||||||
|
src/KingSystem/Resource/resResourceAIProgram.cpp
|
||||||
|
src/KingSystem/Resource/resResourceAIProgram.h
|
||||||
src/KingSystem/Resource/resResourceArchive.cpp
|
src/KingSystem/Resource/resResourceArchive.cpp
|
||||||
src/KingSystem/Resource/resResourceArchive.h
|
src/KingSystem/Resource/resResourceArchive.h
|
||||||
src/KingSystem/Resource/resResourceDemo.cpp
|
src/KingSystem/Resource/resResourceDemo.cpp
|
||||||
|
|
|
@ -88859,7 +88859,7 @@
|
||||||
0x00000071011802bc,sub_71011802BC,156,
|
0x00000071011802bc,sub_71011802BC,156,
|
||||||
0x0000007101180358,sub_7101180358,8,
|
0x0000007101180358,sub_7101180358,8,
|
||||||
0x0000007101180360,sub_7101180360,8,
|
0x0000007101180360,sub_7101180360,8,
|
||||||
0x0000007101180368,Aiprog::ctor,352,
|
0x0000007101180368,Aiprog::ctor,352,_ZN4ksys3res9AIProgramC1Ev
|
||||||
0x00000071011804c8,sub_71011804C8,68,
|
0x00000071011804c8,sub_71011804C8,68,
|
||||||
0x000000710118050c,sub_710118050C,76,
|
0x000000710118050c,sub_710118050C,76,
|
||||||
0x0000007101180558,sub_7101180558,132,
|
0x0000007101180558,sub_7101180558,132,
|
||||||
|
@ -89224,37 +89224,37 @@
|
||||||
0x00000071011a7f38,sub_71011A7F38,12,
|
0x00000071011a7f38,sub_71011A7F38,12,
|
||||||
0x00000071011a7f44,sub_71011A7F44,12,
|
0x00000071011a7f44,sub_71011A7F44,12,
|
||||||
0x00000071011a80c4,sub_71011A80C4,140,
|
0x00000071011a80c4,sub_71011A80C4,140,
|
||||||
0x00000071011a8150,sub_71011A8150,108,
|
0x00000071011a8150,sub_71011A8150,108,_ZN4ksys3res9AIProgramD1Ev
|
||||||
0x00000071011a81bc,ResourceAiprog::m2,104,
|
0x00000071011a81bc,ResourceAiprog::m2,104,_ZThn632_N4ksys3res9AIProgramD1Ev
|
||||||
0x00000071011a8224,sub_71011A8224,112,
|
0x00000071011a8224,sub_71011A8224,112,_ZThn664_N4ksys3res9AIProgramD1Ev
|
||||||
0x00000071011a8294,sub_71011A8294,108,
|
0x00000071011a8294,sub_71011A8294,108,_ZN4ksys3res9AIProgramD0Ev
|
||||||
0x00000071011a8300,ResourceAiprog::m3,104,
|
0x00000071011a8300,ResourceAiprog::m3,104,_ZThn632_N4ksys3res9AIProgramD0Ev
|
||||||
0x00000071011a8368,sub_71011A8368,112,
|
0x00000071011a8368,sub_71011A8368,112,_ZThn664_N4ksys3res9AIProgramD0Ev
|
||||||
0x00000071011a83d8,Aiprog::x,312,
|
0x00000071011a83d8,Aiprog::x,312,_ZN4ksys3res9AIProgram17finalizeAIActionsERN4sead6BufferINS1_11AIActionDefEEE
|
||||||
0x00000071011a8510,Aiprog::x_0,256,
|
0x00000071011a8510,Aiprog::x_0,256,_ZN4ksys3res9AIProgram17finalizeBehaviorsEv
|
||||||
0x00000071011a8610,Aiprog::x_1,256,
|
0x00000071011a8610,Aiprog::x_1,256,_ZN4ksys3res9AIProgram15finalizeQueriesEv
|
||||||
0x00000071011a8710,sub_71011A8710,68,
|
0x00000071011a8710,sub_71011A8710,68,_ZN4ksys3res9AIProgram9doCreate_EPhjPN4sead4HeapE
|
||||||
0x00000071011a8754,ResourceAiprog::doCreate,68,
|
0x00000071011a8754,ResourceAiprog::doCreate,68,_ZThn632_N4ksys3res9AIProgram9doCreate_EPhjPN4sead4HeapE
|
||||||
0x00000071011a8798,Aiprog::parse,1116,
|
0x00000071011a8798,Aiprog::parse,1116,_ZN4ksys3res9AIProgram6parse_EPhmPN4sead4HeapE!
|
||||||
0x00000071011a8bf4,Aiprog::parseListAIAction,2624,
|
0x00000071011a8bf4,Aiprog::parseListAIAction,2624,_ZN4ksys3res9AIProgram14parseAIActionsERN4sead6BufferINS1_11AIActionDefEEEPNS2_4HeapERN3agl3utl13ParameterListERKNSA_16ResParameterListEPKc!
|
||||||
0x00000071011a9634,Aiprog::parseListBehavior,1204,
|
0x00000071011a9634,Aiprog::parseListBehavior,1204,_ZN4ksys3res9AIProgram14parseBehaviorsEPN4sead4HeapERKN3agl3utl16ResParameterListE
|
||||||
0x00000071011a9ae8,Aiprog::parseListQuery,1204,
|
0x00000071011a9ae8,Aiprog::parseListQuery,1204,_ZN4ksys3res9AIProgram12parseQueriesEPN4sead4HeapERKN3agl3utl16ResParameterListE
|
||||||
0x00000071011a9f9c,ResourceAiprog::parse,8,
|
0x00000071011a9f9c,ResourceAiprog::parse,8,_ZThn632_N4ksys3res9AIProgram6parse_EPhmPN4sead4HeapE
|
||||||
0x00000071011a9fa4,Aiprog::m5,196,
|
0x00000071011a9fa4,Aiprog::m5,196,_ZN4ksys3res9AIProgram9finalize_Ev?
|
||||||
0x00000071011aa068,ResourceAiprog::m5,8,
|
0x00000071011aa068,ResourceAiprog::m5,8,_ZThn632_N4ksys3res9AIProgram9finalize_Ev
|
||||||
0x00000071011aa070,Aiprog::loadDefParameters,1556,
|
0x00000071011aa070,Aiprog::loadDefParameters,1556,_ZN4ksys3res9AIProgram14parseDefParamsEPNS1_10DefinitionEPvPN4sead4HeapERKN3agl3utl16ResParameterListEPtSD_
|
||||||
0x00000071011aa684,sub_71011AA684,256,
|
0x00000071011aa684,sub_71011AA684,256,_ZN4ksys3res9AIProgram10Definition14addSInstParam_IN4sead14SafeStringBaseIcEEEEbiPKcPNS4_4HeapERKT_
|
||||||
0x00000071011aa784,Aiprog::getActionsOrAIs,20,
|
0x00000071011aa784,Aiprog::getActionsOrAIs,20,_ZNK4ksys3res9AIProgram15getActionsOrAIsENS1_12AIActionTypeE
|
||||||
0x00000071011aa840,Aiprog::x_2,208,
|
0x00000071011aa840,Aiprog::x_2,208,_ZNK4ksys3res9AIProgram13getSInstParamEPN4sead14SafeStringBaseIcEERKNS1_10DefinitionERKS4_
|
||||||
0x00000071011aa910,sub_71011AA910,156,
|
0x00000071011aa910,sub_71011AA910,156,_ZNK4ksys3res9AIProgram13getSInstParamEPPKiRKNS1_10DefinitionERKN4sead14SafeStringBaseIcEE?
|
||||||
0x00000071011aaa48,Aiprog::x_3,156,
|
0x00000071011aaa48,Aiprog::x_3,156,_ZNK4ksys3res9AIProgram13getSInstParamEPPKN4sead7Vector3IfEERKNS1_10DefinitionERKNS2_14SafeStringBaseIcEE?
|
||||||
0x00000071011aaae4,sub_71011AAAE4,168,
|
0x00000071011aaae4,sub_71011AAAE4,168,_ZNK4ksys3res9AIProgram13getSInstParamEPPKbRKNS1_10DefinitionERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011aab8c,sub_71011AAB8C,8,
|
0x00000071011aab8c,sub_71011AAB8C,8,_ZNK4ksys3res9AIProgram27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE?
|
||||||
0x00000071011aab94,sub_71011AAB94,92,
|
0x00000071011aab94,sub_71011AAB94,92,_ZNK4ksys3res9AIProgram18getRuntimeTypeInfoEv
|
||||||
0x00000071011aabf0,sub_71011AABF0,8,
|
0x00000071011aabf0,sub_71011AABF0,8,_ZNK4ksys3res9AIProgram10needsParseEv
|
||||||
0x00000071011aabf8,ResourceAiprog::m0,8,
|
0x00000071011aabf8,ResourceAiprog::m0,8,_ZThn632_NK4ksys3res9AIProgram27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE?
|
||||||
0x00000071011aac00,ResourceAiprog::m1,92,
|
0x00000071011aac00,ResourceAiprog::m1,92,_ZThn632_NK4ksys3res9AIProgram18getRuntimeTypeInfoEv
|
||||||
0x00000071011aac5c,ResourceAiprog::needsParse,8,
|
0x00000071011aac5c,ResourceAiprog::needsParse,8,_ZThn632_NK4ksys3res9AIProgram10needsParseEv
|
||||||
0x00000071011aadd8,sub_71011AADD8,364,
|
0x00000071011aadd8,sub_71011AADD8,364,
|
||||||
0x00000071011aaf44,sub_71011AAF44,140,
|
0x00000071011aaf44,sub_71011AAF44,140,
|
||||||
0x00000071011aafd0,sub_71011AAFD0,136,
|
0x00000071011aafd0,sub_71011AAFD0,136,
|
||||||
|
|
Can't render this file because it is too large.
|
2
lib/agl
2
lib/agl
|
@ -1 +1 @@
|
||||||
Subproject commit 27e919f21530a5c7b2186d9c616f9ad590b71496
|
Subproject commit 2f5bcf2d6617da25a9d60470ae4e5da8380965a1
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <heap/seadDisposer.h>
|
||||||
|
#include <prim/seadSafeString.h>
|
||||||
|
#include <prim/seadSizedEnum.h>
|
||||||
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
|
namespace ksys {
|
||||||
|
|
||||||
|
enum class AIDefType {
|
||||||
|
AI = 0,
|
||||||
|
Action = 1,
|
||||||
|
Behavior = 2,
|
||||||
|
Query = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AIDefInstParamKind {
|
||||||
|
Static = 0,
|
||||||
|
Dynamic = 1,
|
||||||
|
MapUnit = 2,
|
||||||
|
AITree = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AIDefParamType {
|
||||||
|
String = 0,
|
||||||
|
Int = 1,
|
||||||
|
Float = 2,
|
||||||
|
Vec3 = 3,
|
||||||
|
Bool = 4,
|
||||||
|
Tree = 5,
|
||||||
|
AITreeVariablePointer = 6,
|
||||||
|
UInt = 7,
|
||||||
|
BaseProcLink = 8,
|
||||||
|
MesTransceiverId = 9,
|
||||||
|
BaseProcHandle = 10,
|
||||||
|
Rail = 11,
|
||||||
|
Other = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AIDef {
|
||||||
|
union Value {
|
||||||
|
u8 raw[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr size_t NumParametersMax = 64;
|
||||||
|
|
||||||
|
const char* param_names[NumParametersMax];
|
||||||
|
sead::SizedEnum<AIDefParamType, u8> param_types[NumParametersMax];
|
||||||
|
s32 num_params;
|
||||||
|
u32 calc_timing;
|
||||||
|
bool no_stop;
|
||||||
|
bool trigger_action;
|
||||||
|
bool dynamic_param_child;
|
||||||
|
u8 _24b;
|
||||||
|
Value param_values[NumParametersMax];
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(AIDef, 0x650);
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
class AIClassDef {
|
||||||
|
SEAD_SINGLETON_DISPOSER(AIClassDef)
|
||||||
|
public:
|
||||||
|
void init(const sead::SafeString& aidef_file_name, sead::Heap* heap);
|
||||||
|
|
||||||
|
void getDef(AIDef* def, const sead::SafeString& class_name, AIDefInstParamKind param_kind,
|
||||||
|
AIDefType class_type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Data;
|
||||||
|
|
||||||
|
Data* mData;
|
||||||
|
// res::Handle mResHandle;
|
||||||
|
};
|
||||||
|
// KSYS_CHECK_SIZE_NX150(AIClassDef, 0x78);
|
||||||
|
|
||||||
|
} // namespace ksys
|
|
@ -8,38 +8,38 @@ ParamPack::~ParamPack() {
|
||||||
auto* param = mParams;
|
auto* param = mParams;
|
||||||
while (param) {
|
while (param) {
|
||||||
if (param->data) {
|
if (param->data) {
|
||||||
switch (Param::Type(param->type)) {
|
switch (param->type) {
|
||||||
case Param::Type::String:
|
case AIDefParamType::String:
|
||||||
delete static_cast<sead::SafeString*>(param->data);
|
delete static_cast<sead::SafeString*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Int:
|
case AIDefParamType::Int:
|
||||||
delete static_cast<int*>(param->data);
|
delete static_cast<int*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Float:
|
case AIDefParamType::Float:
|
||||||
delete static_cast<float*>(param->data);
|
delete static_cast<float*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Vec3:
|
case AIDefParamType::Vec3:
|
||||||
delete static_cast<sead::Vector3f*>(param->data);
|
delete static_cast<sead::Vector3f*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Bool:
|
case AIDefParamType::Bool:
|
||||||
delete static_cast<bool*>(param->data);
|
delete static_cast<bool*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::AITreeVariablePointer:
|
case AIDefParamType::AITreeVariablePointer:
|
||||||
delete static_cast<void**>(param->data);
|
delete static_cast<void**>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::UInt:
|
case AIDefParamType::UInt:
|
||||||
delete static_cast<u32*>(param->data);
|
delete static_cast<u32*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::MesTransceiverId:
|
case AIDefParamType::MesTransceiverId:
|
||||||
delete static_cast<mes::TransceiverId*>(param->data);
|
delete static_cast<mes::TransceiverId*>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::BaseProcHandle:
|
case AIDefParamType::BaseProcHandle:
|
||||||
delete static_cast<BaseProcHandle**>(param->data);
|
delete static_cast<BaseProcHandle**>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Rail:
|
case AIDefParamType::Rail:
|
||||||
delete static_cast<Rail**>(param->data);
|
delete static_cast<Rail**>(param->data);
|
||||||
break;
|
break;
|
||||||
case Param::Type::BaseProcLink:
|
case AIDefParamType::BaseProcLink:
|
||||||
delete static_cast<BaseProcLink*>(param->data);
|
delete static_cast<BaseProcLink*>(param->data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -58,47 +58,47 @@ void InlineParamPack::copyToParamPack(ParamPack& pack) const {
|
||||||
const InlineParam* param = params;
|
const InlineParam* param = params;
|
||||||
for (u32 i = 0; i < n; ++i, ++param) {
|
for (u32 i = 0; i < n; ++i, ++param) {
|
||||||
switch (param->type) {
|
switch (param->type) {
|
||||||
case Param::Type::String: {
|
case AIDefParamType::String: {
|
||||||
const sead::SafeString src = param->cstr;
|
const sead::SafeString src = param->cstr;
|
||||||
const sead::SafeString key = param->key;
|
const sead::SafeString key = param->key;
|
||||||
auto* dst = pack.getVariable<sead::BufferedSafeString>(key, Param::Type::String);
|
auto* dst = pack.getVariable<sead::BufferedSafeString>(key, AIDefParamType::String);
|
||||||
if (dst)
|
if (dst)
|
||||||
dst->copy(src);
|
dst->copy(src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Param::Type::Int:
|
case AIDefParamType::Int:
|
||||||
pack.setVariable(param->key, Param::Type::Int, param->i);
|
pack.setVariable(param->key, AIDefParamType::Int, param->i);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Float:
|
case AIDefParamType::Float:
|
||||||
pack.setVariable(param->key, Param::Type::Float, param->f);
|
pack.setVariable(param->key, AIDefParamType::Float, param->f);
|
||||||
break;
|
break;
|
||||||
case Param::Type::Vec3:
|
case AIDefParamType::Vec3:
|
||||||
if (auto* dst = pack.getVariable<sead::Vector3f>(param->key, Param::Type::Vec3)) {
|
if (auto* dst = pack.getVariable<sead::Vector3f>(param->key, AIDefParamType::Vec3)) {
|
||||||
dst->x = param->vec3.x;
|
dst->x = param->vec3.x;
|
||||||
dst->y = param->vec3.y;
|
dst->y = param->vec3.y;
|
||||||
dst->z = param->vec3.z;
|
dst->z = param->vec3.z;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Param::Type::Bool:
|
case AIDefParamType::Bool:
|
||||||
pack.setVariable(param->key, Param::Type::Bool, param->b);
|
pack.setVariable(param->key, AIDefParamType::Bool, param->b);
|
||||||
break;
|
break;
|
||||||
case Param::Type::UInt:
|
case AIDefParamType::UInt:
|
||||||
pack.setVariable(param->key, Param::Type::UInt, param->u);
|
pack.setVariable(param->key, AIDefParamType::UInt, param->u);
|
||||||
break;
|
break;
|
||||||
case Param::Type::BaseProcLink:
|
case AIDefParamType::BaseProcLink:
|
||||||
pack.setVariable(param->key, Param::Type::BaseProcLink, param->baseProcLink);
|
pack.setVariable(param->key, AIDefParamType::BaseProcLink, param->baseProcLink);
|
||||||
break;
|
break;
|
||||||
case Param::Type::MesTransceiverId:
|
case AIDefParamType::MesTransceiverId:
|
||||||
pack.setVariable(param->key, Param::Type::MesTransceiverId, param->mesTransceiverId);
|
pack.setVariable(param->key, AIDefParamType::MesTransceiverId, param->mesTransceiverId);
|
||||||
break;
|
break;
|
||||||
case Param::Type::BaseProcHandle: {
|
case AIDefParamType::BaseProcHandle: {
|
||||||
auto* baseProcHandle = static_cast<BaseProcHandle*>(param->ptr);
|
auto* baseProcHandle = static_cast<BaseProcHandle*>(param->ptr);
|
||||||
pack.setVariable(param->key, Param::Type::BaseProcHandle, baseProcHandle);
|
pack.setVariable(param->key, AIDefParamType::BaseProcHandle, baseProcHandle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Param::Type::Rail: {
|
case AIDefParamType::Rail: {
|
||||||
auto* rail = static_cast<Rail*>(param->ptr);
|
auto* rail = static_cast<Rail*>(param->ptr);
|
||||||
pack.setVariable(param->key, Param::Type::Rail, rail);
|
pack.setVariable(param->key, AIDefParamType::Rail, rail);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include <basis/seadTypes.h>
|
#include <basis/seadTypes.h>
|
||||||
#include <math/seadVector.h>
|
#include <math/seadVector.h>
|
||||||
#include <prim/seadSafeString.h>
|
#include <prim/seadSafeString.h>
|
||||||
|
#include <prim/seadSizedEnum.h>
|
||||||
|
|
||||||
|
#include "KingSystem/ActorSystem/actAiClassDef.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProc.h"
|
#include "KingSystem/ActorSystem/actBaseProc.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||||
#include "KingSystem/MessageSystem/mesTransceiver.h"
|
#include "KingSystem/MessageSystem/mesTransceiver.h"
|
||||||
|
@ -17,27 +19,11 @@ class Rail;
|
||||||
namespace act::ai {
|
namespace act::ai {
|
||||||
|
|
||||||
struct Param {
|
struct Param {
|
||||||
enum class Type {
|
|
||||||
String = 0,
|
|
||||||
Int = 1,
|
|
||||||
Float = 2,
|
|
||||||
Vec3 = 3,
|
|
||||||
Bool = 4,
|
|
||||||
Tree = 5,
|
|
||||||
AITreeVariablePointer = 6,
|
|
||||||
UInt = 7,
|
|
||||||
BaseProcLink = 8,
|
|
||||||
MesTransceiverId = 9,
|
|
||||||
BaseProcHandle = 10,
|
|
||||||
Rail = 11,
|
|
||||||
Other = 12,
|
|
||||||
};
|
|
||||||
|
|
||||||
Param* next;
|
Param* next;
|
||||||
u32 hash;
|
u32 hash;
|
||||||
const char* name;
|
const char* name;
|
||||||
void* data;
|
void* data;
|
||||||
u16 type;
|
sead::SizedEnum<AIDefParamType, u16> type;
|
||||||
bool used;
|
bool used;
|
||||||
u8 _23;
|
u8 _23;
|
||||||
};
|
};
|
||||||
|
@ -49,12 +35,12 @@ public:
|
||||||
~ParamPack();
|
~ParamPack();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* getVariable(const sead::SafeString& key, Param::Type type, bool a4 = true) const {
|
T* getVariable(const sead::SafeString& key, AIDefParamType type, bool a4 = true) const {
|
||||||
const u32 hash = agl::utl::ParameterBase::calcHash(key);
|
const u32 hash = agl::utl::ParameterBase::calcHash(key);
|
||||||
auto* param = mParams;
|
auto* param = mParams;
|
||||||
if (!param)
|
if (!param)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
while (param->hash != hash || Param::Type(param->type) != type) {
|
while (param->hash != hash || param->type != type) {
|
||||||
param = param->next;
|
param = param->next;
|
||||||
if (!param)
|
if (!param)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -65,7 +51,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void setVariable(const sead::SafeString& key, Param::Type type, const T& val) const {
|
void setVariable(const sead::SafeString& key, AIDefParamType type, const T& val) const {
|
||||||
T* variable = getVariable<T>(key, type, true);
|
T* variable = getVariable<T>(key, type, true);
|
||||||
if (variable)
|
if (variable)
|
||||||
*variable = val;
|
*variable = val;
|
||||||
|
@ -87,7 +73,7 @@ struct InlineParam {
|
||||||
BaseProcLink baseProcLink;
|
BaseProcLink baseProcLink;
|
||||||
sead::Vector3f vec3;
|
sead::Vector3f vec3;
|
||||||
mes::TransceiverId mesTransceiverId;
|
mes::TransceiverId mesTransceiverId;
|
||||||
Param::Type type;
|
AIDefParamType type;
|
||||||
const char* key;
|
const char* key;
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(InlineParam, 0x50);
|
KSYS_CHECK_SIZE_NX150(InlineParam, 0x50);
|
||||||
|
|
|
@ -0,0 +1,447 @@
|
||||||
|
#include "KingSystem/Resource/resResourceAIProgram.h"
|
||||||
|
#include <agl/Utils/aglParameter.h>
|
||||||
|
#include <heap/seadHeapMgr.h>
|
||||||
|
#include "KingSystem/ActorSystem/actAiClassDef.h"
|
||||||
|
#include "KingSystem/Resource/resCurrentResNameMgr.h"
|
||||||
|
#include "KingSystem/Utils/HeapUtil.h"
|
||||||
|
|
||||||
|
namespace ksys::res {
|
||||||
|
|
||||||
|
AIProgram::AIProgram() : ParamIO("aiprog", 0) {}
|
||||||
|
|
||||||
|
AIProgram::~AIProgram() = default;
|
||||||
|
|
||||||
|
const sead::Buffer<AIProgram::AIActionDef>& AIProgram::getActionsOrAIs(AIActionType type) const {
|
||||||
|
return type == AIActionType::AI ? mAIs : mActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::doCreate_(u8*, u32, sead::Heap*) {
|
||||||
|
mStr = CurrentResNameMgr::instance()->getCurrentResName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parseAIActionIdx(agl::utl::ResParameterObj obj, sead::Buffer<u16>& buffer,
|
||||||
|
sead::Heap* heap, bool clear = false) {
|
||||||
|
if (obj.ptr() == nullptr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto num = obj.getNum();
|
||||||
|
if (num == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!buffer.tryAllocBuffer(num, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (clear) {
|
||||||
|
for (s32 i = 0; i < num; ++i)
|
||||||
|
buffer(i) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = buffer.begin(), it_end = buffer.end();
|
||||||
|
auto it_res = obj.begin(), it_res_end = obj.end();
|
||||||
|
auto* res_ptr = it_res.getParam().ptr();
|
||||||
|
for (; it != it_end && it_res != it_res_end; ++it, ++it_res)
|
||||||
|
*it = *agl::utl::ResParameter{res_ptr + it.getIndex()}.getData<s32>();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parseBehaviorIdx(agl::utl::ResParameterObj obj, sead::Buffer<u8>& buffer,
|
||||||
|
sead::Heap* heap) {
|
||||||
|
if (obj.ptr() == nullptr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto num = obj.getNum();
|
||||||
|
if (num == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!buffer.tryAllocBuffer(num, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < num; ++i)
|
||||||
|
buffer(i) = 0;
|
||||||
|
|
||||||
|
auto it = buffer.begin(), it_end = buffer.end();
|
||||||
|
auto it_res = obj.begin(), it_res_end = obj.end();
|
||||||
|
for (; it != it_end && it_res != it_res_end; ++it, ++it_res)
|
||||||
|
*it = *it_res.getParam().getData<s32>();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NON_MATCHING: the parameter iteration loops in parseAIActionIdx and parseBehaviorIdx
|
||||||
|
bool AIProgram::parse_(u8* data, size_t, sead::Heap* parent_heap) {
|
||||||
|
if (data) {
|
||||||
|
auto* heap = util::tryCreateDualHeap(parent_heap);
|
||||||
|
mHeap = heap;
|
||||||
|
if (!heap)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
heap->enableWarning(false);
|
||||||
|
heap = mHeap;
|
||||||
|
|
||||||
|
agl::utl::ResParameterArchive archive{data};
|
||||||
|
const auto root = archive.getRootList();
|
||||||
|
|
||||||
|
if (!parseAIActions(mAIs, heap, mParamListAI, root, "AI") ||
|
||||||
|
!parseAIActions(mActions, heap, mParamListAction, root, "Action") ||
|
||||||
|
!parseBehaviors(heap, root) || !parseQueries(heap, root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ai_idx_obj = agl::utl::getResParameterObj(root, "DemoAIActionIdx");
|
||||||
|
if (!parseAIActionIdx(ai_idx_obj, mDemoAIActionIndices, heap)) {
|
||||||
|
mHeap->adjust();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto behavior_idx_obj = agl::utl::getResParameterObj(root, "DemoBehaviorIdx");
|
||||||
|
if (!parseBehaviorIdx(behavior_idx_obj, mDemoBehaviorIndices, heap)) {
|
||||||
|
mHeap->adjust();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyResParameterArchive(agl::utl::ResParameterArchive{data});
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeap->adjust();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NON_MATCHING: the parameter iteration loops in parseAIActionIdx and parseBehaviorIdx
|
||||||
|
bool AIProgram::parseAIActions(sead::Buffer<AIActionDef>& defs, sead::Heap* heap,
|
||||||
|
agl::utl::ParameterList& target_list,
|
||||||
|
const agl::utl::ResParameterList& root, const char* type_name) {
|
||||||
|
const auto list = agl::utl::getResParameterList(root, type_name);
|
||||||
|
if (!list.ptr())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto num = list.getResParameterListNum();
|
||||||
|
if (num == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!defs.tryAllocBuffer(num, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto& action : defs) {
|
||||||
|
action.mClassName = "";
|
||||||
|
action.mName = "";
|
||||||
|
action.mGroupName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it_res = list.listBegin();
|
||||||
|
const auto it_res_end = list.listEnd();
|
||||||
|
|
||||||
|
sead::FixedSafeString<32> list_name{type_name};
|
||||||
|
list_name.append("_");
|
||||||
|
const s32 trim_length = list_name.calcLength();
|
||||||
|
|
||||||
|
auto it = defs.begin();
|
||||||
|
const auto it_end = defs.end();
|
||||||
|
for (; it != it_end && it_res != it_res_end; ++it, ++it_res) {
|
||||||
|
list_name.trim(trim_length);
|
||||||
|
list_name.appendWithFormat("%d", it.getIndex());
|
||||||
|
target_list.addList(&it->mList, list_name);
|
||||||
|
|
||||||
|
const auto res = *it_res;
|
||||||
|
const auto def_obj = agl::utl::getResParameterObj(res, "Def");
|
||||||
|
if (def_obj.ptr()) {
|
||||||
|
it->mName = agl::utl::getResParameter(def_obj, "Name").getData<char>();
|
||||||
|
it->mClassName = agl::utl::getResParameter(def_obj, "ClassName").getData<char>();
|
||||||
|
|
||||||
|
const auto group_name = agl::utl::getResParameter(def_obj, "GroupName");
|
||||||
|
if (group_name.ptr())
|
||||||
|
it->mGroupName = group_name.getData<char>();
|
||||||
|
else
|
||||||
|
it->mGroupName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto child_idx_obj = agl::utl::getResParameterObj(res, "ChildIdx");
|
||||||
|
if (!parseAIActionIdx(child_idx_obj, it->mChildIndices, heap, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto behavior_idx_obj = agl::utl::getResParameterObj(res, "BehaviorIdx");
|
||||||
|
if (!parseBehaviorIdx(behavior_idx_obj, it->mBehaviorIndices, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!parseDefParams(&*it, &defs, heap, res, &it->mTriggerAction, &it->mDynamicParamChild))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addList(&target_list, type_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::parseBehaviors(sead::Heap* heap, const agl::utl::ResParameterList& root) {
|
||||||
|
const auto list = agl::utl::getResParameterList(root, "Behavior");
|
||||||
|
if (!list.ptr())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto num = list.getResParameterListNum();
|
||||||
|
if (num == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!mBehaviors.tryAllocBuffer(num, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto& behavior : mBehaviors) {
|
||||||
|
behavior.mClassName = "";
|
||||||
|
behavior.mName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it_res = list.listBegin();
|
||||||
|
const auto it_res_end = list.listEnd();
|
||||||
|
|
||||||
|
sead::FixedSafeString<32> list_name{"Behavior_"};
|
||||||
|
const s32 trim_length = list_name.calcLength();
|
||||||
|
|
||||||
|
auto it = mBehaviors.begin();
|
||||||
|
const auto it_end = mBehaviors.end();
|
||||||
|
for (; it != it_end && it_res != it_res_end; ++it, ++it_res) {
|
||||||
|
list_name.trim(trim_length);
|
||||||
|
list_name.appendWithFormat("%d", it.getIndex());
|
||||||
|
mParamListBehavior.addList(&it->mList, list_name);
|
||||||
|
|
||||||
|
const auto res = *it_res;
|
||||||
|
const auto obj = agl::utl::getResParameterObj(res, "Def");
|
||||||
|
if (obj.ptr()) {
|
||||||
|
const auto name_param = agl::utl::getResParameter(obj, "ClassName");
|
||||||
|
it->mClassName = name_param.getData<char>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parseDefParams(&*it, &mBehaviors, heap, res, &it->mCalcTiming, &it->mNoStop))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addList(&mParamListBehavior, "Behavior");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::parseQueries(sead::Heap* heap, const agl::utl::ResParameterList& root) {
|
||||||
|
const auto list = agl::utl::getResParameterList(root, "Query");
|
||||||
|
if (!list.ptr())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto num = list.getResParameterListNum();
|
||||||
|
if (num == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!mQueries.tryAllocBuffer(num, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto& query : mQueries) {
|
||||||
|
query.mClassName = "";
|
||||||
|
query.mName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it_res = list.listBegin();
|
||||||
|
const auto it_res_end = list.listEnd();
|
||||||
|
|
||||||
|
sead::FixedSafeString<32> list_name{"Query_"};
|
||||||
|
const s32 trim_length = list_name.calcLength();
|
||||||
|
|
||||||
|
auto it = mQueries.begin();
|
||||||
|
const auto it_end = mQueries.end();
|
||||||
|
for (; it != it_end && it_res != it_res_end; ++it, ++it_res) {
|
||||||
|
list_name.trim(trim_length);
|
||||||
|
list_name.appendWithFormat("%d", it.getIndex());
|
||||||
|
mParamListQuery.addList(&it->mList, list_name);
|
||||||
|
|
||||||
|
const auto res = *it_res;
|
||||||
|
const auto obj = agl::utl::getResParameterObj(res, "Def");
|
||||||
|
if (obj.ptr()) {
|
||||||
|
const auto name_param = agl::utl::getResParameter(obj, "ClassName");
|
||||||
|
it->mClassName = name_param.getData<char>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parseDefParams(&*it, &mQueries, heap, res, nullptr, nullptr))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addList(&mParamListQuery, "Query");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::finalize_() {
|
||||||
|
{
|
||||||
|
sead::ScopedCurrentHeapSetter setter{mHeap};
|
||||||
|
|
||||||
|
finalizeAIActions(mAIs);
|
||||||
|
finalizeAIActions(mActions);
|
||||||
|
finalizeBehaviors();
|
||||||
|
finalizeQueries();
|
||||||
|
mDemoBehaviorIndices.freeBuffer();
|
||||||
|
mDemoAIActionIndices.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mHeap) {
|
||||||
|
mHeap->destroy();
|
||||||
|
mHeap = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::Definition::finalize_() {
|
||||||
|
for (auto*& param : mSInstParams) {
|
||||||
|
if (param) {
|
||||||
|
delete param;
|
||||||
|
param = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSInstParams.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::AIActionDef::finalize_() {
|
||||||
|
Definition::finalize_();
|
||||||
|
mChildIndices.freeBuffer();
|
||||||
|
mBehaviorIndices.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::finalizeAIActions(sead::Buffer<AIActionDef>& defs) {
|
||||||
|
for (auto& def : defs)
|
||||||
|
def.finalize_();
|
||||||
|
defs.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::finalizeBehaviors() {
|
||||||
|
for (auto& def : mBehaviors)
|
||||||
|
def.finalize_();
|
||||||
|
mBehaviors.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIProgram::finalizeQueries() {
|
||||||
|
for (auto& def : mQueries)
|
||||||
|
def.finalize_();
|
||||||
|
mQueries.freeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
const agl::utl::ParameterBase* AIProgram::Definition::findSInstParam(u32 name_hash) const {
|
||||||
|
for (const auto* param : mSInstParams) {
|
||||||
|
if (param && param->getNameHash() == name_hash)
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const agl::utl::ParameterBase*
|
||||||
|
AIProgram::Definition::findSInstParam(const sead::SafeString& name) const {
|
||||||
|
return findSInstParam(agl::utl::ParameterBase::calcHash(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::getSInstParam(sead::SafeString* value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name) const {
|
||||||
|
const auto* param = def.findSInstParam(param_name);
|
||||||
|
if (!param || param->getParameterType() != agl::utl::ParameterType::StringRef) {
|
||||||
|
*value = sead::SafeString::cEmptyString;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*value = param->ptrT<char>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::getSInstParam(const s32** value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name) const {
|
||||||
|
static const s32 sDefault{};
|
||||||
|
return getSInstParam_(value, def, param_name, agl::utl::ParameterType::Int, &sDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::getSInstParam(const sead::Vector3f** value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name) const {
|
||||||
|
return getSInstParam_(value, def, param_name, agl::utl::ParameterType::Vec3,
|
||||||
|
&sead::Vector3f::zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::getSInstParam(const bool** value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name) const {
|
||||||
|
static const bool sDefault{};
|
||||||
|
return getSInstParam_(value, def, param_name, agl::utl::ParameterType::Bool, &sDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIProgram::parseDefParams(AIProgram::Definition* def, void* buffer, sead::Heap* heap,
|
||||||
|
const agl::utl::ResParameterList& res, u16* param1, u16* param2) {
|
||||||
|
const auto sinst_obj = agl::utl::getResParameterObj(res, "SInst");
|
||||||
|
const s32 sinst_num_params = sinst_obj.ptr() ? sinst_obj.getNum() : 0;
|
||||||
|
|
||||||
|
AIDef aidef;
|
||||||
|
|
||||||
|
if (&mAIs == buffer) {
|
||||||
|
AIClassDef::instance()->getDef(&aidef, def->mClassName, AIDefInstParamKind::Static,
|
||||||
|
AIDefType::AI);
|
||||||
|
*param1 = aidef.trigger_action;
|
||||||
|
*param2 = aidef.dynamic_param_child;
|
||||||
|
} else if (&mActions == buffer) {
|
||||||
|
AIClassDef::instance()->getDef(&aidef, def->mClassName, AIDefInstParamKind::Static,
|
||||||
|
AIDefType::Action);
|
||||||
|
*param1 = aidef.trigger_action;
|
||||||
|
*param2 = 0;
|
||||||
|
} else if (&mBehaviors == buffer) {
|
||||||
|
AIClassDef::instance()->getDef(&aidef, def->mClassName, AIDefInstParamKind::Static,
|
||||||
|
AIDefType::Behavior);
|
||||||
|
*param1 = aidef.calc_timing;
|
||||||
|
*param2 = aidef.no_stop;
|
||||||
|
} else {
|
||||||
|
AIClassDef::instance()->getDef(&aidef, def->mClassName, AIDefInstParamKind::Static,
|
||||||
|
AIDefType::Query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sinst_num_params != 0) {
|
||||||
|
const auto num_params =
|
||||||
|
aidef.num_params < sinst_num_params ? aidef.num_params : sinst_num_params;
|
||||||
|
|
||||||
|
if (!def->mSInstParams.tryAllocBuffer(sinst_num_params, heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < sinst_num_params; ++i)
|
||||||
|
def->mSInstParams[i] = nullptr;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < num_params; ++i) {
|
||||||
|
const char* name = aidef.param_names[i];
|
||||||
|
switch (aidef.param_types[i]) {
|
||||||
|
case AIDefParamType::String:
|
||||||
|
case AIDefParamType::Tree:
|
||||||
|
if (!def->addSInstParam_<sead::SafeString>(i, name, heap, ""))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case AIDefParamType::UInt:
|
||||||
|
if (!def->addSInstParam_<u32>(i, name, heap, 0))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case AIDefParamType::Int:
|
||||||
|
if (!def->addSInstParam_<s32>(i, name, heap, 0))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case AIDefParamType::Float:
|
||||||
|
if (!def->addSInstParam_<f32>(i, name, heap, 0))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case AIDefParamType::Vec3:
|
||||||
|
if (!def->addSInstParam_<sead::Vector3f>(i, name, heap, sead::Vector3f::zero))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case AIDefParamType::Bool:
|
||||||
|
if (!def->addSInstParam_<bool>(i, name, heap, false))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
def->mSInstParams[i] = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def->mList.addObj(&def->mSInstObj, "SInst");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool AIProgram::Definition::addSInstParam_(s32 idx, const char* name, sead::Heap* heap,
|
||||||
|
const T& value) {
|
||||||
|
mSInstParams[idx] = new (heap) agl::utl::Parameter<T>;
|
||||||
|
|
||||||
|
auto* param = static_cast<agl::utl::Parameter<T>*>(mSInstParams[idx]);
|
||||||
|
if (!param)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
param->initializeParameter(value, name, name, &mSInstObj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ksys::res
|
|
@ -0,0 +1,138 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <agl/Utils/aglParameter.h>
|
||||||
|
#include <agl/Utils/aglParameterList.h>
|
||||||
|
#include <agl/Utils/aglParameterObj.h>
|
||||||
|
#include <container/seadBuffer.h>
|
||||||
|
#include <math/seadVector.h>
|
||||||
|
#include "KingSystem/Resource/resResource.h"
|
||||||
|
#include "KingSystem/Utils/ParamIO.h"
|
||||||
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
|
namespace ksys::res {
|
||||||
|
|
||||||
|
class AIProgram : public ParamIO, public Resource {
|
||||||
|
SEAD_RTTI_OVERRIDE(AIProgram, Resource)
|
||||||
|
public:
|
||||||
|
enum class AIActionType {
|
||||||
|
AI = 0,
|
||||||
|
Action = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Definition {
|
||||||
|
const agl::utl::ParameterBase* findSInstParam(u32 name_hash) const;
|
||||||
|
const agl::utl::ParameterBase* findSInstParam(const sead::SafeString& name) const;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool addSInstParam_(s32 idx, const char* name, sead::Heap* heap, const T& value);
|
||||||
|
|
||||||
|
void finalize_();
|
||||||
|
|
||||||
|
agl::utl::ParameterList mList;
|
||||||
|
const char* mClassName;
|
||||||
|
const char* mName;
|
||||||
|
sead::Buffer<agl::utl::ParameterBase*> mSInstParams;
|
||||||
|
agl::utl::ParameterObj mSInstObj;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(Definition, 0x98);
|
||||||
|
|
||||||
|
struct AIActionDef : Definition {
|
||||||
|
void finalize_();
|
||||||
|
|
||||||
|
const char* mGroupName;
|
||||||
|
sead::Buffer<u16> mChildIndices;
|
||||||
|
sead::Buffer<u8> mBehaviorIndices;
|
||||||
|
u16 mTriggerAction;
|
||||||
|
u16 mDynamicParamChild;
|
||||||
|
u16 _c4;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(AIActionDef, 0xc8);
|
||||||
|
|
||||||
|
struct BehaviorDef : Definition {
|
||||||
|
u16 mCalcTiming;
|
||||||
|
u16 mNoStop;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(BehaviorDef, 0xa0);
|
||||||
|
|
||||||
|
struct QueryDef : Definition {};
|
||||||
|
KSYS_CHECK_SIZE_NX150(QueryDef, 0x98);
|
||||||
|
|
||||||
|
AIProgram();
|
||||||
|
~AIProgram() override;
|
||||||
|
|
||||||
|
const sead::Buffer<AIActionDef>& getActionsOrAIs(AIActionType type) const;
|
||||||
|
const sead::Buffer<BehaviorDef>& getBehaviors() const { return mBehaviors; }
|
||||||
|
const sead::Buffer<QueryDef>& getQueries() const { return mQueries; }
|
||||||
|
|
||||||
|
bool getSInstParam(sead::SafeString* value, const Definition& def,
|
||||||
|
const sead::SafeString& param_name) const;
|
||||||
|
bool getSInstParam(const f32** value, const Definition& def,
|
||||||
|
const sead::SafeString& param_name) const;
|
||||||
|
bool getSInstParam(const s32** value, const Definition& def,
|
||||||
|
const sead::SafeString& param_name) const;
|
||||||
|
bool getSInstParam(const sead::Vector3f** value, const Definition& def,
|
||||||
|
const sead::SafeString& param_name) const;
|
||||||
|
bool getSInstParam(const bool** value, const Definition& def,
|
||||||
|
const sead::SafeString& param_name) const;
|
||||||
|
|
||||||
|
void doCreate_(u8* buffer, u32 bufferSize, sead::Heap* heap) override;
|
||||||
|
bool needsParse() const override { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool parse_(u8* data, size_t size, sead::Heap* parent_heap) override;
|
||||||
|
bool parseAIActions(sead::Buffer<AIActionDef>& defs, sead::Heap* heap,
|
||||||
|
agl::utl::ParameterList& target_list,
|
||||||
|
const agl::utl::ResParameterList& root, const char* type_name);
|
||||||
|
bool parseBehaviors(sead::Heap* heap, const agl::utl::ResParameterList& root);
|
||||||
|
bool parseQueries(sead::Heap* heap, const agl::utl::ResParameterList& root);
|
||||||
|
bool parseDefParams(Definition* def, void* buffer, sead::Heap* heap,
|
||||||
|
const agl::utl::ResParameterList& res, u16* param1, u16* param2);
|
||||||
|
|
||||||
|
void finalize_() override;
|
||||||
|
void finalizeAIActions(sead::Buffer<AIActionDef>& defs);
|
||||||
|
void finalizeBehaviors();
|
||||||
|
void finalizeQueries();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool getSInstParam_(const T** value, const Definition& def, const sead::SafeString& param_name,
|
||||||
|
agl::utl::ParameterType param_type, const T* default_value) const;
|
||||||
|
|
||||||
|
sead::Heap* mHeap = nullptr;
|
||||||
|
sead::SafeString mStr;
|
||||||
|
|
||||||
|
sead::Buffer<AIActionDef> mAIs;
|
||||||
|
sead::Buffer<AIActionDef> mActions;
|
||||||
|
sead::Buffer<BehaviorDef> mBehaviors;
|
||||||
|
sead::Buffer<QueryDef> mQueries;
|
||||||
|
|
||||||
|
agl::utl::ParameterList mParamListAI;
|
||||||
|
agl::utl::ParameterList mParamListAction;
|
||||||
|
agl::utl::ParameterList mParamListBehavior;
|
||||||
|
agl::utl::ParameterList mParamListQuery;
|
||||||
|
|
||||||
|
sead::Buffer<u16> mDemoAIActionIndices;
|
||||||
|
sead::Buffer<u8> mDemoBehaviorIndices;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(AIProgram, 0x448);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool AIProgram::getSInstParam_(const T** value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name,
|
||||||
|
agl::utl::ParameterType param_type,
|
||||||
|
const T* default_value) const {
|
||||||
|
const auto* param = def.findSInstParam(param_name);
|
||||||
|
if (!param || param->getParameterType() != param_type) {
|
||||||
|
*value = default_value;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*value = param->ptrT<T>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool AIProgram::getSInstParam(const f32** value, const AIProgram::Definition& def,
|
||||||
|
const sead::SafeString& param_name) const {
|
||||||
|
static const f32 sDefault{};
|
||||||
|
return getSInstParam_(value, def, param_name, agl::utl::ParameterType::F32, &sDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ksys::res
|
Loading…
Reference in New Issue