SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
MapObjActor.cpp
1#include "Game/MapObj/MapObjActor.hpp"
2#include "Game/MapObj/MapPartsRotator.hpp"
3#include "Game/MapObj/MapPartsRailMover.hpp"
4#include "Game/MapObj/MapPartsRailGuideDrawer.hpp"
5#include "Game/MapObj/MapPartsRailPosture.hpp"
6#include "Game/MapObj/MapPartsRailRotator.hpp"
7#include "Game/LiveActor/MaterialCtrl.hpp"
8#include "Game/LiveActor/ModelObj.hpp"
9#include "Game/LiveActor/LodCtrl.hpp"
10#include "Game/MapObj/StageEffectDataTable.hpp"
11#include "Game/Util.hpp"
12
13#include <cstdio>
14#include <cstring>
15
16NrvMapObjActor::HostTypeDone NrvMapObjActor::HostTypeDone::sInstance;
17NrvMapObjActor::HostTypeMove NrvMapObjActor::HostTypeMove::sInstance;
18NrvMapObjActor::HostTypeWait NrvMapObjActor::HostTypeWait::sInstance;
19
20MapObjActor::MapObjActor(const char *pName) : LiveActor(pName) {
21 mObjectName = 0;
22 mPlanetLodCtrl = 0;
23 mBloomModel = 0;
24 mModelObj = 0;
25 mMatrixSetter = 0;
26 mRailMover = 0;
27 mRotator = 0;
28 mRailRotator = 0;
29 mRailPosture = 0;
30 mRailGuideDrawer = 0;
31 _B4 = 0;
32 _B5 = 0;
33 _B6 = 0;
34 mWaitNrv = &NrvMapObjActor::HostTypeWait::sInstance;
35 mMoveNrv = &NrvMapObjActor::HostTypeMove::sInstance;
36 mDoneNrv = &NrvMapObjActor::HostTypeDone::sInstance;
37}
38
39MapObjActor::MapObjActor(const char *pName, const char *pObjName) : LiveActor(pName) {
40 mObjectName = pObjName;
41 mPlanetLodCtrl = 0;
42 mBloomModel = 0;
43 mModelObj = 0;
44 mMatrixSetter = 0;
45 mRailMover = 0;
46 mRotator = 0;
47 mRailRotator = 0;
48 mRailPosture = 0;
49 mRailGuideDrawer = 0;
50 _B4 = 0;
51 _B6 = 0;
52 mWaitNrv = &NrvMapObjActor::HostTypeWait::sInstance;
53 mMoveNrv = &NrvMapObjActor::HostTypeMove::sInstance;
54 mDoneNrv = &NrvMapObjActor::HostTypeDone::sInstance;
55}
56
57void MapObjActor::init(const JMapInfoIter &rIter) {
58 if (mObjectName) {
59 return;
60 }
61
62 MR::getObjectName(&mObjectName, rIter);
63}
64
65void MapObjActor::initAfterPlacement() {
66 if (!mMatrixSetter) {
67 return;
68 }
69
70 if (!_B4) {
71 return;
72 }
73
74 mMatrixSetter->updateMtxUseBaseMtx();
75}
76
77void MapObjActor::appear() {
78 LiveActor::appear();
79
80 if (mBloomModel) {
81 mBloomModel->appear();
82 }
83
84 if (MR::isExistEffectKeeper(this)) {
85 const char* appearEffectName = cEffectNameAppear;
86 if (MR::isRegisteredEffect(this, appearEffectName)) {
87 MR::emitEffect(this, appearEffectName);
88 }
89 }
90
91 if (!MR::isEqualString(mObjectName, "DarkHopperRotateStepA")) {
92 const char* startSound = MR::StageEffect::getStartSe(mObjectName);
93
94 if (startSound) {
95 MR::startSound(this, startSound, -1, -1);
96 }
97 }
98
99 if (_B6) {
100 MR::startSystemSE("SE_SY_READ_RIDDLE_S", -1, -1);
101 }
102}
103
104void MapObjActor::kill() {
105 if (MR::isValidSwitchDead(this)) {
106 MR::onSwitchDead(this);
107 }
108
109 if (mModelObj) {
110 mModelObj->kill();
111 }
112
113 if (mBloomModel) {
114 mBloomModel->kill();
115 }
116
117 LiveActor::kill();
118}
119
120bool MapObjActor::isObjectName(const char *pName) const {
121 return MR::isEqualString(pName, mObjectName);
122}
123
124void MapObjActor::connectToScene(const MapObjActorInitInfo &rInfo) {
125 if (rInfo.mConnectToScene) {
126 if (MR::isExistCollisionResource(this, mObjectName)) {
127 s32 type = rInfo._5C;
128
129 if (type == 1) {
130 MR::connectToSceneCollisionMapObjStrongLight(this);
131 }
132 else if (type == 2) {
133 MR::connectToSceneCollisionMapObjWeakLight(this);
134 }
135 else {
136 MR::connectToSceneCollisionMapObj(this);
137 }
138 }
139 else if (rInfo._5C == 1) {
140 MR::connectToSceneMapObjStrongLight(this);
141 }
142 else {
143 MR::connectToSceneMapObj(this);
144 }
145 }
146}
147
148void MapObjActor::initCaseUseSwitchA(const MapObjActorInitInfo &) {
149 setNerve(mWaitNrv);
150}
151
152void MapObjActor::initCaseNoUseSwitchA(const MapObjActorInitInfo &) {
153
154}
155
156void MapObjActor::initCaseUseSwitchB(const MapObjActorInitInfo &rInfo) {
157 void (MapObjActor::*end)(void) = &MapObjActor::endMapPartsFunctions;
158 void (MapObjActor::*start)(void) = &MapObjActor::startMapPartsFunctions;
159 MR::listenStageSwitchOnOffB(this, MR::Functor(this, end), MR::Functor(this, start));
160}
161
162void MapObjActor::initCaseNoUseSwitchB(const MapObjActorInitInfo &rInfo) {
163 MapObjActorUtil::startAllMapPartsFunctions(this);
164}
165
166void MapObjActor::control() {
167 if (!tryEmitWaitEffect()) {
168 tryDeleteWaitEffect();
169 }
170
171 if (mPlanetLodCtrl) {
172 mPlanetLodCtrl->update();
173 }
174
175 if (mRailPosture) {
176 mRailPosture->movement();
177 }
178
179 if (mRailMover) {
180 mRailMover->movement();
181
182 if (mRailMover->isWorking()) {
183 mPosition.set(mRailMover->_28);
184 mRailMover->tryResetPositionRepeat();
185 }
186 }
187
188 if (mRotator) {
189 mRotator->movement();
190 if (mRotator->isOnReverse()) {
191 const char* startSound = MR::StageEffect::getStartSe(mObjectName);
192
193 if (startSound) {
194 MR::startSound(this, startSound, -1, -1);
195 }
196 }
197 }
198
199 if (mRailRotator) {
200 mRailRotator->movement();
201 }
202
203 if (!mRailMover && !mRotator && !mRailRotator && !MR::isEqualString(mObjectName, "OceanRingRuinsMove")) {
204 const char* movingSound = MR::StageEffect::getMovingSe(mObjectName);
205 if (movingSound) {
206 MR::startLevelSound(this, movingSound, -1, -1, -1);
207 }
208 }
209
210 if (mRailGuideDrawer) {
211 mRailGuideDrawer->movement();
212 }
213}
214
216 updateProjmapMtx();
217
218 if (MR::isExistMirrorCamera() && _B5) {
219 MR::setMirrorReflectionInfoFromModel(this);
220 }
221
222 bool v3 = 1;
223 bool v4 = 1;
224 bool v5 = 0;
225
226 if (mRotator && mRotator->isWorking()) {
227 v5 = true;
228 }
229
230 if (!v5) {
231 bool v7 = 0;
232
233 if (mRailRotator && mRailRotator->isWorking()) {
234 v7 = 1;
235 }
236
237 if (!v7) {
238 v4 = 0;
239 }
240 }
241
242 if (!v4) {
243 bool v9 = 0;
244
245 if (mRailPosture && mRailPosture->isWorking()) {
246 v9 = 1;
247 }
248
249 if (!v9) {
250 v3 = 0;
251 }
252 }
253
254 if (!v3) {
256 }
257 else {
258 TPos3f mtx;
259 mtx.identity();
260
261 if (mRailPosture && mRailPosture->isWorking()) {
262 mtx.concat(mRailPosture->_18);
263 }
264
265 if (mRotator && mRotator->isWorking()) {
266 mtx.concat(mRotator->getRotateMtx());
267 }
268
269 if (mRailRotator && mRailRotator->isWorking()) {
270 mtx.concat(mRailRotator->_5C);
271 }
272
273 mtx.mMtx[0][3] = mPosition.x;
274 mtx.mMtx[1][3] = mPosition.y;
275 mtx.mMtx[2][3] = mPosition.z;
276 MR::setBaseTRMtx(this, mtx);
277 }
278}
279
280void MapObjActor::startClipped() {
281 tryEmitWaitEffect();
282 LiveActor::startClipped();
283}
284
285void MapObjActor::endClipped() {
286 LiveActor::endClipped();
287 tryDeleteWaitEffect();
288}
289
290bool MapObjActor::tryCreateBreakModel(const MapObjActorInitInfo &rInfo) {
291 char buf[0x100];
292
293 if (rInfo._80) {
294 snprintf(buf, 0x100, "%s", rInfo._80);
295 }
296 else {
297 snprintf(buf, 0x100, "%sBreak", mObjectName);
298 }
299
300 if (!MR::isExistModel(buf)) {
301 return false;
302 }
303
304 if (MR::isEqualString(mObjectName, "SandUpDownTowerBreakableWallB")) {
305 MtxPtr baseMtx = getBaseMtx();
306 mModelObj = MR::createModelObjMapObj("壊れモデル", buf, baseMtx);
307 }
308 else {
309 MtxPtr baseMtx = getBaseMtx();
310 mModelObj = MR::createModelObjMapObjStrongLight("壊れモデル", buf, baseMtx);
311 }
312
313 mModelObj->makeActorDead();
314
315 return true;
316}
317
318bool MapObjActor::tryEmitWaitEffect() {
319 if (!MR::isExistEffectKeeper(this)) {
320 return false;
321 }
322
323 if (!MR::isRegisteredEffect(this, mObjectName)) {
324 return false;
325 }
326
327 if (MR::calcCameraDistanceZ(mPosition) > 4000.0f) {
328 return false;
329 }
330
331 if (MR::isEffectValid(this, mObjectName)) {
332 return false;
333 }
334
335 MR::emitEffect(this, mObjectName);
336 return true;
337}
338
339bool MapObjActor::tryDeleteWaitEffect() {
340 if (!MR::isExistEffectKeeper(this)) {
341 return false;
342 }
343
344 if (!MR::isRegisteredEffect(this, mObjectName)) {
345 return false;
346 }
347
348 if (MR::calcCameraDistanceZ(mPosition) <= 4000.0f) {
349 return false;
350 }
351
352 if (MR::isNearPlayer(this, 4000.0f)) {
353 return false;
354 }
355
356 if (!MR::isEffectValid(this, mObjectName)) {
357 return false;
358 }
359
360 MR::deleteEffect(this, mObjectName);
361 return true;
362}
363
364void MapObjActor::startMapPartsFunctions() {
365 MapObjActorUtil::startAllMapPartsFunctions(this);
366}
367
368void MapObjActor::endMapPartsFunctions() {
369 MapObjActorUtil::endAllMapPartsFunctions(this);
370}
371
372void MapObjActor::pauseMapPartsFunctions() {
373 MapObjActorUtil::pauseAllMapPartsFunctions(this);
374}
375
376void MapObjActor::setStateWait() {
377 setNerve(mWaitNrv);
378}
379
380void MapObjActor::updateProjmapMtx() {
381 if (!mMatrixSetter) {
382 return;
383 }
384
385 if (!_B4) {
386 return;
387 }
388
389 mMatrixSetter->updateMtxUseBaseMtx();
390}
391
392void MapObjActor::exeWait() {
393 if (MR::isValidSwitchA(this) && MR::isOnSwitchA(this)) {
394 MapObjActorUtil::startAllMapPartsFunctions(this);
395 setNerve(mMoveNrv);
396 }
397}
398
399void MapObjActor::exeMove() {
400 if (MR::isFirstStep(this)) {
401 const char* moveName = cBckNameMove;
402 if (MR::isExistBck(this, moveName)) {
403 MR::startBck(this, moveName, 0);
404 }
405 }
406
407 if (MR::isExistBck(this, cBckNameMove) && MR::isBckStopped(this)) {
408 setNerve(mDoneNrv);
409 }
410}
411
412void MapObjActorUtil::startAllMapPartsFunctions(const MapObjActor *pActor) {
413 if (pActor->mRotator) {
414 pActor->mRotator->start();
415 }
416
417 if (pActor->mRailMover) {
418 pActor->mRailMover->start();
419 }
420
421 if (pActor->mRailRotator) {
422 pActor->mRailRotator->start();
423 }
424
425 if (pActor->mRailPosture) {
426 pActor->mRailPosture->start();
427 }
428
429 if (pActor->mRailGuideDrawer) {
430 pActor->mRailGuideDrawer->start();
431 }
432}
433
434void MapObjActorUtil::endAllMapPartsFunctions(const MapObjActor *pActor) {
435 if (pActor->mRotator) {
436 pActor->mRotator->end();
437 }
438
439 if (pActor->mRailMover) {
440 pActor->mRailMover->end();
441 }
442
443 if (pActor->mRailRotator) {
444 pActor->mRailRotator->end();
445 }
446
447 if (pActor->mRailPosture) {
448 pActor->mRailPosture->end();
449 }
450}
451
452void MapObjActorUtil::pauseAllMapPartsFunctions(const MapObjActor *pActor) {
453 if (pActor->mRotator) {
454 pActor->mRotator->_14 = 0;
455 }
456
457 if (pActor->mRailMover) {
458 pActor->mRailMover->_14 = 0;
459 }
460
461 if (pActor->mRailRotator) {
462 pActor->mRailRotator->_14 = 0;
463 }
464}
465
466void MapObjActorUtil::resumeAllMapPartsFunctions(const MapObjActor *pActor) {
467 if (pActor->mRotator) {
468 pActor->mRotator->_14 = 1;
469 }
470
471 if (pActor->mRailMover) {
472 pActor->mRailMover->_14 = 1;
473 }
474
475 if (pActor->mRailRotator) {
476 pActor->mRailRotator->_14 = 1;
477 }
478}
479
480bool MapObjActorUtil::isRotatorMoving(const MapObjActor *pActor) {
481 return pActor->mRotator->isMoving();
482}
483
484bool MapObjActorUtil::isRailMoverWorking(const MapObjActor *pActor) {
485 return pActor->mRailMover->isWorking();
486}
487
488bool MapObjActorUtil::isRailMoverReachedEnd(const MapObjActor *pActor) {
489 return pActor->mRailMover->isReachedEnd();
490}
491
492f32 MapObjActorUtil::getSeesaw1AxisAngularSpeed(const MapObjActor *pActor) {
493 return pActor->mRotator->_40.mMtx[2][2];
494}
495
496void MapObjActorUtil::forceRotateSeesaw1Axis(const MapObjActor *pActor, f32 a2) {
497 pActor->mRotator->_40.mMtx[2][3] = a2;
498}
499
500void MapObjActorUtil::startRotator(const MapObjActor *pActor) {
501 pActor->mRotator->start();
502}
503
504void MapObjActorUtil::startRailMover(const MapObjActor *pActor) {
505 pActor->mRailMover->start();
506}
507
508void MapObjActorUtil::endRotator(const MapObjActor *pActor) {
509 pActor->mRotator->end();
510}
511
512void MapObjActorUtil::pauseRotator(const MapObjActor *pActor) {
513 pActor->mRotator->_14 = 0;
514}
515
516void MapObjActorUtil::resetRailMoverToInitPos(const MapObjActor *pActor) {
517 pActor->mRailMover->resetToInitPos();
518}
519
520void MapObjActorUtil::startBreak(MapObjActor *pActor) {
521 if (!MapObjActorUtil::tryStartBreak(pActor)) {
522 pActor->kill();
523 }
524}
525
526bool MapObjActorUtil::tryStartBreak(MapObjActor *pActor) {
527 const char* stopSe = MR::StageEffect::getStopSe(pActor->mObjectName);
528 if (stopSe) {
529 MR::startSound(pActor, stopSe, -1, -1);
530 }
531
532 const char* breakEffect = cEffectNameBreak;
533 if (MR::isRegisteredEffect(pActor, breakEffect)) {
534 MR::emitEffect(pActor, breakEffect);
535 }
536
537 ModelObj* modelObj = pActor->mModelObj;
538 if (modelObj) {
539 pActor->mModelObj->appear();
540 const char* breakName = (const char *)cBckNameBreak;
541 MR::startAllAnim(modelObj, breakName);
542
543 if (MR::isExistBva(pActor, breakName)) {
544 MR::startBva(pActor, breakName);
545 MR::setBvaFrameAndStop(pActor, 1.0f);
546 }
547 else {
548 MR::hideModel(pActor);
549 }
550
551 MR::invalidateClipping(modelObj);
552 return true;
553 }
554 else {
555 const char* breakName = cBckNameBreak;
556 if (MR::isExistBck(pActor, breakName)) {
557 MR::startAllAnim(pActor, breakName);
558 MR::invalidateClipping(pActor);
559 return true;
560 }
561 }
562
563 return false;
564}
565
566bool MapObjActorUtil::isBreakStopped(const MapObjActor *pActor) {
567 const LiveActor* actor = pActor->mModelObj;
568
569 if (!pActor->mModelObj && MR::isExistBck(pActor, cBckNameBreak)) {
570 actor = pActor;
571 }
572
573 if (!actor) {
574 return false;
575 }
576
577 return MR::isBckOneTimeAndStopped(actor);
578}
579
580void MapObjActorUtil::killBloomModel(MapObjActor *pActor) {
581 pActor->mBloomModel->kill();
582}
583
584void MapObjActorUtil::appearBloomModel(MapObjActor *pActor) {
585 pActor->mBloomModel->appear();
586 char buf[0x100];
587 snprintf(buf, 0x100, "%sBloom", pActor->mObjectName);
588 MR::tryStartAllAnim(pActor->mBloomModel, buf);
589}
590
591namespace NrvMapObjActor {
592 void HostTypeDone::execute(Spine *pSpine) const {
593
594 }
595
596 void HostTypeMove::execute(Spine *pSpine) const {
597 MapObjActor* actor = reinterpret_cast<MapObjActor*>(pSpine->mExecutor);
598 actor->exeMove();
599 }
600
601 void HostTypeWait::execute(Spine *pSpine) const {
602 MapObjActor* actor = reinterpret_cast<MapObjActor*>(pSpine->mExecutor);
603 actor->exeWait();
604 }
605};
The basis of a drawable actor that can contain states (see: Nerve)
Definition LiveActor.hpp:24
TVec3f mPosition
3D vector of the actor's position.
Definition LiveActor.hpp:95
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.
virtual MtxPtr getBaseMtx() const
Gets the base matrix of the model used for the actor.
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.
Definition Spine.hpp:9