summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/Awareness/actAwareness.h
blob: 5b13c5ef6553bf7a342cc40dc2593059c75bc8a7 (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
147
148
149
150
151
152
153
154
155
156
#pragma once

#include <container/seadBuffer.h>
#include <container/seadOrderedSet.h>
#include <container/seadSafeArray.h>
#include <heap/seadDisposer.h>
#include <prim/seadEnum.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/ActorSystem/actBaseProcLink.h"
#include "KingSystem/Utils/Types.h"

namespace ksys::act {

class AwarenessInstance;

class Awareness {
    SEAD_SINGLETON_DISPOSER(Awareness)

    Awareness() = default;
    virtual ~Awareness();

public:
    struct InitArg {
        int num_instances_max;
        // TODO: rename
        int num_links_max;
        int num_links2_max;
    };

    bool init(const InitArg& arg, sead::Heap* heap);
    bool initBeforeStageGen();
    void setPaused(bool paused);
    void setEventActive(bool active);
    void calc();

    static u32 calcHash(const sead::SafeString& key);

private:
    friend class AwarenessInstance;

    SEAD_ENUM(Flag, _0, Paused, _2, _3, EventActive, _5, _6)

    // FIXME: rename
    struct Unk1 {
        virtual ~Unk1() { finalize(); }
        void finalize();
        void calc();

        void* _8{};
        void* _10{};
    };

    struct TerrorFilter {
        bool operator<(const TerrorFilter& rhs) const { return target < rhs.target; }

        u32 flags;
        u32 target;
    };

    struct SensorFilter {
        bool operator<(const SensorFilter& rhs) const { return target < rhs.target; }

        u32 flags;
        u32 target;
    };

    struct SensorFilterBuffer {
        bool operator<(const SensorFilterBuffer& rhs) const { return target < rhs.target; }

        union Params {
            struct {
                int system;
                int sense;
                int sight;
                int worry;
                int hearing;
            };
            sead::SafeArray<int, 5> raw;
        };
        Params params;
        u32 target;
    };

    struct InstanceRef {
        AwarenessInstance* instance{};
    };

    struct Instances {
        ~Instances() { instances.freeBuffer(); }
        bool registerInstance(AwarenessInstance* instance);
        void deregisterInstance(AwarenessInstance* instance);
        void calc();
        void calcForEvent(bool check_334);
        AwarenessInstance*& get(int i) { return instances[i].instance; }
        AwarenessInstance*& operator[](int i) { return get(i); }

        sead::Buffer<InstanceRef> instances;
        int count = 0;
        int ticks = 0;
        sead::CriticalSection critical_section;
    };

    // FIXME: rename
    struct Link {
        BaseProcLink link;
        // TODO: physics body?
        void* _10{};
    };

    // FIXME: rename
    struct Link2 {
        Link2() { _10 = 0; }
        BaseProcLink link;
        u8 _10{};
        u32 _14{};
        void* _18{};
    };

    // FIXME: rename
    struct Links {
        void calc();

        sead::Buffer<Link> buffer;
        sead::Atomic<int> count;
    };

    // FIXME: rename
    struct Links2 {
        void calc();

        sead::Buffer<Link2> buffer;
        sead::Atomic<int> count;
    };

    void finalize();
    bool loadSystemData();

    bool checkFlag(Flag flag) const { return (1u << flag) & mFlags.getDirect(); }
    void setFlag(Flag flag) { mFlags.setBit(flag); }
    void resetFlag(Flag flag) { mFlags.resetBit(flag); }

    Instances mInstances;
    Links mLinks;
    Links2 mLinks2;
    Unk1 mUnk;
    sead::OrderedSet<TerrorFilter> mTerrorFilters;
    sead::OrderedSet<SensorFilter> mSensorFilters;
    sead::OrderedSet<SensorFilterBuffer> mSensorFilterBuffers;
    sead::BitFlag8 mFlags;
    sead::Heap* mHeap{};
};
KSYS_CHECK_SIZE_NX150(Awareness, 0x138);

}  // namespace ksys::act