1#include "Library/LiveActor/LiveActor.h"
2
3#include "Library/Action/ActorActionKeeper.h"
4#include "Library/Audio/System/AudioKeeper.h"
5#include "Library/Collision/Collider.h"
6#include "Library/Effect/EffectKeeper.h"
7#include "Library/Execute/ActorExecuteInfo.h"
8#include "Library/Execute/ExecuteUtil.h"
9#include "Library/HitSensor/HitSensorKeeper.h"
10#include "Library/LiveActor/ActorAnimFunction.h"
11#include "Library/LiveActor/ActorClippingFunction.h"
12#include "Library/LiveActor/ActorCollisionFunction.h"
13#include "Library/LiveActor/ActorFlagFunction.h"
14#include "Library/LiveActor/ActorInitInfo.h"
15#include "Library/LiveActor/ActorInitUtil.h"
16#include "Library/LiveActor/ActorModelFunction.h"
17#include "Library/LiveActor/ActorMovementFunction.h"
18#include "Library/LiveActor/ActorPoseKeeper.h"
19#include "Library/LiveActor/ActorPoseUtil.h"
20#include "Library/LiveActor/ActorSceneInfo.h"
21#include "Library/LiveActor/ActorSensorUtil.h"
22#include "Library/LiveActor/LiveActorFlag.h"
23#include "Library/LiveActor/LiveActorFunction.h"
24#include "Library/Matrix/MatrixUtil.h"
25#include "Library/Model/ModelKeeper.h"
26#include "Library/Nature/NatureDirector.h"
27#include "Library/Nerve/NerveKeeper.h"
28#include "Library/Placement/PlacementFunction.h"
29#include "Library/Rail/RailKeeper.h"
30#include "Library/Screen/ScreenPointKeeper.h"
31#include "Library/Shader/ActorOcclusionKeeper.h"
32#include "Library/Shadow/ActorShadowUtil.h"
33#include "Library/Shadow/ShadowKeeper.h"
34#include "Library/Stage/StageSwitchKeeper.h"
35#include "Project/Action/ActionPadAndCameraCtrl.h"
36#include "Project/Action/ActionSeCtrl.h"
37#include "Project/Clipping/ClippingFunction.h"
38#include "Project/Item/ActorItemKeeper.h"
39#include "Project/Item/ActorScoreKeeper.h"
40#include "Project/Light/ActorPrepassLightKeeper.h"
41
42namespace al {
43
44LiveActor::LiveActor(const char* actorName) : mName(actorName) {
45 mFlags = new LiveActorFlag();
46 mShadowKeeper = new ShadowKeeper();
47}
48
49CollisionDirector* LiveActor::getCollisionDirector() const {
50 return mSceneInfo->collisionDirector;
51}
52
53AreaObjDirector* LiveActor::getAreaObjDirector() const {
54 return mSceneInfo->areaObjDirector;
55}
56
57CameraDirector* LiveActor::getCameraDirector() const {
58 return mSceneInfo->cameraDirector;
59}
60
61NatureDirector* LiveActor::getNatureDirector() const {
62 return mSceneInfo->natureDirector;
63}
64
65SceneObjHolder* LiveActor::getSceneObjHolder() const {
66 return mSceneInfo->sceneObjHolder;
67}
68
69void LiveActor::draw() const {}
70
71void LiveActor::initAfterPlacement() {
72 tryInitFixedModelGpuBuffer(actor: this);
73 if (mPrePassLightKeeper)
74 mPrePassLightKeeper->initAfterPlacement();
75}
76
77void LiveActor::appear() {
78 makeActorAlive();
79}
80
81void LiveActor::makeActorAlive() {
82 if (mHitSensorKeeper)
83 mHitSensorKeeper->validateBySystem();
84 if (mScreenPointKeeper)
85 mScreenPointKeeper->validateBySystem();
86 mFlags->isDead = false;
87 if (isClipped(this))
88 endClipped();
89 if (!isHideModel(actor: this) && mModelKeeper)
90 mModelKeeper->show();
91 resetPosition(actor: this);
92 if (mCollisionParts)
93 validateCollisionPartsBySystem(this);
94 if (mHitSensorKeeper)
95 mHitSensorKeeper->update();
96 alClippingFunction::addToClippingTarget(actor: this);
97 if (mExecuteInfo) {
98 alActorSystemFunction::addToExecutorMovement(actor: this);
99 if (!isHideModel(actor: this) && mExecuteInfo->getDrawerCount() >= 1)
100 alActorSystemFunction::addToExecutorDraw(actor: this);
101 }
102 if (getAudioKeeper())
103 getAudioKeeper()->appear();
104 if (mPrePassLightKeeper)
105 mPrePassLightKeeper->appear(isHideModel(actor: this));
106 if (mOcclusionKeeper)
107 mOcclusionKeeper->appear(isModelHidden: isHideModel(actor: this));
108 if (mShadowKeeper && !isHideModel(actor: this))
109 mShadowKeeper->show();
110 if (mSubActorKeeper)
111 alSubActorFunction::trySyncAlive(subActorKeeper: mSubActorKeeper);
112}
113
114void LiveActor::kill() {
115 makeActorDead();
116}
117
118void LiveActor::makeActorDead() {
119 mFlags->isDead = true;
120 if (mModelKeeper)
121 mModelKeeper->hide();
122 if (mHitSensorKeeper)
123 mHitSensorKeeper->invalidateBySystem();
124 if (mPoseKeeper)
125 setVelocityZero(this);
126 if (mScreenPointKeeper)
127 mScreenPointKeeper->invalidateBySystem();
128 alClippingFunction::removeFromClippingTarget(actor: this);
129 if (mCollider)
130 mCollider->onInvalidate();
131 if (mCollisionParts)
132 invalidateCollisionPartsBySystem(this);
133 if (getEffectKeeper())
134 getEffectKeeper()->deleteAndClearEffectAll();
135 if (getAudioKeeper())
136 getAudioKeeper()->kill();
137 if (mShadowKeeper)
138 hideShadow(actor: this);
139 if (mActionKeeper) {
140 if (mActionKeeper->getPadAndCameraCtrl())
141 mActionKeeper->getPadAndCameraCtrl()->notifyActorDead();
142 if (mActionKeeper && mActionKeeper->getSeCtrl())
143 mActionKeeper->getSeCtrl()->resetAction(false);
144 }
145 if (mPrePassLightKeeper)
146 mPrePassLightKeeper->requestKill();
147 if (mOcclusionKeeper)
148 mOcclusionKeeper->requestKill();
149 if (mExecuteInfo) {
150 alActorSystemFunction::removeFromExecutorMovement(actor: this);
151 if (mExecuteInfo->getDrawerCount() >= 1)
152 alActorSystemFunction::removeFromExecutorDraw(actor: this);
153 }
154 if (mSubActorKeeper)
155 alSubActorFunction::trySyncDead(subActorKeeper: mSubActorKeeper);
156}
157
158void LiveActor::movement() {
159 if (mFlags->isDead || (mFlags->isClipped && !mFlags->isDrawClipped))
160 return;
161 if (mActionKeeper)
162 mActionKeeper->updatePrev();
163 if (mModelKeeper)
164 mModelKeeper->update();
165 if (mFlags->isMaterialCodeValid && isCollidedGround(this)) {
166 setMaterialCode(actor: this, materialCode: getCollidedFloorMaterialCodeName(this));
167 if (mFlags->isPuddleMaterialValid)
168 updateMaterialCodePuddle(actor: this);
169 }
170 if (mHitSensorKeeper) {
171 mHitSensorKeeper->attackSensor();
172 if (mFlags->isDead)
173 return;
174 }
175 if (mNerveKeeper) {
176 mNerveKeeper->update();
177 if (mFlags->isDead)
178 return;
179 }
180 control();
181 if (mFlags->isDead)
182 return;
183 updateCollider();
184 if (isUpdateMovementEffectAudioCollisionSensor(actor: this)) {
185 if (mEffectKeeper)
186 mEffectKeeper->update();
187 if (mCollisionParts) {
188 if (!mModelKeeper || !mModelKeeper->isFixedModel()) {
189 sead::Matrix34f baseMtx;
190 mPoseKeeper->calcBaseMtx(mtx: &baseMtx);
191 preScaleMtx(outMtx: &baseMtx, scale: mPoseKeeper->getScale());
192 syncCollisionMtx(this, &baseMtx);
193 }
194 }
195 if (mHitSensorKeeper)
196 mHitSensorKeeper->update();
197 }
198 if (mActionKeeper)
199 mActionKeeper->updatePost();
200 if (mShadowKeeper)
201 mShadowKeeper->update();
202 if (mScreenPointKeeper)
203 mScreenPointKeeper->update();
204 if (mModelKeeper)
205 mModelKeeper->updateLast();
206}
207
208void LiveActor::calcAnim() {
209 sead::Matrix34f baseMtx;
210 alActorPoseFunction::calcBaseMtx(mtx: &baseMtx, actor: this);
211 if (mModelKeeper && mModelKeeper->isNeedSetBaseMtxAndCalcAnim())
212 setBaseMtxAndCalcAnim(this, baseMtx, getScale(actor: this));
213 if (mCollisionParts) {
214 preScaleMtx(outMtx: &baseMtx, scale: getScale(actor: this));
215 syncCollisionMtx(this, &baseMtx);
216 }
217 if (getEffectKeeper())
218 getEffectKeeper()->update();
219 if (mHitSensorKeeper)
220 mHitSensorKeeper->update();
221 if (mOcclusionKeeper)
222 mOcclusionKeeper->updateAndRequest();
223}
224
225void LiveActor::startClipped() {
226 mFlags->isClipped = true;
227 if (mModelKeeper)
228 mModelKeeper->hide();
229 if (!mFlags->isDrawClipped) {
230 if (mHitSensorKeeper)
231 mHitSensorKeeper->invalidateBySystem();
232 if (getAudioKeeper())
233 getAudioKeeper()->startClipped();
234 if (mActionKeeper && mActionKeeper->getPadAndCameraCtrl())
235 mActionKeeper->getPadAndCameraCtrl()->notifyActorStartClipped();
236 }
237 if (getEffectKeeper())
238 getEffectKeeper()->offCalcAndDraw();
239 if (mShadowKeeper)
240 mShadowKeeper->hide();
241 if (mScreenPointKeeper)
242 mScreenPointKeeper->invalidateBySystem();
243 if (mPrePassLightKeeper)
244 mPrePassLightKeeper->hideModel();
245 if (mOcclusionKeeper)
246 mOcclusionKeeper->hideModel();
247 if (mExecuteInfo) {
248 if (!mFlags->isDrawClipped)
249 alActorSystemFunction::removeFromExecutorMovement(actor: this);
250 if (mExecuteInfo->getDrawerCount() >= 1)
251 alActorSystemFunction::removeFromExecutorDraw(actor: this);
252 if (mFlags->isDrawClipped && mModelKeeper && mModelKeeper->isIgnoreUpdateDrawClipping())
253 setNeedSetBaseMtxAndCalcAnimFlag(actor: this, value: false);
254 }
255 if (mSubActorKeeper)
256 alSubActorFunction::trySyncClippingStart(subActorKeeper: mSubActorKeeper);
257}
258
259void LiveActor::endClipped() {
260 mFlags->isClipped = false;
261 if (!mFlags->isDrawClipped) {
262 if (mHitSensorKeeper) {
263 mHitSensorKeeper->validateBySystem();
264 updateHitSensorsAll(this);
265 }
266 if (getAudioKeeper())
267 getAudioKeeper()->endClipped();
268 if (mActionKeeper && mActionKeeper->getPadAndCameraCtrl())
269 mActionKeeper->getPadAndCameraCtrl()->notifyActorEndClipped();
270 }
271 if (getEffectKeeper())
272 getEffectKeeper()->onCalcAndDraw();
273 if (mScreenPointKeeper)
274 mScreenPointKeeper->validateBySystem();
275 if (mExecuteInfo) {
276 if (!mFlags->isDrawClipped)
277 alActorSystemFunction::addToExecutorMovement(actor: this);
278 if (mExecuteInfo->getDrawerCount() >= 1 && !isHideModel(actor: this))
279 alActorSystemFunction::addToExecutorDraw(actor: this);
280 if (mModelKeeper && mModelKeeper->isIgnoreUpdateDrawClipping())
281 setNeedSetBaseMtxAndCalcAnimFlag(actor: this, value: true);
282 }
283 if (!isHideModel(actor: this) && mModelKeeper)
284 mModelKeeper->show();
285 if (mShadowKeeper && !isHideModel(actor: this))
286 mShadowKeeper->show();
287 if (mPrePassLightKeeper)
288 mPrePassLightKeeper->appear(isHideModel(actor: this));
289 if (mOcclusionKeeper)
290 mOcclusionKeeper->appear(isModelHidden: isHideModel(actor: this));
291 if (mSubActorKeeper)
292 alSubActorFunction::trySyncClippingEnd(subActorKeeper: mSubActorKeeper);
293}
294
295const sead::Matrix34f* LiveActor::getBaseMtx() const {
296 if (mModelKeeper)
297 return mModelKeeper->getBaseMtx();
298 if (mPoseKeeper)
299 return mPoseKeeper->getMtxPtr();
300 return nullptr;
301}
302
303RailRider* LiveActor::getRailRider() const {
304 if (mRailKeeper)
305 return mRailKeeper->getRailRider();
306 return nullptr;
307}
308
309ActorSceneInfo* LiveActor::getSceneInfo() const {
310 return mSceneInfo;
311}
312
313void LiveActor::initHitSensor(s32 amount) {
314 mHitSensorKeeper = new HitSensorKeeper(amount);
315}
316
317void LiveActor::initCollider(f32 radius, f32 offsetY, u32 allocatedHitInfo) {
318 mCollider = new Collider(getCollisionDirector(), getBaseMtx(), &getTrans(actor: this),
319 &getGravity(actor: this), radius, offsetY, allocatedHitInfo);
320 mFlags->isCollideOff = false;
321}
322
323void LiveActor::initPoseKeeper(ActorPoseKeeperBase* poseKeeper) {
324 mPoseKeeper = poseKeeper;
325}
326
327void LiveActor::initExecuteInfo(ActorExecuteInfo* executeInfo) {
328 mExecuteInfo = executeInfo;
329}
330
331void LiveActor::initRailKeeper(const ActorInitInfo& info, const char* linkName) {
332 mRailKeeper = tryCreateRailKeeper(info: *info.placementInfo, linkName);
333}
334
335void LiveActor::initModelKeeper(ModelKeeper* modelKeeper) {
336 mModelKeeper = modelKeeper;
337 offUpdateMovementEffectAudioCollisionSensor(actor: this);
338}
339
340void LiveActor::initScoreKeeper() {
341 mScoreKeeper = new ActorScoreKeeper();
342}
343
344void LiveActor::initStageSwitchKeeper() {
345 mStageSwitchKeeper = new StageSwitchKeeper();
346}
347
348void LiveActor::initItemKeeper(s32 itemAmount) {
349 mItemKeeper = new ActorItemKeeper(this, itemAmount);
350}
351
352void LiveActor::initActionKeeper(ActorActionKeeper* actionKeeper) {
353 mActionKeeper = actionKeeper;
354}
355
356void LiveActor::initScreenPointKeeper(ScreenPointKeeper* screenPointKeeper) {
357 mScreenPointKeeper = screenPointKeeper;
358}
359
360void LiveActor::initEffectKeeper(EffectKeeper* effectKeeper) {
361 mEffectKeeper = effectKeeper;
362 if (mModelKeeper)
363 alEffectKeeperInitFunction::setupModelToEffectKeeper(effectKeeper: mEffectKeeper, modelKeeper: mModelKeeper);
364 alEffectKeeperInitFunction::setupCameraToEffectKeeper(effectKeeper: mEffectKeeper, iUseCamera: this);
365}
366
367void LiveActor::initNerveKeeper(NerveKeeper* nerveKeeper) {
368 mNerveKeeper = nerveKeeper;
369}
370
371void LiveActor::initAudioKeeper(AudioKeeper* audioKeeper) {
372 mAudioKeeper = audioKeeper;
373}
374
375void LiveActor::initActorPrePassLightKeeper(ActorPrePassLightKeeper* lightKeeper) {
376 mPrePassLightKeeper = lightKeeper;
377}
378
379void LiveActor::initActorOcclusionKeeper(ActorOcclusionKeeper* occlusionKeeper) {
380 mOcclusionKeeper = occlusionKeeper;
381}
382
383void LiveActor::initSubActorKeeper(SubActorKeeper* subActorKeeper) {
384 mSubActorKeeper = subActorKeeper;
385}
386
387void LiveActor::initSceneInfo(ActorSceneInfo* sceneInfo) {
388 mSceneInfo = sceneInfo;
389}
390
391void LiveActor::updateCollider() {
392 if (!mPoseKeeper)
393 return;
394 const sead::Vector3f& velocity = getVelocity(actor: this);
395 if (mCollider) {
396 if (mFlags->isCollideOff) {
397 *getTransPtr(actor: this) += velocity;
398 mCollider->onInvalidate();
399 } else {
400 *getTransPtr(actor: this) += mCollider->collide(velocity);
401 }
402 return;
403 }
404 *getTransPtr(actor: this) += velocity;
405}
406
407} // namespace al
408