1#pragma once
2
3#include <basis/seadTypes.h>
4#include <heap/seadHeap.h>
5#include <prim/seadTypedBitFlag.h>
6#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
7#include "KingSystem/ActorSystem/actDebug.h"
8#include "KingSystem/GameData/gdtFlagHandle.h"
9#include "KingSystem/Map/mapDebug.h"
10#include "KingSystem/Map/mapMubinIter.h"
11#include "KingSystem/Map/mapPlacementActors.h"
12#include "KingSystem/Map/mapPlacementMgr.h"
13#include "KingSystem/Utils/Types.h"
14
15namespace ksys::act {
16class Actor;
17class BaseProc;
18class BaseProcInitializer;
19class BaseProcCreateTask;
20} // namespace ksys::act
21
22namespace ksys::map {
23
24class ObjectLinkData;
25struct ObjectLink;
26struct ObjectLinkArray;
27class LinkTag;
28
29class Object {
30public:
31 // TODO: rename
32 enum class Flag0 : u32 {
33 _2 = 0x2,
34 _4 = 0x4,
35 _8 = 0x8,
36 _10 = 0x10,
37 _20 = 0x20,
38 _40 = 0x40,
39 _80 = 0x80,
40 _100 = 0x100,
41 ActorCreated = 0x200,
42 _400 = 0x400,
43 _800 = 0x800,
44 _2000 = 0x2000,
45 _4000 = 0x4000,
46 _8000 = 0x8000,
47 _10000 = 0x10000,
48 _40000 = 0x40000,
49 _80000 = 0x80000,
50 _100000 = 0x100000,
51 StaticCompoundInstanceEnabled = 0x200000,
52 _400000 = 0x400000,
53 _2000000 = 0x2000000,
54 _4000000 = 0x4000000,
55 _40000000 = 0x40000000,
56 _80000000 = 0x80000000,
57 ResetOnUnlinkFailed = _100 | _2000,
58 ResetOnUnlink = _2 | _4 | _80 | _100 | ActorCreated | _400 | _2000,
59 _400400 = _400 | _400000,
60 _500400 = _400400 | _100000,
61 _80002106 = _2 | _4 | _100 | _2000 | _80000000,
62 ResetOnFreed = ResetOnUnlink | _500400 | _20 | _40 | _4000 | _2000000 | _4000000 |
63 _40000000 | _80000000,
64 };
65
66 enum class Flag {
67 IsLinkTag = 0x1,
68 IncrementSave = 0x2,
69 IsLinkTagNAndOrNOr = 0x4,
70 _8 = 0x8,
71 ShapeCapsuleOrCylinder = 0x10,
72 SheikSensorTargetDeadOrAlive = 0x20,
73 UnderGodForest = 0x40,
74 UnderGodForestOff = 0x80,
75 CreateNotRain = 0x100,
76 ActorCreated = 0x200,
77 HasTraversePos = 0x400,
78 HasUniqueName = 0x800,
79 IsCreateSharpWeapon = 0x1000,
80 // TODO: rename this. This name is too long...
81 IsTurnActorBowChargeAndHasBasicSigLink = 0x8000,
82 };
83
84 enum class HardModeFlag {
85 ActorCreated = 0x1,
86 /// This actor only spawns in master mode (hard mode).
87 IsHardModeActor = 0x2,
88 /// This actor only spawns during the One-Hit Obliterator (Ichigeki/一撃) challenge.
89 IsOneHitChallengeActor = 0x4,
90 /// This actor does not rank up in master mode.
91 DisableRankup = 0x8,
92 };
93
94 Object();
95 ~Object();
96
97 void initData(MubinIter* iter, u8 idx, u32 actor_data_idx, ActorData* data);
98 void free();
99
100 void registerBaseProc(act::BaseProc* proc);
101 void setBaseProcDirect(act::BaseProc* proc);
102 void onBaseProcCreated(act::BaseProc* proc);
103 act::BaseProc* tryGetProc(bool force);
104 void unlinkProc(bool force);
105
106 bool getActorWithAccessor(act::ActorLinkConstDataAccess& accessor);
107 act::Actor* tryGetActor(bool force);
108 act::Actor* getActor();
109
110 LinkTag* tryGetLinkTag(bool force);
111
112 bool isEnemyOrNpcOrActiveOrMapPassive() const;
113 bool isFlags8Cleared() const;
114 bool isNpcOrActiveOrMapPassiveOrFlag1() const;
115 bool isMapPassive(const PlacementActors* pa) const;
116 bool isEnemyOrNpc(const PlacementActors* pa) const;
117 bool isRevivalGameDataFlagOn() const;
118 bool checkActorDataFlag(const PlacementActors* pa, ActorData::Flag flag) const;
119 bool checkTraverseFlags() const;
120 bool checkRevivalFlag(ActorData::Flag bit) const;
121
122 void setRevivalFlagValueIf(ActorData::Flag bit, bool value);
123 void setRevivalFlagValue(bool value);
124 void setFieldATrue();
125
126 sead::Vector3f getScale() const;
127 sead::Vector3f getRotate() const;
128 void setTranslate(const sead::Vector3f& translate);
129
130 f32 getDispDistanceMultiplier() const {
131 f32 mult = 1.0;
132
133 if (act::ActorDebug::instance() != nullptr)
134 mult = act::ActorDebug::instance()->mDispDistanceMultiplier;
135
136 return mult;
137 }
138
139 void getTraversePosAndLoadDistance(sead::Vector3f* traverse_pos, f32* load_dist) const;
140 f32 getDispDistance(const PlacementActors* pa, bool get_diameter, bool ignore_radius) const;
141 f32 getDispDistance(const ActorData* data, bool get_diameter, u32 unused,
142 bool ignore_radius) const;
143 f32 getDispDistance(bool get_diameter = false, bool ignore_radius = false) const;
144 f32 getTraverseDist(const ActorData* data, bool get_diameter, u32 unused,
145 bool ignore_radius) const;
146 f32 getTraverseDistForLOD() const;
147
148 const char* getUnitConfigName() const;
149 const char* getUnitConfigNameFromByaml() const;
150 void getUniqueName(const char** out) const;
151
152 Object* findPlacementLODLinkObject(const PlacementActors* unused) const;
153 Object* findPlacementLODLinkObject() const;
154
155 const char* getHashIdStringDebug() const;
156 const char* getHashIdStringDebug_0() const;
157
158 bool x_18() const;
159 bool x_20() const;
160 s32 x_22() const;
161
162 bool hasGenGroup() const;
163 void spawnGenGroupActorsIfNeeded(Object* obj);
164
165 void* getRails() const;
166 void* getRails_0() const;
167 bool setupTargetLinks(Object* src, ObjectLink* link, sead::Heap* heap);
168 bool allocLinkData(sead::Heap* heap);
169 void incrementLinkNum();
170 void decrementLinkNum();
171 bool checkCreateOrDeleteLinkObjRevival() const;
172
173 bool shouldSkipSpawn() const;
174 bool shouldSkipSpawn_(bool x) const;
175
176 // TODO:
177 void initRevivalGameDataFlagAndMiscFlags(ActorData* data, bool zero);
178 f32 getLoadDistance(bool get_diameter) const;
179 Object* findSrcLODLinkObject() const;
180
181 const auto& getFlags0() const { return mFlags0; }
182 void setFlags0(Flag0 bit) { mFlags0.set(bit); }
183 void resetFlags0(Flag0 bit) { mFlags0.reset(bit); }
184 const auto& getFlags() const { return mFlags; }
185 const auto& getActorFlags8() const { return mActorFlags8; }
186 const auto& getHardModeFlags() const { return mHardModeFlags; }
187
188 auto getActorDataIdx() const { return mActorDataIdx; }
189 auto getIdx() const { return mIdx; }
190 auto getId() const { return mId; }
191 auto getStaticCompoundActorId() const { return mStaticCompoundActorId; }
192 void setStaticCompoundActorId(s16 id) { mStaticCompoundActorId = id; }
193
194 const ActorData& getActorData() const {
195 return PlacementMgr::instance()->mPlacementActors->mActorData[mActorDataIdx];
196 }
197
198 u8 getNumLinksPointingToMe() const { return mNumLinksPointingToMe; }
199
200 const MubinIter& getMubinIter() const { return mMubinIter; }
201 act::BaseProc* getProc() const { return mProc; }
202 ObjectLinkData* getLinkData() const { return mLinkData; }
203
204 gdt::FlagHandle getRevivalGameDataFlagHash() const { return mRevivalGameDataFlagHash; }
205 u32 getHashId() const { return mHashId; }
206
207 const sead::Vector3f& getTranslate() const { return mTranslate; }
208
209 auto getTraverseDistInt() const { return mTraverseDistInt; }
210
211private:
212 sead::TypedBitFlag<Flag0, sead::Atomic<u32>> mFlags0;
213 u16 mActorDataIdx = 0xffff;
214 sead::TypedBitFlag<Flag, u16> mFlags;
215 u8 mIdx = 0;
216 u8 mNumLinksPointingToMe = 0;
217 sead::TypedBitFlag<ActorFlag8, u8> mActorFlags8;
218 u8 _b = 0xff;
219 u16 mId = 0;
220 s16 mStaticCompoundActorId = -1;
221 void* _10 = nullptr;
222 void* _18 = nullptr;
223 void* _20 = nullptr;
224 MubinIter mMubinIter;
225 act::BaseProc* mProc = nullptr;
226 ObjectLinkData* mLinkData = nullptr;
227 gdt::FlagHandle mRevivalGameDataFlagHash = gdt::InvalidHandle;
228 void* _50 = nullptr;
229 u32 mHashId = 0;
230 sead::Vector3f mTranslate;
231 f32 mTraverseDist = 0.0;
232 u16 mTraverseDistInt = 0;
233 sead::TypedBitFlag<HardModeFlag, u8> mHardModeFlags;
234};
235KSYS_CHECK_SIZE_NX150(Object, 0x70);
236
237} // namespace ksys::map
238