SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
MarioActor.cpp
1#include "Game/Player/MarioActor.hpp"
2#include "Game/Animation/XanimePlayer.hpp"
3#include "Game/Enemy/KariKariDirector.hpp"
4#include "Game/Gravity.hpp"
5#include "Game/LiveActor/Binder.hpp"
6#include "Game/Map/CollisionParts.hpp"
7#include "Game/Map/HitInfo.hpp"
8#include "Game/Map/WaterInfo.hpp"
9#include "Game/Player/MarioAnimator.hpp"
10#include "Game/Player/MarioConst.hpp"
11#include "Game/Player/MarioEffect.hpp"
12#include "Game/Player/MarioHolder.hpp"
13#include "Game/Player/MarioMessenger.hpp"
14#include "Game/Player/MarioNullBck.hpp"
15#include "Game/Player/MarioParts.hpp"
16#include "Game/Player/MarioShadow.hpp"
17#include "Game/Player/MarioSwim.hpp"
18#include "Game/Player/RushEndInfo.hpp"
19#include "Game/Screen/GameSceneLayoutHolder.hpp"
20#include "Game/Util/CameraUtil.hpp"
21#include "Game/Util/FootPrint.hpp"
22#include "JSystem/JAudio2/JAIAudible.hpp"
23#include "JSystem/JMath/JMath.hpp"
24
25Triangle &Triangle::operator=(const Triangle &rOther)
26{
27 mParts = rOther.mParts;
28 mIdx = rOther.mIdx;
29 mSensor = rOther.mSensor;
30 mNormals[0] = rOther.mNormals[0];
31 mNormals[1] = rOther.mNormals[1];
32 mNormals[2] = rOther.mNormals[2];
33 mNormals[3] = rOther.mNormals[3];
34 mPos[0] = rOther.mPos[0];
35 mPos[1] = rOther.mPos[1];
36 mPos[2] = rOther.mPos[2];
37
38 return *this;
39}
40
41MarioActor::MarioActor(const char *pName) : LiveActor(pName), _1B0(0xFFFFFFFF)
42{
43 initMember();
44 mMario = new Mario(this);
45 _930 = 0;
46 _468.x = 0;
47 mMaxHealth = 3;
48 mHealth = 3;
49 _384 = 8;
50
51 if (MR::isPlayerLuigi()) {
52 mMaxHealth = 3;
53 mHealth = 3;
54 }
55
56 if (MR::isGalaxyDarkCometAppearInCurrentStage()) {
57 mMaxHealth = 1;
58 mHealth = 1;
59 }
60 init2D();
61 _989 = 0;
62 _41C = 0;
63 _420 = 0;
64 _37C = 0;
65 _92C = 0;
66 _388 = 0;
67 _38C = 0;
68 _390 = 0;
69 _394 = 0;
70 _398 = 0;
71 _3A4 = 0;
72 _3A8 = 0;
73 _3AA = 0;
74 _944 = 0;
75 _946 = 0;
76 _BC4 = 0;
77 _948 = 0;
78 _94C = 0;
79 _94E = 0;
80 _94A = 0;
81 _47C = 0;
82 _3DC = 0;
83 _3D8 = 0;
84 _3DA = 0;
85 _3AC = 0;
86 _B94 = 0;
87 _378 = 0;
88 _6D4 = 0f;
89 mSuperKinokoCollected = false;
90 mPowerupCollected = false;
91 mTransforming = false;
92 _950 = 0;
93 _951 = 0;
94 _974 = 0;
95 _39C = 0;
96 _3B0 = 0.000003814697265625f;
97
98 _3B4.zero();
99
100 _3C1 = false;
101 _211 = 0;
102 _468.y = 0;
103 _468.z = 0;
104 _474 = 0;
105 _924 = nullptr;
106 _928 = 0;
107 _480 = 0;
108 _481 = 0;
109 _482 = 0;
110 _483 = 0;
111
112 _484.zero();
113
114 _B92 = 0;
115 _3D4 = 0;
116 _3D6 = 0;
117 _3D2 = 1;
118 _3DF = 0;
119 _3DE = 0;
120 _EEB = 1;
121 _9D4 = 0;
122
123 _9CC = 0.0f;
124 _9D0 = 0.0f;
125
126 _9D8.zero();
127
128 _9F1 = false;
129 _9F2 = false;
130 _EA4 = false;
131 _EA5 = false;
132 _FCC = false;
133 _FCD = false;
134
135 _EA8.identity();
136 _3EC.identity();
137
138 _1F0.zero();
139 _1FC.zero();
140
141 _F4C = 0;
142 _208 = 1000.0f;
143
144 _F50.zero();
145 _F5C.zero();
146 _F68.zero();
147
148 for (int i = 0; i < 6; i++) {
149 _A28[i] = 0;
150 }
151
152 _A61 = false;
153
154 _A64 = 0xff;
155
156 _A68 = 1.0f;
157
158 _A6C = 0;
159 _B48 = nullptr;
160 _934 = false;
161 _7E2 = 0;
162 _EF6 = 0;
163 _424 = 0;
164 _4A4 = 0;
165 _6D0 = 0;
166 _3A0 = 0;
167 _EFC = 0;
168 _EF8 = 0;
169 _E9C = 0;
170
171 _EA0 = 1.0f;
172
173 _3C4.zero();
174
175 _3D0 = 0;
176 _7DE = 0;
177 _3C0 = false;
178 _B90 = false;
179 _B91 = false;
180 _39D = 0;
181 _B96 = 0;
182 _EF0 = 0;
183 _EF2 = 0;
184 _EF4 = 0x78;
185 _1AA = 0;
186 _1AC = 0.0f;
187
188 _1B0.set(0xFF, 0xFF, 0xFF, 0);
189
190 _1B5 = false;
191 _988 = 0;
192
193 _F10 = 2;
194 _F12 = 2;
195
196 _F14 = 3;
197 _F16 = 3;
198
199 _F18 = 0xb;
200
201 _F1A = 3;
202
203 _F0E = 7;
204
205 resetPadSwing();
206
207 _F0D = 0;
208
209 _F1C = 0x3C;
210 _F1E = 0x3C;
211
212 _1E1 = 0;
213 _F24 = 0;
214 _F28 = 0;
215
216 _C2C.identity();
217 _C5C.identity();
218 _D1C.identity();
219 _D4C.identity();
220 _D7C.identity();
221
222 _1B4 = 0;
223 _1C3 = false;
224 _1E0 = false;
225}
226
227static float BASE_ROTATION = 0.0f;
228
230{
231 long initialAnimation = -1;
232 if (!MR::isValidInfo(rInfo)) {
233 return;
234 }
235 TVec3f position, rotation, scale;
236
237 MR::getJMapInfoTrans(rInfo, &position);
238 MR::getJMapInfoRotate(rInfo, &rotation);
239 MR::getJMapInfoScale(rInfo, &scale);
240
241 rotation.x = BASE_ROTATION + (f32)fmod(rotation.x - BASE_ROTATION + 360.0f, 360.0);
242 rotation.y = BASE_ROTATION + (f32)fmod(rotation.y - BASE_ROTATION + 360.0f, 360.0);
243 rotation.z = BASE_ROTATION + (f32)fmod(rotation.z - BASE_ROTATION + 360.0f, 360.0);
244
245 if (MR::isExistJMapArg(rInfo)) {
246 MR::getJMapInfoArg0NoInit(rInfo, &initialAnimation);
247 }
248 init2(position, rotation, initialAnimation);
249}
250
251struct DUMMY {
252 u8 _0[0x30];
253};
254
255void MarioActor::init2(const TVec3f &a, const TVec3f &b, long initialAnimation)
256{
257 _8C = 1;
258 gIsLuigi = false;
259 if (MR::isPlayerLuigi()) {
260 gIsLuigi = true;
261 }
262 mPosition.set(a);
263 mRotation.set(b);
264 mScale.set(TVec3f(1.0f, 1.0f, 1.0f));
265 mMario->setHeadAndFrontVecFromRotate(mRotation);
266 mMario->_290 = mMario->_310;
267 updateBaseScaleMtx();
268 _A18 = mRotation;
269 initDrawAndModel();
270
271 // Matrix?
272 _C28 = new DUMMY[MR::getJointNum(this)];
273
274 MR::connectToScene(this, 0x25, 0x9, 0x14, 0x22);
275 MR::initLightCtrlForPlayer(this);
276 mMarioAnim = new MarioAnimator(this);
277 mMarioEffect = new MarioEffect(this);
278 _214 = new CollisionShadow(100.0f, 360.0f);
279 mConst = new MarioConst();
280 if (gIsLuigi) {
281 mConst->_8 = 1;
282 }
283 mMario->initAfterConst();
284 _36C = new GravityInfo();
285 _374 = 0.0f;
286 initNerve(&NrvMarioActor::MarioActorNrvWait::sInstance);
287 _FB4 = 0;
288 _FB8 = 0;
289 initActionMatrix();
290 initBinder(60.0f, 1.0f, 8);
291 _2C4.x = 0.0f;
292 _2C4.y = 70.0f;
293 _2C4.z = 0.0f;
294 mBinder->_1EC._0 = false;
295 MR::setBinderOffsetVec(this, &_2C4, false);
296
297 mBinder->setTriangleFilter(TriangleFilterDelegator<MarioActor>::allocateDelegator(this, &MarioActor::binderFilter));
298
299 mBinder->_1EC._3 = true;
300 initEffect();
301 MR::invalidateClipping(this);
302
303 _240.setInline(0.0f, -1.0f, 0.0f);
304
305 _24C = _240;
306 _334 = 0;
307 _336 = 0;
308 _338 = 0;
309
310 _264.zero();
311 _270 = mPosition;
312 calcCenterPos();
313 initSound(0x10, 0);
314 addSoundObjHolder();
315 initParts();
316 initMorphStringTable();
317 MR::declareGlobalEventCameraAbyss("奈落カメラ");
318 MR::declareBlackHoleCamera("ブラックホール");
319 MR::declareGlobalEventCameraDead("昇天カメラ", 0.34999999404f, 0x78, 0x3C);
320 MR::declareGlobalEventCamera("水中フォロー");
321 MR::declareGlobalEventCamera("水中プラネット");
322 MR::declareGlobalEventCamera("水上フォロー");
323 MR::declareGlobalEventCamera("引き戻し");
324 MR::declareEventCameraProgrammable("変身初出カメラ");
325 _2B8 = mPosition;
326 _33C = mPosition;
327 _348.zero();
328 _354.zero();
329 setupSensors();
330 MR::getMarioHolder()->setMarioActor(this);
331 _1BC = new MarioMessenger(getSensor("dummy"));
332 _300 = mMario->_1F0;
333 _2D0 = _300;
334 _330 = 0;
335 _332 = 0;
336 MR::setGameCameraTargetToPlayer();
337 _A0C = 0;
338 _B48 = new FootPrint("足跡", 0x100, -1);
339 _B48->setTexture(MR::getTexFromArc("Footprint.bti", this));
340 switch (initialAnimation) {
341 case 1:
342 mMario->changeAnimation("基本", (const char *)nullptr);
343 break;
344 case 2:
345 mMario->changeAnimationNonStop("ウォークイン");
346 break;
347 default:
348 mMario->changeAnimation("ステージインA", (const char *)nullptr);
349 break;
350 }
351 updateTransForCamera();
352 _F44 = 1;
353 _984 = 0.0f;
354 _978.zero();
355 _27C.zero();
356 _288.zero();
357 _498 = new FixedPosition(this, "HandR", TVec3f(0.0f, 0.0f, 0.0f), TVec3f(0.0f, 0.0f, 0.0f));
358 _49C = new FixedPosition(this, "HandR", TVec3f(76.3300018311f, 15.6899995804f, 88.9899978638f), TVec3f(1.79999995232f, 52.5099983215f, 39.5800018311f));
359 _494 = 0;
360 _4B0 = 35.0f;
361 _4B4 = 60.0f;
362 _4B8.setInline(0.0f, 1.0f, 0.0f);
363 _4C4 = -_4B8;
364 _482 = true;
365 appear();
366 _482 = false; // do we change this to control appearances?
367 _1C6 = 0;
368 _1C8 = 0.0f;
369 _1CC = 0.0f;
370 _1D0 = 0;
371 _1D1 = 0;
372 _A24 = 0;
373 _A25 = 0;
374 _1D8 = new (0x20) MarioActor::FBO[MR::getFrameBufferWidth()];
375 _1DC = new (0x20) MarioActor::FBO[MR::getFrameBufferWidth()];
376 _1E4 = 0.0f;
377 _1E8 = 0;
378 _1EC = 0.0f;
379 _F3C = new JAIAudible[0x1E];
380 _F40 = 0;
381 _F42 = 1;
382 for (int i = 0; i < 0x1E; i++) {
383 JAIAudible &rAudible = _F3C[i];
384 rAudible._0 = 1.0f;
385 rAudible._4 = 0.0f;
386 rAudible._8 = 0.0f;
387 }
388 _8C = 0; // is this to indicate that we are in the process of initialization?
389}
390
391void MarioActor::initAfterPlacement()
392{
393 updateGravityVec(true, true);
394 mMario->_1D8 = _240;
395 mMario->_1F0 = -_240;
396 mMario->_1FC = -_240;
397 _300 = mMario->_1F0;
398 _2D0 = _300;
399 _2C4 = _240 % -70.0f;
400 calcCenterPos();
401 MR::updateHitSensorsAll(this);
402 _360 = getGravityVector();
403 _1C0 = true;
404 _9F4 = getGravityVector();
405 updateCameraInfo();
406 calcBaseFrontVec(-_240);
407}
408
409void MarioActor::initAfterOpeningDemo()
410{
411 mMario->changeAnimationNonStop("ウォークイン");
412 _37C = 0;
413}
414
415void MarioActor::calcBaseFrontVec(const TVec3f &rVec)
416{
417 TVec3f cross, j(0.0f, 1.0f, 0.0f);
418 f32 y = j.dot(rVec);
419 if (y < -0.99f) {
420 _258.setInline(0.0f, 0.0f, 1.0f);
421 }
422 else {
423 f32 cosine;
424 if (MR::makeAxisAndCosignVecToVec(&cross, &cosine, rVec, j)) {
425 TVec3f k(0.0f, 0.0f, 1.0f);
426 Mtx transformation;
427 PSMTXRotAxisRad(transformation, cross.toCVec(), -JMAAcosRadian(cosine));
428 PSMTXMultVecSR(transformation, k.toCVec(), _258.toVec());
429 MR::normalize(&_258);
430 }
431 else {
432 _258.setInline(0.0f, 0.0f, 1.0f);
433 }
434 }
435}
436
437void MarioActor::playSound(const char *pName, long duration)
438{
439 mMario->playSound(pName, duration);
440}
441
442void MarioActor::changeAnimation(const char *pName, const char *pNewName)
443{
444 mMario->changeAnimation(pName, pNewName);
445}
446
447void MarioActor::changeAnimationNonStop(const char *pName)
448{
449 mMario->changeAnimationNonStop(pName);
450}
451
452void MarioActor::changeAnimationUpper(const char *pName)
453{
454 if (!mMario->_71C) {
455 if (isAnimationRun("基本")) {
456 mMario->changeAnimationUpper(pName, nullptr);
457 return;
458 }
459 }
460 mMario->changeAnimation(pName, (const char *)nullptr);
461}
462
463void MarioActor::stopAnimation(const char *pName)
464{
465 mMario->stopAnimation(pName, (const char *)nullptr);
466}
467
468bool MarioActor::isAnimationRun(const char *pName) const
469{
470 return mMario->isAnimationRun(pName);
471}
472
473void MarioActor::changeNullAnimation(const char *pName, signed char num)
474{
475 mNullAnimation->appear();
476 MR::startBck(mNullAnimation, pName, nullptr);
477 _B92 = num;
478}
479
480bool MarioActor::isStopNullAnimation() const
481{
482 if (!MR::isBckStopped(mNullAnimation)) {
483 return MR::isDead(mNullAnimation);
484 }
485 return true;
486}
487
488void MarioActor::changeGameOverAnimation()
489{
490 int animation = 0;
491 if (mMario->isStatusActive(0x12)) {
492 mMario->closeStatus(nullptr);
493 }
494
495 if (mMario->isAnimationRun("前方小ダメージ")) {
496 animation = 0;
497 }
498 if (mMario->isAnimationRun("後方小ダメージ")) {
499 animation = 0;
500 }
501 if (mMario->isAnimationRun("ファイアラン前兆")) {
502 animation = 0;
503 }
504 if (mMario->isAnimationRun("炎のランナー")) {
505 animation = 0;
506 }
507 if (mMario->isAnimationRun("電気ダメージ")) {
508 animation = 1;
509 }
510 if (mMario->isAnimationRun("電気ダメージ終了")) {
511 animation = 1;
512 }
513 if (mMario->isAnimationRun("炎ダメージ")) {
514 animation = 2;
515 }
516 if (mMario->isAnimationRun("ファイアダンス")) {
517 animation = 2;
518 }
519 if (mMario->isAnimationRun("中ダメージ")) {
520 animation = 3;
521 }
522 if (mMario->isAnimationRun("中ダメージ空中")) {
523 animation = 3;
524 }
525 if (mMario->isAnimationRun("中ダメージ着地")) {
526 animation = 3;
527 }
528 if (mMario->isAnimationRun("中後ダメージ")) {
529 animation = 4;
530 }
531 if (mMario->isAnimationRun("中後ダメージ空中")) {
532 animation = 4;
533 }
534 if (mMario->isAnimationRun("中後ダメージ着地")) {
535 animation = 4;
536 }
537 if (mMario->isAnimationRun("落下")) {
538 animation = 5;
539 }
540 if (mMario->isAnimationRun("空中ふんばり")) {
541 animation = 5;
542 }
543 if (mMario->isAnimationRun("つぶれ")) {
544 animation = 6;
545 }
546 if (mMario->isAnimationRun("つぶれ復帰")) {
547 animation = 6;
548 }
549
550 if (mMario->isAnimationRun("氷結") || mMario->isStatusActive(0xd)) {
551 animation = -1;
552 }
553
554 if (mMario->isSwimming()) {
555 animation = 7;
556 }
557 if (isNerve(&NrvMarioActor::MarioActorNrvGameOverSink::sInstance)) {
558 animation = 8;
559 }
560 if (MR::getKariKariClingNum() && mMario->getMovementStates()._1) {
561 animation = 4;
562 }
563 if (_39D == 2) {
564 animation = 9;
565 }
566 if (_39D == 1) {
567 animation = 10;
568 }
569
570 switch (animation) {
571 case 0:
572 mMario->changeAnimationNonStop("座りダウン");
573 break;
574 case 1:
575 mMario->changeAnimationNonStop("感電ダウン");
576 break;
577 case 2:
578 mMario->changeAnimationNonStop("炎ダウン");
579 break;
580 case 3:
581 mMario->changeAnimationNonStop("仰向けダウン");
582 break;
583 case 4:
584 mMario->changeAnimationNonStop("俯せダウン");
585 break;
586 case 5:
587 if (mMario->getMovementStates()._1) {
588 mMario->changeAnimationNonStop("座りダウン");
589 }
590 else {
591 mMario->changeAnimationNonStop("奈落ダウン");
592 }
593 break;
594 case 6:
595 mMario->changeAnimationNonStop("つぶれダウン");
596 break;
597 case 7:
598 mMario->changeAnimationNonStop("水泳ダウン");
599 break;
600 case 8:
601 mMario->changeAnimationNonStop("埋まりダウン");
602 break;
603 case 9:
604 mMario->changeAnimationNonStop("レース負け");
605 break;
606 case 10:
607 mMario->changeAnimationNonStop("水中レース負け");
608 break;
609 }
610 _B90 = true;
611 stopEffect("無敵中");
612 _A6E = false;
613}
614
615XjointTransform *MarioActor::getJointCtrl(const char *pName) const
616{
617 XanimeCore *pCore = mMarioAnim->_C->mCore;
618 return pCore->getJointTransform(MR::getJointIndex(this, pName));
619}
620
621bool MarioActor::isTurning() const
622{
623 return getMovementStates()._3;
624}
625
626bool MarioActor::isDebugMode() const
627{
628 return getMovementStates()._16;
629}
630
631void MarioActor::updateRotationInfo()
632{
633 TRot3f stack_44;
634 PSMTXConcat(getBaseMtx(), _E3C.toMtxPtr(), stack_44.toMtxPtr());
635 MR::makeRTFromMtxPtr(nullptr, &mRotation, stack_44.toMtxPtr(), true);
636 if (mRotation.z > 90.0f && mRotation.x > 90.0f) {
637 f32 diff = 180.0f - mRotation.y;
638 mRotation.z = 0.0f;
639 mRotation.y = diff;
640 mRotation.x = 0.0f;
641 }
642 stack_44.getEuler(_318);
643 _318.scaleInline(57.2957763672f);
644 stack_44.getEuler(_324);
645 _324.scaleInline(57.2957763672f);
646 if (MR::isSameDirection(_240, mMario->_208, .01f)) {
647 _A18 = mRotation;
648 }
649 else {
650 TPos3f stack_14;
651 TVec3f stack_8 = -_240;
652 MR::makeMtxUpFront(&stack_14, stack_8, mMario->_208);
653 MR::makeRTFromMtxPtr(nullptr, &_A18, stack_14.toMtxPtr(), true);
654 if (_A18.z > 90.0f && _A18.x > 90.0f) {
655 f32 diff = 180.0f - _A18.y;
656 _A18.z = 0.0f;
657 _A18.y = diff;
658 _A18.x = 0.0f;
659 }
660 }
661}
662
663void MarioActor::exeWait()
664{
665 if (_FB8 != 0) {
666 _FB8--;
667 if (_FB8 == 0) {
668 setNerve(_FB4);
669 _FB4 = nullptr;
670 }
671 }
672}
673
674void MarioActor::movement()
675{
676 _468.y = 0;
677 _378++;
678 _1E1 = 0;
679 PSMTXCopy(_AE0.toMtxPtr(), _AB0.toMtxPtr());
680 PSMTXCopy(MR::getCameraViewMtx(), _AE0.toMtxPtr());
681 updateCameraInfo();
682 _4A8 = 0;
683 _4AC = 0.785398185253f;
684 LiveActor::movement();
685 TVec3f stack_134(mPosition);
686 stack_134 -= _294;
687 TVec3f stack_128(stack_134);
688 stack_128 -= mVelocity;
689 _27C = stack_134;
690 TVec3f stack_11C(_288);
691 _288 = stack_128;
692 if (MR::isOppositeDirection(_288, stack_11C, 0.01f)) {
693 f32 mag_288 = PSVECMag(_288.toCVec());
694 f32 magStack_11C = PSVECMag(stack_11C.toCVec());
695 if (!MR::isNearZero(mag_288, 0.001f) && !MR::isNearZero(magStack_11C, 0.001f) && MR::isNearZero(mag_288 - magStack_11C, 1.0f)) {
696 mPosition -= _288 % 0.5f;
697 }
698 }
699 if (PSVECMag(stack_128.toCVec()) > 0.1f) {
700 if (!(getMovementStates()._A)) {
701 if (!MR::isNearZero(mVelocity, 0.001f)) {
702 f32 diffMag = PSVECMag(_294.translateOpposite(_270).toCVec());
703 f32 vMag = PSVECMag(mVelocity.toCVec());
704 if (PSVECMag(stack_128.toCVec()) > 2.0f * (diffMag + vMag)) {
705 mMario->stopWalk();
706 }
707 }
708 }
709 if (getMovementStates()._23 && PSVECMag(mVelocity.toCVec()) < PSVECMag(stack_134.toCVec())) {
710 if (stack_134.dot(getGravityVec()) < -0.0f) {
711 TVec3f stack_110;
712 MR::vecKillElement(mVelocity, getGravityVec(), &stack_110);
713 if (MR::isNearZero(stack_110, 0.001f)) {
714 MR::vecKillElement(stack_134, getGravityVec(), &stack_110);
715 }
716 stack_110.setLength(PSVECMag(stack_134.toCVec()));
717 mMario->push(stack_110);
718 if (mMario->_3BC <= 2) {
719 f32 scale = PSVECMag(stack_128.toCVec());
720 if (scale > 10.0f) {
721 scale = 10.0f;
722 }
723 mMario->_2D4 += -getGravityVec() % scale;
724 }
725 }
726 }
727 else if (getMovementStates()._23) {
728 TVec3f stack_104(mMario->_8F8);
729 MR::normalizeOrZero(&stack_104);
730 TVec3f stack_F8;
731 f32 elementA = MR::vecKillElement(stack_134, stack_104, &stack_F8);
732 f32 elementB = MR::vecKillElement(mVelocity, stack_104, &stack_F8);
733 if (PSVECMag(mVelocity.toCVec()) > 20.0f && elementA < elementB * 0.5f) {
734 if (mMario->isAnimationRun("坂すべり下向きあおむけ")) {
735 mMario->push(mMario->_208 % 5.0f);
736 }
737 else if (mMario->isAnimationRun("坂すべり上向きうつぶせ")) {
738 mMario->push(mMario->_208 % -5.0f);
739 }
740 mMario->mDrawStates._2 = true;
741 }
742 }
743 if (getMovementStates()._0 && !_9F1) {
744 if (stack_128.dot(getGravityVec()) < -40.0f) {
745 TVec3f stack_EC(mPosition.translateOpposite(getGravityVec() % 100.0f));
746 TVec3f stack_E0;
747 Triangle *pTmp = mMario->getTmpPolygon();
748
749 if (MR::getFirstPolyOnLineToMap(&stack_E0, pTmp, stack_EC, getGravityVec() % 200f)) {
750 TVec3f stack_D4;
751 if (MR::vecKillElement(stack_E0.translateOpposite(mPosition), getGravityVec(), &stack_D4) < -5f && pTmp->mParts && !pTmp->mParts->_D4 && getMovementStates()._3E != 1) {
752 mPosition = stack_E0;
753 mMario->_130 = mPosition;
754 mMario->stopJump();
755 mMario->changeAnimation("基本", "落下");
756 mMario->updateGroundInfo();
757 }
758 }
759 }
760 else if (stack_128.dot(getGravityVec()) > 40.0f) {
761 if (mMario->_4C8->isValid()) {
762 if (MR::isSensorPressObj(mMario->_4C8->mSensor)) {
763 mMario->mDrawStates._1E = true;
764 }
765 }
766 else {
767 const u32 stop = mBinder->_28;
768 for (int i = 0; i < stop; i++) {
769 if (MR::isSensorPressObj(mBinder->getPlane(i)->mSensor)) {
770 mMario->mDrawStates._1E = true;
771 }
772 }
773 }
774 if (mMario->_31C.translateOpposite(mPosition).dot(getGravityVector()) < 0.0f) {
775 bool eject = true;
776 CollisionParts *parts = mMario->_45C->mParts;
777 if (parts && !mMario->_45C->mParts->_D4) {
778 TVec3f stack_C8, stack_BC, stack_B0;
779 PSMTXMultVec(parts->mInvBaseMatrix.toMtxPtr(), mMario->_31C.toCVec(), stack_C8.toVec());
780 PSMTXMultVec(parts->mPrevBaseMatrix.toMtxPtr(), stack_C8.toCVec(), stack_BC.toVec());
781 stack_B0 = mMario->_31C.translateOpposite(stack_BC);
782 if (stack_B0.dot(stack_128) > 0.0f) {
783 eject = false;
784 }
785 }
786 if (eject) {
787 mPosition = mMario->_31C;
788 mMario->_2D4.zero();
789 mMario->_148.zero();
790 if (!mMario->_5FC && (getDrawStates()._1E || getPrevDrawStates()._1E)) {
791 TVec3f stack_A4(stack_128);
792 MR::normalizeOrZero(&stack_A4);
793 _3B4 = stack_A4;
794 setPress(0, 0);
795 _3B0 = 0.1f;
796 }
797 }
798 }
799 }
800 }
801 else if (mMario->getMovementStates()._1) {
802 const u32 stop = mBinder->_28;
803 bool eject = false;
804 for (u32 i = 0; i < stop; i++) {
805 const Triangle *plane = mBinder->getPlane(i);
806 if (!MR::isSensorPressObj(plane->mSensor)) {
807 continue;
808 }
809 if (mMario->_368.dot(*plane->getNormal(0)) > 0.0f) {
810 if (mMario->_72C < 200.0f) {
811 eject = true;
812 }
813 else if (plane->getNormal(0)->dot(stack_134) < 0.0f) {
814 eject = true;
815 }
816 else {
817 eject = false;
818 }
819 }
820 else if (plane->getNormal(0)->dot(stack_134) < 0.0f) {
821 eject = true;
822 }
823 else if (mMario->_5FC) {
824 if (!MR::isWallCodeNoAction(plane) && !mMario->isOnimasuBinderPressSkip()) {
825 _3B4 = mMario->_368;
826 mMario->_10._3E = false;
827 *mMario->_4C8 = *plane;
828 setPress(2, 0);
829 _3B0 = 0.1f;
830 }
831 eject = true;
832 }
833 }
834 if (eject) {
835 TVec3f stack_98;
836 f32 element = MR::vecKillElement(stack_134, mMario->_368, &stack_98);
837 mPosition -= mMario->_368 % element;
838 }
839 }
840 }
841 if (mMario->mDrawStates._1A) {
842 mMario->mDrawStates._1A = false;
843 mMarioAnim->MarioAnimator::update();
844 }
845 mMario->recordRelativePosition();
846 updateTransForCamera();
847 calcAnimInMovement();
848 _935 = false;
849 mMario->_2D0 = 0.0f;
850 _F3C_vec[_F40] = mMario->_208;
851 _F40 = (u16)(_F40 + 1) % _F42;
852}
853
854void MarioActor::control()
855{
856 if (mSuperKinokoCollected) {
857 if (MR::tryStartDemoWithoutCinemaFrame(this, "マリオスーパー化")) { // 6-up camera
858 mSuperKinokoCollected = false;
859 changeMaxLife(6);
860 MR::stopAnimFrame(this);
861 MR::requestPowerupHPMeter();
862 mMario->startPadVib("マリオ[変身]");
863 MR::startSystemSE("SE_SY_SUPER_KINOKO_GET", -1, -1);
864 _3DA = 0x5a;
865 }
866 }
867 else if (mPowerupCollected) {
868 if (MR::tryStartDemoWithoutCinemaFrame(this, "マリオ変身")) {
869 mPowerupCollected = false;
870 mTransforming = true;
871 if (_3D4 == 6) {
872 MR::requestMovementOn(_9A4);
873 changeTeresaAnimation("change", -1);
874 }
875 _3D8 = 0x40;
876 MR::stopAnimFrame(this);
877 playEffect("変身");
878 mMario->startPadVib("マリオ[変身]");
879 }
880 }
881 control2();
882 _294 = mPosition;
883}
884
885void MarioActor::control2()
886{
887 if ((_3D8 && _3D4) || _3DA) {
888 mMario->_350.zero();
889 mMario->_35C.zero();
890 _7DC = 0;
891 _930 = 0;
892 mVelocity.zero();
893 _264.zero();
894 _270 = mPosition;
895 if (getMovementStates()._1 && !MR::isSameMtx(mMario->_45C->getPrevBaseMtx()->toMtxPtr(), mMario->_45C->getBaseMtx()->toMtxPtr())) {
896 mMario->_130 = mPosition;
897 mMario->checkEnforceMove();
898 mPosition = mMario->_130;
899 }
900 }
901 else {
902 if (_BC4) {
903 _BC4--;
904 }
905 _951 = 0;
906 controlMain();
907 if (!_EA4) {
908 if (!_F44) {
909 MR::offBind(this);
910 }
911 else {
912 MR::onBind(this);
913 }
914 }
915 _978 = mVelocity;
916 if (getDrawStates()._B) {
917 mBinder->_1EC._1 = false;
918 }
919 else {
920 mBinder->_1EC._1 = true;
921 }
922 if (mMario->isDamaging()) {
923 _424 = 0;
924 }
925 }
926}
927
928void MarioActor::controlMain()
929{
930 if (_3C0) {
931 _7DC = 0;
932 _930 = 0;
933 }
934 updateActionTrigger();
935 updateControllerSwing();
936 updateControllerSwingLeft();
937 update2D();
938 if (_A61) {
939 _A6C++;
940 }
941 if (!isEnableMoveMario()) {
942 _7DC = 0;
943 _930 = 0;
944 careMovingObject();
945 }
946 else {
947 mVelocity.zero();
948 updateBehavior();
949 updateRotationInfo();
950 updateTakingPosition();
951 updateSearchLight();
952 updateThrowing();
953 updateBeeWingAnimation();
954 updateFairyStar();
955 _930 = 0;
956 }
957}
958
959void MarioActor::updateBehavior()
960{
961 updateLife();
962 updatePlayerMode();
963 _37C++;
964 if (_EF6) {
965 _EF6--;
966 }
967 if (_3A8) {
968 _3A8--;
969 }
970 if (_3AC) {
971 _3AC--;
972 }
973 _264 = mPosition.translateOpposite(_270);
974 _270 = mPosition;
975 updateBindRatio();
976 updateEffect();
977 if (_B94 && !--_B94) {
978 mMario->stopAnimationUpper("ハンマー投げ回転中", nullptr);
979 mMario->stopAnimation("ハンマー投げ回転中", (const char *)nullptr);
980 }
981 updatePunching();
982 if (!doPressing() && !doStun() && !doRush()) {
983 updateGravityVec(false, false);
984 if (!tryJumpRush()) {
985 checkPriorRushTarget();
986 if (!tryThrow() && !tryStandardRush()) {
987 if (getMovementStates()._1) {
988 initForJump();
989 }
990 updateSwingTimer();
991 updateSwingAction();
992 updateThrowVector();
993 lockOnDPD();
994 if (!checkClapCatchStart()) {
995 _7DC = 0;
996 mMario->Mario::update();
997 updateForCamera();
998 updateTornado();
999 tryCoinPull();
1000 mMario->mDrawStates._1A = true;
1001 }
1002 }
1003 }
1004 }
1005}
1006
1007void MarioActor::updateBindRatio()
1008{
1009 if (!_934 && !MR::isNearZero(_978.translateOpposite(_264), 0.001f)) {
1010 f32 mag = PSVECMag(_978.toCVec());
1011 if (mag / PSVECMag(_978.translateOpposite(_264).toCVec()) < 2.0f) {
1012 _984 += 0.1f;
1013 }
1014 else {
1015 _984 -= 0.1f;
1016 }
1017 }
1018 else if (!MR::isNearZero(_978, 0.001f)) {
1019 _984 -= 0.01f;
1020 }
1021 _984 = MR::clamp(_984, 0.0f, 1.0f);
1022}
1023
1024bool MarioActor::isInPunchTimerRange() const
1025{
1026 bool ret = false;
1027 if (_3E6) {
1028 ret = MR::isInRange(_945, 6.0f, 20.0f);
1029 }
1030 return ret;
1031}
1032
1033void MarioActor::updatePunching()
1034{
1035 if (_944) {
1036 bool canSpinring = true;
1037 _944--;
1038 _945++;
1039 if (!_946 && !getMovementStates()._2B) {
1040 canSpinring = false;
1041 }
1042 if (canSpinring && !mMario->isSwimming() && !_944 && selectAction("スピン回復エフェクト") == true) {
1043 playEffect("スピンリング");
1044 }
1045 bool canPunch = isInPunchTimerRange();
1046 if (!mMario->isSwimming()) {
1047 canPunch = true;
1048 }
1049 if (canPunch) {
1050 const Mario::MovementStates &moveStates = getMovementStates();
1051 if (moveStates._8 || moveStates._1A || moveStates._19) {
1052 mMario->tryWallPunch();
1053 }
1054 }
1055 }
1056 if (mMario->isAnimationRun("ハンマー投げリリース") && mMario->getMovementStates()._1 && !_38C && !mMario->_420 && mMario->Mario::isStickOn()) {
1057 mMario->stopAnimation(nullptr, (const char *)nullptr);
1058 }
1059}
1060
1061bool MarioActor::doRush()
1062{
1063 if (_934) {
1064 tryCoinPull();
1065 tryRushInRush();
1066 if (!_934) {
1067 return false;
1068 }
1069 updateGravityVec(false, false);
1070 if (!checkClapCatchStart() && _7DC) {
1071 bodyClap();
1072 }
1073 _7DC = 0;
1074 _7E2 = false;
1075 mMario->_130 = mPosition;
1076 mMario->updateGroundInfo();
1077 mMario->updateCubeCode();
1078 mMario->decDamageAfterTimer();
1079 if (selectWaterInOutRush(_924)) {
1080 WaterInfo stack_44;
1081 if (!MR::getWaterAreaObj(&stack_44, mPosition)) {
1082 mMario->forceExitSwim();
1083 }
1084 }
1085 else if (!selectWaterInOut(_924->mActor->mName)) {
1086 s32 initial = mMario->mSwim->_144;
1087 mMario->mSwim->checkWaterCube(false);
1088 if ((int)mMario->mSwim->_144 != initial) {
1089 if (mMario->mSwim->_144 <= 1 && (u32)initial - 2 <= 1) {
1090 playEffectRT("水面ジャンプ水柱", mMario->mSwim->_160, mMario->mSwim->_16C);
1091 emitEffectWaterColumn(mMario->mSwim->_160, mMario->mSwim->_16C);
1092 }
1093 else if ((u32)initial <= 1 && mMario->mSwim->_144 - 2 <= 1) {
1094 playEffectRT("水面ジャンプ水柱", -mMario->_328, mMario->mSwim->_16C);
1095 emitEffectWaterColumn(mMario->mSwim->_160, mMario->mSwim->_16C);
1096 }
1097 if (initial == 2) {
1098 _384 = 8;
1099 MR::getGameSceneLayoutHolder().changeLifeMeterModeGround();
1100 mMario->forceExitSwim();
1101 }
1102 else if (initial == 0) {
1103 MR::getGameSceneLayoutHolder().changeLifeMeterModeWater();
1104 }
1105 }
1106 }
1107 if (mMario->isForceStopRush()) {
1108 bool received = _924->receiveMessage(0x95, getSensor("body"));
1109 if (_934 && received) {
1110 RushEndInfo stack_20(nullptr, 4, TVec3f(0.0f, 0.0f, 0.0f), false, 0);
1111 endRush(&stack_20);
1112 }
1113 }
1114 mMarioAnim->setHoming();
1115 updateTornado();
1116 if (_934 && selectRecoverFlyMeter(_924)) {
1117 for (u32 i = 0; i < 4; i++) {
1118 mMario->incAirWalkTimer();
1119 }
1120 }
1121 updateSwingTimer();
1122 return true;
1123 }
1124 else {
1125 _7E2 = false;
1126 return false;
1127 }
1128}
1129
1130void MarioActor::updateSwingTimer()
1131{
1132 if (_934) {
1133 stopSpinTicoEffect(false);
1134 }
1135 else {
1136 if (_948) {
1137 _948--;
1138 }
1139 if (_94C && --_94C == 6) {
1140 _94E = 5;
1141 }
1142 if (_94E && --_94E == 0) {
1143 mMario->startPadVib((unsigned long)0);
1144 mMario->playSound("スピン回復終了", -1);
1145 Color8 stack_8;
1146 stack_8.set(0x50, 0x80, 0xc8, 0);
1147 _1AA = 0xf;
1148 _1AC = 1.5f;
1149 _1B0 = stack_8;
1150 _1B5 = true;
1151 }
1152 if (_946) {
1153 if (--_946 == 0x18) {
1154 selectAction("スピン回復エフェクト");
1155 stopEffectForce("スピンリング");
1156 }
1157 if (_946 == 0xd) {
1158 _94C = 0x13;
1159 }
1160 }
1161 }
1162}
1163
1164void MarioActor::updateSwingAction()
1165{
1166 if (isJumping() && _3D4 != 6 && !mMario->isStatusActive(0x18)) {
1167 _946 = 0;
1168 }
1169 bool requestRush = isRequestRush();
1170 bool requestSpinJump2P = false;
1171 if (!requestRush) {
1172 if (requestRush = isRequestSpinJump2P()) {
1173 requestSpinJump2P = true;
1174 }
1175 }
1176 _1E1 = requestRush;
1177 if (_946) {
1178 if (!requestRush) {
1179 return;
1180 }
1181 if (!isPunching()) {
1182 if (_948) {
1183 _948 += 0x96;
1184 }
1185 else {
1186 _948 += 0x12c;
1187 }
1188 }
1189 if (!requestRush) {
1190 return;
1191 }
1192 tryReleaseBombTeresa();
1193 return;
1194 }
1195 bool canRush = true;
1196 if (!requestRush) {
1197 return;
1198 }
1199 if (mMario->isAnimationRun("壁はじき")) {
1200 canRush = false;
1201 }
1202 if (isJumping() && mMario->_428) {
1203 canRush = false;
1204 }
1205 if (_3D4 == 9) {
1206 canRush = false;
1207 }
1208 if (mMario->getCurrentStatus() == 1) {
1209 canRush = false;
1210 }
1211 if (mMario->isSwimming()) {
1212 canRush = false;
1213 }
1214 if (mMario->isStatusActive(0x18)) {
1215 canRush = false;
1216 }
1217 if (mMario->isStatusActive(0x13)) {
1218 canRush = false;
1219 }
1220 if (_468.x) {
1221 canRush = false;
1222 }
1223 if (mMario->isStatusActive(2)) {
1224 canRush = false;
1225 }
1226 if (_3C0) {
1227 canRush = false;
1228 }
1229 if (_EA4) {
1230 canRush = false;
1231 }
1232 if (!canRush) {
1233 return;
1234 }
1235 u8 action = selectAction("スピンアタック");
1236 switch (action) {
1237 case 1:
1238 bool didSpinPunch = true;
1239 if (!mMario->mMovementStates._F && isJumping() && !mMario->isDamaging() && !mMario->mMovementStates._2B) {
1240 bool tmp = false;
1241 if (_F0C) {
1242 tmp = true;
1243 }
1244 mMario->trySpinJump(tmp);
1245 setPunchHitTimer(0x19);
1246 tryReleaseBombTeresa();
1247 if (requestSpinJump2P) {
1248 MR::start2PJumpAssistSound();
1249 }
1250 }
1251 else if (!getMovementStates()._F && !mMario->isAnimationRun("地上ひねり")) {
1252 const char *pLastAnimationName = mMarioAnim->_10->getCurrentAnimationName();
1253 if (_3D4 == 4) {
1254 if (!mMario->isAnimationRun("ハチスピン")) {
1255 didSpinPunch = trySpinPunch();
1256 }
1257 }
1258 else {
1259 didSpinPunch = trySpinPunch();
1260 }
1261 _974 = 0;
1262 if (pLastAnimationName != mMarioAnim->_10->getCurrentAnimationName()) {
1263 mMario->playSound("パンチ風切り", -1);
1264 }
1265 }
1266 if (_3D4 == 4) {
1267 if (isJumping()) {
1268 if (!mMario->isAnimationRun("ハチスピン空中")) {
1269 mMario->playSound("声スピン", -1);
1270 mMario->playSound("スピンジャンプ", -1);
1271 }
1272 mMario->changeAnimation("ハチスピン空中", (const char *)nullptr);
1273 }
1274 else if (getMovementStates()._A || _9F1) {
1275 mMario->changeAnimation("サマーソルト", (const char *)nullptr);
1276 }
1277 else {
1278 mMario->changeAnimation("ハチスピン", (const char *)nullptr);
1279 }
1280 }
1281 if (didSpinPunch) {
1282 _946 = mConst->_0[mConst->_8]->_426 + 0x22;
1283 }
1284 break;
1285 case 2:
1286 if (isEnableSpinPunch() && !mMario->isSwimming()) {
1287 shootFireBall();
1288 }
1289 break;
1290 case 3:
1291 if (isEnableSpinPunch()) {
1292 doFreezeAttack();
1293 setPunchHitTimer(0x1e);
1294 }
1295 break;
1296 case 4:
1297 if (mMario->_418 != 0) {
1298 break;
1299 }
1300 mMario->startTeresaDisappear();
1301 const Constants *pConstants = mConst->_0[mConst->_8];
1302 _946 = pConstants->_6C8 + pConstants->_426;
1303 break;
1304 case 5:
1305 if (!isEnableSpinPunch()) {
1306 break;
1307 }
1308 if (isJumping()) {
1309 mMario->changeAnimation("ハチスピン空中", (const char *)nullptr);
1310 }
1311 else {
1312 if (getMovementStates()._A || _9F1) {
1313 mMario->changeAnimation("サマーソルト", (const char *)nullptr); // Summersault
1314 }
1315 else {
1316 mMario->changeAnimation("ハチスピン", (const char *)nullptr);
1317 }
1318 }
1319 _946 = mConst->_0[mConst->_8]->_426 + 0x22;
1320 break;
1321 }
1322}
1323
1324void MarioActor::updateRealMtx()
1325{
1326 updateBaseScaleMtx();
1327 getRealMtx(_C2C.toMtxPtr(), "HandL");
1328 getRealMtx(_C5C.toMtxPtr(), "HandR");
1329 PSMTXCopy(MR::getJointMtx(this, "HandL"), _C8C.toMtxPtr());
1330 PSMTXCopy(MR::getJointMtx(this, "HandR"), _CBC.toMtxPtr());
1331 PSMTXCopy(MR::getJointMtx(this, "Face0"), _CEC.toMtxPtr());
1332 getRealMtx(_D1C.toMtxPtr(), "FootR");
1333 getRealMtx(_D4C.toMtxPtr(), "Spine1");
1334 getRealMtx(_D7C.toMtxPtr(), "CapPosition");
1335 getRealMtx(_DAC.toMtxPtr(), "Hip");
1336 getRealMtx(_DDC.toMtxPtr(), "Spine2");
1337 TVec3f stack_50;
1338 MR::extractMtxTrans(_DDC.toMtxPtr(), &stack_50);
1339 if (MR::isNan(stack_50)) {
1340 MR::getJointMtx(this, "Spine2");
1341 getBaseMtx();
1342 }
1343 bool notStatus12 = true;
1344 if (mMario->isStatusActive(0x12)) {
1345 notStatus12 = false;
1346 }
1347 if (!notStatus12) {
1348 return;
1349 }
1350 TVec3f stack_44, stack_38;
1351 MR::extractMtxTrans(_D7C.toMtxPtr(), &stack_44);
1352 MR::extractMtxTrans(_DAC.toMtxPtr(), &stack_38);
1353 _4B8 = stack_44.translateOpposite(stack_38);
1354 _4C4 = stack_38.translateOpposite(stack_44);
1355 if (MR::normalizeOrZero(&_4B8)) {
1356 _4B8 = mMario->_1F0;
1357 }
1358 if (MR::normalizeOrZero(&_4C4)) {
1359 _4C4 = -mMario->_1F0;
1360 }
1361 if (mMario->getMovementStates()._A && mMario->mMovementStates._1) {
1362 _4C4 = -mMario->_1F0;
1363 }
1364 _2AC = stack_44;
1365}
1366
1367void MarioActor::decLife(unsigned short amt)
1368{
1369 if (getMovementStates()._1F) {
1370 return;
1371 }
1372 if (_388 > 0 && amt > _388) {
1373 return;
1374 }
1375 if (amt) {
1376 _388 = amt;
1377 return;
1378 }
1379 if (mHealth) {
1380 mHealth--;
1381 }
1382 _388 = 0;
1383 if (gIsLuigi) {
1384 if (mMaxHealth == 3) {
1385 return;
1386 }
1387 if (mHealth > 3) {
1388 return;
1389 }
1390 mMaxHealth = 3;
1391 return;
1392 }
1393 if (mMaxHealth == 3) {
1394 return;
1395 }
1396 if (mHealth > 3) {
1397 return;
1398 }
1399 mMaxHealth = 3;
1400}
1401
1402void MarioActor::decLifeLarge()
1403{
1404 decLife(0);
1405}
1406
1407void MarioActor::decLifeMiddle()
1408{
1409 decLife(0);
1410}
1411
1412void MarioActor::decLifeSmall()
1413{
1414 decLife(0);
1415}
1416
1417void MarioActor::resetWaterLife()
1418{
1419 _384 = 8;
1420}
1421
1422void MarioActor::updateLife()
1423{
1424 if (!_388) {
1425 return;
1426 }
1427 if (--_388 != 0) {
1428 return;
1429 }
1430 if (!mHealth) {
1431 return;
1432 }
1433 mHealth--;
1434}
1435
1436static const char *sMiddleWaterLifeReduction = "水中ライフ減少";
1437
1438void MarioActor::incLife(unsigned long amt)
1439{
1440 if (isEnableNerveChange() && !_3E4) {
1441 const u32 health = getHealth();
1442 if (mHealth != mMaxHealth) {
1443 mMario->playSound("ライフ回復", -1);
1444 }
1445 mHealth += amt;
1446 if (mHealth >= mMaxHealth) {
1447 mHealth = mMaxHealth;
1448 }
1449 if (health == 1 && mMarioAnim->isAnimationStop()) {
1450 mMarioAnim->_C->changeTrackAnimation(3, "ノーマルウエイト");
1451 if (mMario->_970 && strcmp(mMario->_970, "DamageWait")) {
1452 mMario->startBas(nullptr, false, 0.0f, 0.0f);
1453 setBlink(nullptr);
1454 }
1455 }
1456 }
1457}
1458
1459void MarioActor::changeMaxLife(long max)
1460{
1461 mMaxHealth = max;
1462 while (mHealth != max) {
1463 if (mHealth > max) {
1464 decLife(0);
1465 }
1466 else if (mHealth < max) {
1467 incLife(1);
1468 }
1469 else {
1470 break;
1471 }
1472 }
1473}
1474
1475bool MarioActor::doPressing()
1476{
1477 if (!_390) {
1478 return false;
1479 }
1480 switch (_39C) {
1481 case 0:
1482 if (!mMario->checkVerticalPress(false)) {
1483 if (--_390 == 0x1e && !mHealth && isEnableNerveChange()) {
1484 setNerve(&NrvMarioActor::MarioActorNrvGameOver::sInstance);
1485 }
1486 if (!_390) {
1487 mMario->changeAnimation("つぶれ解除", (const char *)nullptr);
1488 _F44 = true;
1489 }
1490 }
1491 break;
1492 case 2:
1493 case 3:
1494 if (--_390 == 0x1e && !mHealth && isEnableNerveChange()) {
1495 setNerve(&NrvMarioActor::MarioActorNrvGameOver::sInstance);
1496 }
1497 if (!_390) {
1498 mMario->changeAnimation("つぶれ解除", (const char *)nullptr);
1499 _F44 = true;
1500 }
1501 break;
1502 case 4:
1503 if (_390 > 2) {
1504 _390--;
1505 }
1506 mMario->mMovementStates._8 = false;
1507 mMario->mMovementStates._19 = false;
1508 mMario->mMovementStates._1A = false;
1509 break;
1510 }
1511 if (_39C != 1) {
1512 careMovingObject();
1513 }
1514 mMarioAnim->setSpeed(0.0f);
1515 mMario->_350.zero();
1516 mMario->_35C.zero();
1517 resetSensorCount();
1518 return true;
1519}
1520
1521void MarioActor::careMovingObject()
1522{
1523 if (_1E0) {
1524 return;
1525 }
1526 if (getMovementStates()._1 && !MR::isSameMtx(mMario->_45C->getPrevBaseMtx()->toMtxPtr(), mMario->_45C->getBaseMtx()->toMtxPtr())) {
1527 mMario->_130 = mPosition;
1528 mMario->checkEnforceMove();
1529 mPosition = mMario->_130;
1530 }
1531 mMario->_130 = mPosition;
1532 mMario->_160.zero();
1533 mMario->powerAreaMove();
1534 mMario->powerRailMove();
1535 mMario->_130 += mMario->_160;
1536 mMario->_160.zero();
1537 mPosition = mMario->_130;
1538 mMario->checkGround();
1539 mMario->updateFloorCode();
1540}
1541
1542bool MarioActor::doStun()
1543{
1544 if (_38C) {
1545 mMario->mDrawStates._1A = true;
1546 resetSensorCount();
1547 if (getMovementStates()._1 && !MR::isSameMtx(mMario->_45C->getPrevBaseMtx()->toMtxPtr(), mMario->_45C->getBaseMtx()->toMtxPtr())) {
1548 mMario->_130 = mPosition;
1549 mMario->checkEnforceMove();
1550 mPosition = mMario->_130;
1551 }
1552 if (!--_38C) {
1553 f32 stickX, stickY;
1554 getStickValue(&stickX, &stickY);
1555 if (MR::isNearZero(stickX, 0.001f) && MR::isNearZero(stickY, 0.001f) && !getMovementStates()._A) {
1556 mMario->stopWalk();
1557 }
1558 }
1559 mMario->inputStick();
1560 return true;
1561 }
1562 else {
1563 return false;
1564 }
1565}
1566
1567void MarioActor::scaleMtx(MtxPtr rawMtx)
1568{
1569 TVec3f i, j, k;
1570 const TRot3f *pMtx = (TRot3f *)rawMtx;
1571 f32 scalar = 0.35f * (1.0f - _3B0) + 1.0f;
1572 pMtx->getXDir(i);
1573 pMtx->getYDir(j);
1574 pMtx->getZDir(k);
1575 f32 elementX = MR::vecKillElement(i, _3B4, &i);
1576 f32 elementY = MR::vecKillElement(j, _3B4, &j);
1577 f32 elementZ = MR::vecKillElement(k, _3B4, &k);
1578 elementZ *= _3B0;
1579 elementX *= _3B0;
1580 elementY *= _3B0;
1581 i.scale(scalar);
1582 j.scale(scalar);
1583 k.scale(scalar);
1584 i += _3B4 % elementX;
1585 j += _3B4 % elementY;
1586 k += _3B4 % elementZ;
1587 rawMtx[0][0] = i.x;
1588 rawMtx[1][0] = i.y;
1589 rawMtx[2][0] = i.z;
1590 rawMtx[0][1] = j.x;
1591 rawMtx[1][1] = j.y;
1592 rawMtx[2][1] = j.z;
1593 rawMtx[0][2] = k.x;
1594 rawMtx[1][2] = k.y;
1595 rawMtx[2][2] = k.z;
1596}
1597
1598void MarioActor::updateBaseScaleMtx()
1599{
1600 if (mMario->mMovementStates._3C) {
1601 PSMTXScale(_BF8.toMtxPtr(), mScale.x, mScale.y, mScale.z);
1602 }
1603 else {
1604 PSMTXIdentity(_BF8.toMtxPtr());
1605 }
1606}
The basis of a drawable actor that can contain states (see: Nerve)
Definition LiveActor.hpp:24
TVec3f mRotation
3D vector of the actor's rotation.
Definition LiveActor.hpp:96
TVec3f mPosition
3D vector of the actor's position.
Definition LiveActor.hpp:95
TVec3f mScale
3D vector of the actor's scale.
Definition LiveActor.hpp:97
TVec3f mVelocity
3D vector of the actor's velocity.
Definition LiveActor.hpp:98
virtual MtxPtr getBaseMtx() const
Gets the base matrix of the model used for the actor.
HitSensor * getSensor(const char *pSensorName) const
Gets a sensor.
void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
const char * mName
A string to identify the NameObj.
Definition NameObj.hpp:38