| 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 | |
| 15 | namespace ksys::act { |
| 16 | class Actor; |
| 17 | class BaseProc; |
| 18 | class BaseProcInitializer; |
| 19 | class BaseProcCreateTask; |
| 20 | } // namespace ksys::act |
| 21 | |
| 22 | namespace ksys::map { |
| 23 | |
| 24 | class ObjectLinkData; |
| 25 | struct ObjectLink; |
| 26 | struct ObjectLinkArray; |
| 27 | class LinkTag; |
| 28 | |
| 29 | class Object { |
| 30 | public: |
| 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 | |
| 211 | private: |
| 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 | }; |
| 235 | KSYS_CHECK_SIZE_NX150(Object, 0x70); |
| 236 | |
| 237 | } // namespace ksys::map |
| 238 | |