summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/actAiClassDef.h
blob: 1b74f4f46a63a751365b05b3d874166c20f48aa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#pragma once

#include <basis/seadTypes.h>
#include <container/seadBuffer.h>
#include <container/seadSafeArray.h>
#include <heap/seadDisposer.h>
#include <math/seadVector.h>
#include <prim/seadSafeString.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"

namespace ksys {

namespace act {
class BaseProcLink;
}

enum class AIDefType {
    AI = 0,
    Action = 1,
    Behavior = 2,
    Query = 3,
};

constexpr s32 NumAIDefTypes = 4;

enum class AIDefInstParamKind {
    Static = 0,
    Dynamic = 1,
    MapUnit = 2,
    AITree = 3,
};

constexpr bool paramKindHasValue(AIDefInstParamKind kind) {
    return kind == AIDefInstParamKind::MapUnit || kind == AIDefInstParamKind::AITree;
}

constexpr s32 NumAIDefInstParamKinds = 4;

enum class AIDefParamType;

enum class CalcTiming {
    AIAfter = 0,
    ModelAfter = 1,
    ChangeDeleteState = 2,
};

struct AIDef {
    union Value {
        Value() {}
        std::array<u8, 16> raw;
        const char* str;
        s32 i;
        f32 f;
        sead::Vector3f vec3;
        bool b;
        void* tree;
        void* variable_ptr;
        u32 u;
        act::BaseProcLink* proc_link;
    };

    static constexpr size_t NumParametersMax = 64;

    const char* param_names[NumParametersMax];
    sead::SizedEnum<AIDefParamType, u8> param_types[NumParametersMax];
    s32 num_params;
    CalcTiming calc_timing;
    bool no_stop;
    bool trigger_action;
    bool dynamic_param_child;
    u8 _24b;
    Value param_values[NumParametersMax];
};
KSYS_CHECK_SIZE_NX150(AIDef, 0x650);

struct AIDefSet {
    static constexpr size_t NumChildrenMax = 256;

    const char* children[NumChildrenMax];
    s32 num_children;
    AIDef dynamic_params;
    AIDef map_unit_params;
    AIDef ai_tree_params;
};
KSYS_CHECK_SIZE_NX150(AIDefSet, 0x1af8);

class AIClassDef {
    SEAD_SINGLETON_DISPOSER(AIClassDef)
    AIClassDef() = default;
    ~AIClassDef();

public:
    void init(const sead::SafeString& aidef_file_name, sead::Heap* heap);

    void getDef(const sead::SafeString& class_name, AIDefSet* set, AIDefType class_type) const;
    void getDef(AIDef* def, const sead::SafeString& class_name, AIDefInstParamKind param_kind,
                AIDefType class_type) const;

    bool isSystemQuery(const sead::SafeString& query) const;

private:
    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;
        sead::SafeArray<s32, NumAIDefInstParamKinds> inst_params_key_idx;
        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);
    }

    s32 getRawDefIdx(const sead::SafeString& def_name, AIDefType type) const;
    const sead::Buffer<Data::Def>& getRawDefs(AIDefType type) const {
        return mData->defs[s32(type)];
    }

    void doGetDef(AIDef* def, const al::ByamlIter& iter, AIDefInstParamKind param_kind,
                  AIDefType class_type, s32 key_idx) const;

    Data* mData = nullptr;
    res::Handle mResHandle;
};
KSYS_CHECK_SIZE_NX150(AIClassDef, 0x78);

}  // namespace ksys