1#pragma once
2
3#include <container/seadBuffer.h>
4#include <container/seadListImpl.h>
5#include <math/seadBoundBox.h>
6#include <math/seadMatrix.h>
7#include <math/seadVector.h>
8#include <prim/seadSafeString.h>
9#include <prim/seadTypedBitFlag.h>
10#include <thread/seadAtomic.h>
11#include <xlink2/xlink2.h>
12#include "KingSystem/ActorSystem/actActorEditorNode.h"
13#include "KingSystem/ActorSystem/actBaseProc.h"
14#include "KingSystem/ActorSystem/actBaseProcJobHandler.h"
15#include "KingSystem/ActorSystem/actBaseProcLink.h"
16#include "KingSystem/ActorSystem/actPhysicsConstraints.h"
17#include "KingSystem/ActorSystem/actPhysicsUserTag.h"
18#include "KingSystem/Map/mapMubinIter.h"
19#include "KingSystem/Utils/AtomicLongBitFlag.h"
20#include "KingSystem/Utils/Thread/ActorMessageTransceiver.h"
21
22namespace gsys {
23class Model;
24} // namespace gsys
25
26namespace uking::dmg {
27class DamageManagerBase;
28} // namespace uking::dmg
29
30namespace ksys {
31
32namespace as {
33class ASList;
34} // namespace as
35
36namespace map {
37class Object;
38} // namespace map
39
40namespace mii {
41class HylianInfo;
42class UMii;
43} // namespace mii
44
45namespace phys {
46class StaticCompoundRigidBodyGroup;
47class InstanceSet;
48class Reaction;
49class RigidBody;
50class CharacterController;
51} // namespace phys
52
53namespace res {
54class Handle;
55} // namespace res
56
57namespace xlink {
58class XLink;
59} // namespace xlink
60
61namespace act {
62
63namespace ai {
64class RootAi;
65}
66
67class LifeRecoverInfo;
68class Actor;
69class ActorCreator;
70class ActorParam;
71class Attention;
72class Awareness;
73class BaseProcLink;
74class BoneControl;
75class Chemical;
76class ImpulseBaseProcLink;
77class ModelBindInfo;
78class Schedule;
79
80// FIXME: move this to a separate file and rename
81class UMiiModelLink {
82public:
83 explicit UMiiModelLink(Actor* actor) : mActor(actor) {}
84
85 virtual void m0() {}
86 virtual void m1() {}
87 virtual void m2() {}
88 virtual void m3() {}
89
90private:
91 Actor* mActor = nullptr;
92};
93KSYS_CHECK_SIZE_NX150(UMiiModelLink, 0x10);
94
95struct ActorUniqueName {
96 sead::BufferedSafeString* unique_name;
97 sead::FixedSafeString<16> change_attention_type;
98};
99KSYS_CHECK_SIZE_NX150(ActorUniqueName, 0x30);
100
101class Actor : public BaseProc, public ActorMessageTransceiver::IHandler {
102public:
103 enum class StasisFlag {
104 _1 = 1,
105 _2 = 2,
106 _4 = 4,
107 };
108
109 enum class ActorFlag {
110 _18 = 0x18,
111 _25 = 0x25,
112 _29 = 0x29,
113 _2b = 0x2b,
114 _2e = 0x2e,
115 _39 = 0x39,
116 };
117
118 enum class ActorFlag2 {
119 InstEvent = 0x8,
120 _20 = 0x20,
121 NoDistanceCheck = 0x80,
122 Alive = 0x4000000,
123 };
124
125 enum class DeleteType {
126 _1 = 1,
127 _2 = 2,
128 _3 = 3,
129 };
130
131 explicit Actor(const CreateArg& arg);
132 ~Actor() override;
133
134 SEAD_RTTI_OVERRIDE(Actor, BaseProc)
135
136public:
137 const sead::SafeString& getProfile() const;
138 const char* getUniqueName() const;
139
140 ai::RootAi* getRootAi() const { return mRootAi; }
141 const ActorParam* getParam() const { return mActorParam; }
142 map::Object* getMapObject() const { return mMapObject; }
143 const map::MubinIter& getMapObjIter() const { return mMapObjIter; }
144 as::ASList* getASList() const { return mASList; }
145
146 const sead::Matrix34f& getMtx() const { return mMtx; }
147 const sead::Vector3f& getVelocity() const { return mVelocity; }
148 const sead::Vector3f& getAngVelocity() const { return mAngVelocity; }
149 const sead::Vector3f& getScale() const { return mScale; }
150 phys::RigidBody* getMainBody() const { return mMainBody; }
151 phys::RigidBody* getTgtBody() const { return mTgtBody; }
152
153 const MesTransceiverId* getMesTransceiverId() const { return mMsgTransceiver.getId(); }
154 void sendMessage(const MesTransceiverId& dest, const MessageType& type, void* user_data,
155 bool ack);
156
157 f32 getDeleteDistance() const {
158 return sead::Mathf::sqrt(sead::Mathf::clampMin(mDeleteDistanceSq, 0.0f));
159 }
160
161 void setDeleteDistance(f32 distance) { mDeleteDistanceSq = sead::Mathf::square(distance); }
162
163 phys::CharacterController* getCharacterController();
164
165 void clearFlag(ActorFlag flag);
166 bool checkFlag(ActorFlag flag) const;
167 void setFlag(ActorFlag flag);
168 void setFlag(ActorFlag flag, bool on);
169 bool deleteEx(DeleteType type, DeleteReason reason, bool* ok = nullptr);
170
171 void setProperties(int x, const sead::Matrix34f& mtx, const sead::Vector3f& vel,
172 const sead::Vector3f& ang_vel, const sead::Vector3f& scale,
173 bool is_life_infinite, int i, int life) const;
174
175 // FIXME: figure out return types, parameters and names
176 virtual s32 getMaxLife();
177 virtual void m31();
178 virtual void m32();
179 virtual void m33();
180 virtual void m34();
181 virtual void m35();
182 virtual void m36();
183 virtual void getGuardableAngle();
184 virtual void m38();
185 virtual void m39();
186 virtual void m40();
187 virtual void m41();
188 virtual void m42();
189 virtual void m43();
190 virtual void m44();
191 virtual void m45();
192 virtual void m46();
193 virtual void m47();
194 virtual void m48();
195 virtual void m49();
196 virtual void m50();
197 virtual void m51();
198 virtual void m52();
199 virtual void m53();
200 virtual void killWithDropsAndEffects();
201 virtual void m55();
202 virtual void m56();
203 virtual void m57();
204 virtual void onPreFadeOutDelete();
205 virtual void onFadeOutSleep();
206 virtual void m60();
207 virtual void m61();
208 virtual bool shouldUnload();
209 virtual void m63();
210 virtual void initMaybe();
211 virtual void updateLodStuff();
212 virtual void m66();
213 virtual void m67();
214 virtual void m68();
215 virtual void calcMaybe();
216 virtual void m70();
217 virtual void updatePositionMaybe();
218 virtual void m72();
219 virtual void m73();
220 virtual void m74();
221 virtual void m75();
222 virtual void m76();
223 virtual void m77();
224 virtual void afterModelMatrixUpdate();
225 virtual void m79();
226 virtual bool m80();
227 virtual void m81();
228 virtual int getCalcTiming();
229 virtual void m83();
230 virtual void updateMtxFromPhysics();
231 virtual void setMtx();
232 virtual void m86();
233 virtual s32* getLife();
234 virtual void m88();
235 virtual void m89();
236 virtual void m90();
237 virtual void m91();
238 virtual void m92();
239 virtual void m93(int a1, float a2);
240 virtual void m94();
241 virtual void m95();
242 virtual void m96();
243 virtual Chemical* getChemicalStuff();
244 virtual void getWeapons();
245 virtual void getArmors();
246 virtual void m100();
247 virtual void m101();
248 virtual int getExtraHeapSize();
249 virtual void m103();
250 int handleMessage(const Message& message) override;
251 void handleAck(const MessageAck& ack) override;
252 virtual void m106();
253 virtual void m107();
254 virtual void m108();
255 virtual void m109();
256 virtual void m110();
257 virtual void m111();
258 virtual void m112();
259 virtual void m113();
260 virtual void m114();
261 virtual void m115();
262 virtual void m116();
263 virtual void m117();
264 virtual void m118();
265 virtual void m119();
266 virtual void m120();
267 virtual void m121();
268 virtual void m122();
269 virtual void m123();
270 virtual void onPlacementObjReset();
271 virtual void getAtk();
272 virtual void m126();
273 virtual uking::dmg::DamageManagerBase* getDamageMgr();
274 virtual void m128();
275 virtual void m129();
276 virtual void getPlayerRideInfo();
277 virtual void getHorseOptionsMaybe();
278 virtual void m132();
279 virtual void getMotorcyclePriorityStuffMaybe();
280 virtual void getDropData();
281 virtual void m135();
282 virtual LifeRecoverInfo* getLifeRecoverInfo();
283 virtual void m137();
284 virtual void m138();
285 virtual void m139();
286 virtual void m140();
287 virtual void m141();
288 virtual void m142();
289 virtual void m143();
290 virtual void m144();
291 virtual void m145();
292 virtual void m146();
293 virtual void m147();
294
295 sead::Atomic<bool>& get68f() { return _68f; }
296 float get6f0() const { return _6f0; }
297
298 void emitBasicSigOn();
299 void emitBasicSigOff();
300 bool checkBasicSig() const;
301
302 void nullsub_4649(); // Some kind of logging which has been excluded from the build?
303
304 sead::TypedBitFlag<ActorFlag2>& getActorFlags2() { return mActorFlags2; }
305 const sead::TypedBitFlag<ActorFlag2>& getActorFlags2() const { return mActorFlags2; }
306
307 void onAiEnter(const char* name, const char* context);
308
309 static constexpr size_t getCreatorListNodeOffset() {
310 return offsetof(Actor, mCreatorActorListNode);
311 }
312
313protected:
314 friend class ActorCreator;
315
316 struct Unk1 {
317 Actor* actor;
318 u32 _4;
319 };
320
321 struct Unk2 {
322 s16 _0 = -1;
323 s16 _2 = -1;
324 };
325
326 // FIXME: rename
327 void job0_1();
328 void job0_2();
329 void job1_1();
330 void job1_2();
331 void job2_1();
332 void job2_2();
333 void job4();
334
335 /* 0x190 */ sead::Atomic<phys::RigidBody*> mMainBody = nullptr;
336 /* 0x198 */ sead::Atomic<phys::RigidBody*> mTgtBody = nullptr;
337 /* 0x1a0 */ void* _1a0 = nullptr;
338 /* 0x1a8 */ void* _1a8 = nullptr;
339 /* 0x1b0 */ Unk1 mUnk1;
340 /* 0x1c0 */ u32 _1c0 = 3;
341
342 /* 0x1c8 */ BaseProcJobHandlerDualT<Actor> mJob0{this, &Actor::job0_1, &Actor::job0_2};
343 /* 0x238 */ BaseProcJobHandlerDualT<Actor> mJob1{this, &Actor::job1_1, &Actor::job1_2};
344 /* 0x2a8 */ BaseProcJobHandlerDualT<Actor> mJob2{this, &Actor::job2_1, &Actor::job2_2};
345 /* 0x318 */ BaseProcJobHandlerT<Actor> mJob4{this, &Actor::job4};
346
347 /* 0x368 */ sead::ListNode mActiveActorListNode;
348 /* 0x378 */ sead::ListNode mActorsThatLostPlacementObjListNode;
349 /* 0x388 */ sead::ListNode mVillagerListNode;
350
351 /* 0x398 */ sead::Matrix34f mMtx = sead::Matrix34f::ident;
352 /* 0x3c8 */ sead::Matrix34f* mPhysicsMtx = nullptr;
353 /* 0x3d0 */ sead::Matrix34f mHomeMtx = sead::Matrix34f::ident;
354 /* 0x400 */ sead::Vector3f mVelocity{0, 0, 0};
355 /* 0x40c */ sead::Vector3f mAngVelocity{0, 0, 0};
356 /* 0x418 */ sead::Vector3f mScale{1, 1, 1};
357 /* 0x424 */ float mDispDistanceSq;
358 /* 0x428 */ float mDeleteDistanceSq = -1.0;
359 /* 0x42c */ float mLoadDistance = -1.0;
360 /* 0x430 */ sead::Vector3f mPreviousPos{0, 0, 0};
361 /* 0x43c */ sead::Vector3f mPreviousPos2{0, 0, 0};
362 /* 0x448 */ sead::Vector3f _448{0, 0, 0};
363 /* 0x454 */ sead::Vector3f _454{0, 0, 0};
364 /* 0x460 */ sead::Vector3f _460{0, 0, 0};
365 /* 0x46c */ sead::Vector3f _46c{0, 0, 0};
366 /* 0x478 */ sead::Vector3f _478;
367 /* 0x484 */ sead::Vector3f mPreviousPos3{0, 0, 0};
368 /* 0x490 */ float _490 = 0.0;
369 /* 0x494 */ float _494 = 0.0;
370 /* 0x498 */ Unk2 _498;
371 /* 0x49c */ Unk2 _49c;
372 /* 0x4a0 */ s16 _4a0 = -1;
373 /* 0x4a2 */ s16 _4a2 = -1;
374 /* 0x4a4 */ s16 _4a4 = -1;
375 /* 0x4a6 */ s16 _4a6 = -1;
376 /* 0x4a8 */ s16 _4a8 = -1;
377 /* 0x4aa */ s16 _4aa = -1;
378 /* 0x4ac */ s16 _4ac = -1;
379 /* 0x4ae */ s16 _4ae = -1;
380 /* 0x4b0 */ s16 _4b0 = -1;
381 /* 0x4b2 */ s16 _4b2 = -1;
382 /* 0x4b4 */ sead::Vector3f _4b4{0, 0, 0};
383 /* 0x4c0 */ sead::Vector3f mEnterCalcPos{0, 0, 0};
384
385 /* 0x4d0 */ ModelBindInfo* mModelBindInfo = nullptr;
386 /* 0x4d8 */ void* _4d8 = nullptr;
387 /* 0x4e0 */ gsys::Model* mModel = nullptr;
388 /* 0x4e8 */ float _4e8 = 1.0;
389 /* 0x4ec */ float mStartModelOpacity = 0.0;
390 /* 0x4f0 */ float _4f0 = 1.0;
391 /* 0x4f4 */ float _4f4 = 0.0;
392 /* 0x4f8 */ float _4f8 = 0.0;
393 /* 0x4fc */ float _4fc = 0.0;
394 /* 0x500 */ sead::BoundBox3f mAabb{sead::Vector3f::zero, sead::Vector3f::zero};
395
396 /* 0x518 */ sead::TypedBitFlag<ActorFlag2> mActorFlags2{};
397 /* 0x51c */ sead::TypedBitFlag<ActorFlag2> mActorFlags2Prev{};
398 /* 0x520 */ util::AtomicLongBitFlag<64, ActorFlag> mActorFlags{};
399
400 /* 0x528 */ PhysicsUserTag mPhysicsUserTag{this};
401 /* 0x540 */ sead::Atomic<bool> _540 = false;
402
403 /* 0x548 */ void* _548 = nullptr;
404 /* 0x550 */ Awareness* mAwareness = nullptr;
405 /* 0x558 */ ai::RootAi* mRootAi = nullptr;
406 /* 0x560 */ as::ASList* mASList = nullptr;
407 /* 0x568 */ xlink::XLink* mXLink = nullptr;
408 /* 0x570 */ ActorParam* mActorParam = nullptr;
409 /* 0x578 */ phys::InstanceSet* mPhysics = nullptr;
410 /* 0x580 */ PhysicsConstraints mConstraints;
411 /* 0x598 */ void* _598 = nullptr;
412 /* 0x5a0 */ BoneControl* mBoneControl = nullptr;
413 /* 0x5a8 */ phys::StaticCompoundRigidBodyGroup* mFieldBodyGroup = nullptr;
414 /* 0x5b0 */ void* _5b0 = nullptr;
415 /* 0x5b8 */ sead::Heap* mDualHeap = nullptr; // TODO: rename
416 /* 0x5c0 */ sead::Heap* mDualHeap2 = nullptr; // TODO: rename
417 /* 0x5c8 */ sead::Heap* mHeap = nullptr; // TODO: rename
418 /* 0x5d0 */ ActorUniqueName* mUniqueName = nullptr;
419 /* 0x5d8 */ Attention* mAttention = nullptr;
420 /* 0x5e0 */ ActorMessageTransceiver mMsgTransceiver{*this, this};
421 /* 0x638 */ Schedule* mSchedule = nullptr;
422
423 /* 0x640 */ u32 mHashId = 0;
424 /* 0x648 */ map::MubinIter mMapObjIter;
425
426 /* 0x658 */ xlink2::Handle _658;
427 /* 0x668 */ xlink2::Handle _668;
428 /* 0x678 */ res::Handle* mModelResMaybe = nullptr;
429 /* 0x680 */ u8 _680 = 0;
430 /* 0x681 */ u8 _681 = 0;
431 /* 0x682 */ u8 _682 = 0;
432 /* 0x683 */ u8 _683 = 0;
433 /* 0x684 */ u8 mSkipJobPushTimer = 0;
434 /* 0x685 */ sead::BitFlag8 mSpecialJobTypesMaskOverride;
435 /* 0x686 */ s8 _686 = -1;
436 /* 0x687 */ sead::Atomic<bool> _687 = false;
437 /* 0x688 */ sead::Atomic<bool> mLifeInfiniteMaybe = false;
438 /* 0x689 */ sead::Atomic<bool> _689 = false;
439 /* 0x68a */ sead::Atomic<bool> _68a = false;
440 /* 0x68b */ sead::Atomic<bool> mNoFadeInCreate = false;
441 /* 0x68c */ sead::Atomic<bool> _68c = false;
442 /* 0x68d */ sead::Atomic<bool> _68d = false;
443 /* 0x68e */ sead::Atomic<bool> _68e = false;
444 /* 0x68f */ sead::Atomic<bool> _68f = false;
445 /* 0x690 */ bool _690 = false;
446 /* 0x691 */ bool _691 = false;
447 /* 0x694 */ sead::Atomic<int> mFadeOutDeleteType = 0;
448 /* 0x698 */ sead::Atomic<u32> mFadeOutSleepFlags;
449 /* 0x6a0 */ void* _6a0 = nullptr;
450 /* 0x6a8 */ Chemical* mChemical = nullptr;
451 /* 0x6b0 */ phys::Reaction* mReaction = nullptr;
452 /* 0x6b8 */ void* _6b8 = nullptr;
453 /* 0x6c0 */ UMiiModelLink mUMiiModelLink{this};
454 /* 0x6d0 */ float _6d0 = 0.0;
455 /* 0x6d8 */ void* _6d8 = nullptr;
456 /* 0x6e0 */ float _6e0 = 0.0;
457 /* 0x6e4 */ float _6e4 = 0.0;
458 /* 0x6e8 */ float _6e8 = -1.0;
459 /* 0x6ec */ int _6ec = 0;
460 /* 0x6f0 */ float _6f0 = -1.0;
461 /* 0x6f4 */ float _6f4 = 0.0;
462 /* 0x6f8 */ float _6f8 = 0.0;
463 /* 0x6fc */ int _6fc = 0;
464 /* 0x700 */ int _700 = 0;
465 /* 0x708 */ ImpulseBaseProcLink* mImpulseBaseProcLink = nullptr;
466 /* 0x710 */ sead::TypedBitFlag<StasisFlag> mStasisFlags; // TODO: probably need to rename this
467 /* 0x714 */ float mLodLoadDistanceMultiplier = 1.0;
468 /* 0x718 */ float _718 = 0.0;
469 /* 0x71c */ sead::BitFlag32 mSignals;
470 /* 0x720 */ sead::BitFlag32 _720;
471 /* 0x728 */ void* _728 = nullptr;
472 /* 0x730 */ u16 _730 = 0;
473 /* 0x732 */ sead::BitFlag16 mDrawDistanceFlags;
474 /* 0x738 */ BaseProcLink _738;
475 /* 0x748 */ BaseProcLink mCreateArgBaseProcLink;
476 /* 0x758 */ void* _758 = nullptr;
477 /* 0x760 */ xlink2::Handle _760;
478 /* 0x770 */ xlink2::Handle _770;
479 /* 0x780 */ xlink2::Handle mSwordBlurHandle;
480 /* 0x790 */ xlink2::Handle _790;
481 /* 0x7a0 */ sead::Vector3f _7a0 = sead::Vector3f::zero;
482
483 /* 0x7b0 */ ActorCreator* mCreator{};
484 /* 0x7b8 */ sead::ListNode mCreatorActorListNode;
485 /* 0x7c8 */ map::Object* mMapObject{};
486
487 /* 0x7d0 */ void* _7d0 = nullptr;
488 /* 0x7d8 */ bool _7d8 = false;
489
490 /* 0x7e0 */ ActorEditorNode mActorEditorNode;
491 /* 0x810 */ sead::Buffer<void*> mUMiiBones; // FIXME: type
492 /* 0x820 */ mii::UMii* mUMii = nullptr;
493 /* 0x828 */ mii::HylianInfo* mUMiiHylianInfo = nullptr;
494
495 /* 0x830 */ float _830 = 1.0;
496 /* 0x834 */ int _834 = 0;
497 /* 0x838 */ int _838 = 0;
498
499private:
500 enum class HandleMessageResult {
501 _0,
502 _1,
503 _2,
504 };
505
506 HandleMessageResult doHandleMessage_(const Message& message);
507};
508KSYS_CHECK_SIZE_NX150(Actor, 0x840);
509
510BaseProcLink& getDummyBaseProcLink();
511
512} // namespace act
513
514} // namespace ksys
515