NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_a_en_togezo_base.cpp
1#include <game/bases/d_a_en_togezo_base.hpp>
2#include <game/bases/d_a_player.hpp>
4#include <game/mLib/m_allocator_dummy_heap.hpp>
6
7const sBcSensorPoint daEnTogezoBase_c::smc_toge_head = { SENSOR_IS_POINT, 0, 0xc000 };
8const sBcSensorLine daEnTogezoBase_c::smc_toge_foot = { SENSOR_IS_LINE, -0x4000, 0x4000, 0x0 };
9const sBcSensorLine daEnTogezoBase_c::smc_toge_wall = { SENSOR_IS_LINE, 0x7000, 0x5000, 0x8000 };
10
11const sBcSensorLine daEnTogezoBase_c::smc_sakasa_toge_foot = { SENSOR_IS_LINE, -0x3000, 0x2000, 0x0 };
12
13const sBcSensorPoint daEnTogezoBase_c::smc_pipo_head = { SENSOR_IS_POINT, 0, 0x6000 };
14const sBcSensorLine daEnTogezoBase_c::smc_pipo_foot = { SENSOR_IS_LINE, -0x3000, 0x3000, -0x6000 };
15const sBcSensorLine daEnTogezoBase_c::smc_pipo_wall = { SENSOR_IS_LINE, 0x2000, -0x2000, 0x6000 };
16const sCcDatNewF daEnTogezoBase_c::smc_toge_cc = {
17 0.0f, 6.0f,
18 8.0f, 6.0f,
19 CC_KIND_ENEMY,
20 CC_ATTACK_NONE,
21 BIT_FLAG(CC_KIND_PLAYER) | BIT_FLAG(CC_KIND_PLAYER_ATTACK) |
22 BIT_FLAG(CC_KIND_YOSHI) | BIT_FLAG(CC_KIND_ENEMY) |
23 BIT_FLAG(CC_KIND_TAMA),
24 (u32) ~(BIT_FLAG(CC_ATTACK_NONE) | BIT_FLAG(CC_ATTACK_YOSHI_MOUTH) | BIT_FLAG(CC_ATTACK_SPIN_LIFT_UP) | BIT_FLAG(CC_ATTACK_SAND_PILLAR)),
25 CC_STATUS_NONE,
26 dEn_c::normal_collcheck
27};
28
29const float daEnTogezoBase_c::smc_WALK_SPEED_DAT[2] = { 0.5f, -0.5f };
30const s16 daEnTogezoBase_c::smc_ROTATE_SPEED_DAT[2] = { 0x400, -0x400 };
31const s16 daEnTogezoBase_c::smc_ANGLE_Y[2] = { 12000, -12000 };
32
35STATE_DEFINE(daEnTogezoBase_c, Change_Pipo);
36STATE_DEFINE(daEnTogezoBase_c, Change_Togezo);
42
44 createModel();
45
46 createShell("togezo", "g3d/togezo.brres", "togezo_shell", nullptr, 0.0f);
47
48 mVisibleAreaOffset.set(0.0f, 8.0f);
49 mVisibleAreaSize.set(16.0f, 16.0f);
50
51 mActorProperties |= BIT_FLAG(9);
52
53 mCenterOffs.set(0.0f, 6.0f, 0.0f);
54 mSpeedMax.set(0.0f, -4.0f, 0.0f);
55 mScale.set(1.0f, 1.0f, 1.0f);
56
57 mAngle.y = smc_ANGLE_Y[mDirection];
58 mFumiProc.mFumiCheck.m_00 = 8;
59 m_894 = 2;
60
61 initialize();
62
63 return SUCCEEDED;
64}
65
66void daEnTogezoBase_c::createModel() {
67 mAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], 0, 0x20);
68
69 mTogezoResFile = dResMng_c::m_instance->getRes("togezo", "g3d/togezo.brres");
70 nw4r::g3d::ResMdl mdl = mTogezoResFile.GetResMdl("togezo");
71 mTogezoModel.create(mdl, &mAllocator, nw4r::g3d::ScnMdl::BUFFER_RESMATMISC);
72
74
75 nw4r::g3d::ResAnmChr anim = mTogezoResFile.GetResAnmChr("walk");
76 mTogezoAnim.create(mdl, anim, &mAllocator);
77
78 mPaipoResFile = dResMng_c::m_instance->getRes("paipo", "g3d/paipo.brres");
79 nw4r::g3d::ResMdl paipoMdl = mPaipoResFile.GetResMdl("paipo");
80 mPaipoMdl.create(paipoMdl, &mAllocator, nw4r::g3d::ScnMdl::BUFFER_RESMATMISC);
81
83
84 mAllocator.adjustFrmHeap();
85}
86
88 mStateMgr.executeState();
89 if (HasamareBgCheck()) {
90 setDeathInfo_Smoke(nullptr);
91 return SUCCEEDED;
92 }
93
94 if (!mNoRespawn) {
95 if (!isState(StateID_Ice) && checkRyusa()) {
96 ryusaEffect();
97 }
98 }
99
100 if (isCullCheckOk()) {
101 cullCheck();
102 }
103
104 return SUCCEEDED;
105}
106
108 if (mShellMode == SHELL_MODE_PAIPO) {
109 drawPaipo();
110 } else if (mShellMode == SHELL_MODE_BASE) {
111 drawShell();
112 } else {
113 drawTogezo();
114 }
115
116 return SUCCEEDED;
117}
118
119void daEnTogezoBase_c::calcMdl() {
120 calcCatchPos();
121 if (mShellMode == SHELL_MODE_PAIPO) {
122 calcPaipoMdl();
123 } else if (mShellMode == SHELL_MODE_BASE) {
124 calcShellMdl();
125 } else {
126 calcTogezoMdl();
127 }
128}
129
130void daEnTogezoBase_c::calcPaipoMdl() {
131 mVec3_c pos = mPos;
132 mAng3_c angle = mAngle;
133 changePosAngle(&pos, &angle, 1);
134 mMatrix.trans(pos.x, pos.y, pos.z);
135 mMatrix.YrotM(angle.y);
136 mMatrix.XrotM(angle.x);
137 mMatrix.ZrotM(angle.z);
138
139 mPaipoMdl.setLocalMtx(&mMatrix);
140 mPaipoMdl.setScale(mBoyoMng.getScale());
141 mPaipoMdl.calc(false);
142}
143
144void daEnTogezoBase_c::calcTogezoMdl() {
145 mVec3_c pos = mPos;
146 mAng3_c angle = mAngle;
147 changePosAngle(&pos, &angle, 1);
148 mMatrix.trans(pos.x, pos.y, pos.z);
149
150 mMatrix.YrotM(angle.y);
151 mMatrix.ZrotM(angle.z);
152
153 mMatrix.concat(mMtx_c::createTrans(0.0f, 6.0f, 0.0f));
154 mMatrix.XrotM(angle.x);
155 mMatrix.concat(mMtx_c::createTrans(0.0f, -6.0f, 0.0f));
156
157 mTogezoModel.setLocalMtx(&mMatrix);
158 mTogezoModel.setScale(mBoyoMng.getScale());
159 mTogezoModel.calc(false);
160}
161
162void daEnTogezoBase_c::drawTogezo() {
163 mTogezoModel.entry();
164}
165
166void daEnTogezoBase_c::drawPaipo() {
167 mPaipoMdl.entry();
168}
169
171
173 if (mAllocator.mpHeap != mAllocatorDummyHeap_c::getInstance()) {
174 mTogezoAnim.remove();
175 mTogezoModel.remove();
176 mPaipoMdl.remove();
177 }
178 return SUCCEEDED;
179}
180
181void daEnTogezoBase_c::setAfterSleepState() {
182 mSpeed.x = smc_WALK_SPEED_DAT[mDirection];
184}
185
186bool daEnTogezoBase_c::specialFumiProc(dActor_c *actor) {
187 if (mIsFlipped) {
188 return false;
189 }
190 setDamage(actor);
191 return true;
192}
193
194
195bool daEnTogezoBase_c::specialFumiProc_Yoshi(dActor_c *actor) {
196 return !mIsFlipped;
197}
198
199bool daEnTogezoBase_c::checkRyusa() {
200 if (mBc.isFoot()) {
201 mVec3_c center = getCenterPos();
202 u32 unitType = dBc_c::getUnitType(center.x, center.y, mLayer);
203 u32 unitKind = dBc_c::getUnitKind(center.x, center.y, mLayer);
204 u8 v = unitKind >> 16;
205 if (unitType & 0x8000 && v == 3) {
206 return true;
207 }
208 }
209 return false;
210}
211
212void daEnTogezoBase_c::ryusaEffect() {
213 mVec3_c center = getCenterPos();
214 mVec3_c efPos(center.x, center.y, 5500.0f);
215 mLevelEffect.createEffect("Wm_en_quicksand", 0, &efPos, nullptr, nullptr);
216}
217
218bool daEnTogezoBase_c::setPlayerDamage(dActor_c *actor) {
219 dAcPy_c *player = (dAcPy_c *) actor;
220 if (player->setDamage(this, daPlBase_c::DAMAGE_DEFAULT)) {
221 if (mShellMode != SHELL_MODE_BASE) {
222 u8 dir = getTrgToSrcDir_Main(player->getCenterX(), getCenterX());
223 if (mDirection != dir) {
224 mDirection = dir;
225 mAngle.y = smc_ANGLE_Y[mDirection];
226 mSpeed.x = -mSpeed.x;
227 mSpeedMax.x = -mSpeedMax.x;
228 }
229 }
230 return true;
231 }
232
233 return false;
234}
235
236bool daEnTogezoBase_c::turnProc() {
237 mAngle.y += smc_ROTATE_SPEED_DAT[mDirection];
238 s16 target = smc_ANGLE_Y[mDirection];
239 int absTarget = abs(target);
240 int absAngle = abs(mAngle.y);
241 if (absAngle >= absTarget) {
242 mAngle.y = target;
243 return true;
244 }
245 return false;
246}
247
249 calcSpitOutPos(eatingActor);
250 mDirection = eatingActor->mDirection;
251 mPlayerNo = eatingActor->getPlrNo();
252 setSlideThrowSpeed(eatingActor);
253 mIsFlipped = true;
254 reviveCc();
255 mScale.set(1.0f, 1.0f, 1.0f);
256
257 mSensorHead = smc_toge_head;
258 mSensorFootNormal = smc_toge_foot;
259 mSensorWall = smc_toge_wall;
260
261 mCenterOffs.set(0.0f, 6.0f, 0.0f);
263 return true;
264}
265
266bool daEnTogezoBase_c::createIceActor() {
267 const static float cs_offset_tbl[] = {
268 4.0f, 4.0f, 10.0f
269 };
270
271 const static mVec3_c cs_size_tbl[] = {
272 mVec3_c(1.15f, 1.15f, 1.15f),
273 mVec3_c(1.15f, 1.15f, 1.15f),
274 mVec3_c(1.0f, 1.0f, 1.0f)
275 };
276
277 mVec3_c offset(mPos.x, mPos.y - cs_offset_tbl[mShellMode], mPos.z);
278
279 dIceInfo iceInfo[] = {
280 {
281 0,
282 offset,
283 cs_size_tbl[mShellMode]
284 }
285 };
286 return mIceMng.createIce(iceInfo, ARRAY_SIZE(iceInfo));
287}
288
289void daEnTogezoBase_c::pipoRolling() {
290 int rollSpeed = std::fabs(mSpeed.x * 0.5f) * 0x1000;
291 if (rollSpeed > 0x400) {
292 rollSpeed = 0x400;
293 }
294
295 s16 prevSpeed = mPipoRollSpeed;
296 // [This seems wrong, should probably be abs(mPipoRollSpeed) < rollSpeed]
297 if (abs(mPipoRollSpeed) > rollSpeed) {
298 mPipoRollSpeed += 0x20;
299 rollSpeed = prevSpeed;
300 } else {
301 mPipoRollSpeed = 0;
302 }
303
304 mAngle.x += rollSpeed;
305}
306
307void daEnTogezoBase_c::pipoWallBound() {
308 mDirection ^= 1;
309 mAngle.y = smc_ANGLE_Y[mDirection];
310 mSpeedMax.x = -mSpeedMax.x;
311 mSpeed.x = -mSpeed.x;
312}
313
316 if (isBlockHitDeath()) {
318 return;
319 }
320
321 mVec3_c efPos(mVec2_c(mPos.x, mPos.y), 5500.0f);
322 hitdamageEffect(efPos);
323 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN, mPos, 0);
324 mIsFlipped = true;
325 mSpeed.set(l_base_fall_speed_x[mDirection] * 0.5f, 3.5f, 0.0f);
326 mCenterOffs.set(0.0f, 6.0f, 0.0f);
327 if (isState(StateID_Sleep)) {
328 mStateMgr.initializeState();
329 } else {
331 }
332
333 mSensorHead = smc_toge_head;
334 mSensorWall = smc_toge_wall;
335
336 mBc.set(this, smc_sakasa_toge_foot, mSensorHead, mSensorWall);
337}
338
339bool daEnTogezoBase_c::isBlockHitDeath() const {
340 return mShellMode == SHELL_MODE_PAIPO && ACTOR_PARAM(DieOnBlockHit) == 1;
341}
342
343bool daEnTogezoBase_c::isDieShell() {
344 return mShellMode != SHELL_MODE_PAIPO;
345}
346
347void daEnTogezoBase_c::landonEffect(float height) {
348 mVec3_c landPos(mPos.x, mPos.y + height, 5500.0f);
349 u32 unitType = dBc_c::getUnitType(landPos.x, landPos.y - 8.0f, mLayer);
350 u32 unitKind = dBc_c::getUnitKind(landPos.x, landPos.y - 8.0f, mLayer);
351 u32 v = (u8) (unitKind >> 16);
352 u16 footAttr = mBc.getFootAttr();
353 if (footAttr == 12 || unitType & 0x8000 && v == 3) {
354 mEf::createEffect("Wm_en_sndlandsmk_s", 0, &landPos, nullptr, nullptr);
355 } else {
356 mEf::createEffect("Wm_en_landsmoke_s", 0, &landPos, nullptr, nullptr);
357 }
358}
359
360void daEnTogezoBase_c::initializeState_DieFall() {
361 daEnShell_c::initializeState_DieFall();
362 if (mShellMode == SHELL_MODE_PAIPO) {
363 mAngle.y = 0;
364 }
365}
366
367void daEnTogezoBase_c::finalizeState_DieFall() {
368 daEnShell_c::finalizeState_DieFall();
369}
370
371void daEnTogezoBase_c::executeState_DieFall() {
372 const static s16 cs_spin_speed[] = { 0x200, -0x200 };
373
374 if (mShellMode == SHELL_MODE_PAIPO) {
375 s16 xSpeed = smc_DEADFALL_SPINSPEED;
376 s16 ySpeed = cs_spin_speed[mIceDeathDirection];
377 if (mInLiquid) {
378 xSpeed *= smc_WATER_ROLL_DEC_RATE;
379 ySpeed *= smc_WATER_ROLL_DEC_RATE;
380 }
381 mAngle.x += xSpeed;
382 mAngle.y += ySpeed;
383 calcSpeedY();
384 posMove();
385 } else {
386 daEnShell_c::executeState_DieFall();
387 }
388}
389
390void daEnTogezoBase_c::initializeState_Pipo() {
391 mSpeed.x = -1.0f;
392 mShellMode = SHELL_MODE_PAIPO;
393 mCenterOffs.set(0.0f, 0.0f, 0.0f);
394 mCc.mCcData.mBase.mOffset.y = 0.0f;
395 mSpeedMax.y = -4.0f;
396 mMaxFallSpeed = -4.0f;
398}
399
400void daEnTogezoBase_c::finalizeState_Pipo() {
401 mAccelF = 0.0f;
402 mAccelY = -0.1875f;
403}
404
405void daEnTogezoBase_c::executeState_Pipo() {
406 calcSpeedX();
408 posMove();
409 pipoRolling();
410 EnBgCheckFoot();
411 mBc.checkHead(mBc.mFlags);
412 EnBgCheckWall();
413
414 if (mSensorHead.mFlags & BIT_FLAG(31)) {
415 if (mBc.mFlags != 0) {
416 mBc.mFlags = 0;
417 } else {
418 mSensorHead.mFlags &= ~BIT_FLAG(31);
419 mSensorFootNormal.mFlags &= ~BIT_FLAG(31);
420 mSensorWall.mFlags &= ~BIT_FLAG(31);
421 mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall);
422 }
423 }
424 if (mBc.isHead()) {
425 mSpeed.y = 0;
426 }
427 if (mBc.isWall(mDirection)) {
428 pipoWallBound();
429 if (!mBc.isFoot()) {
430 mDirection ^= 1;
431 mSpeed.x *= -0.5f;
432 }
433 }
434 if (mBc.isFoot()) {
435 Bound(0.1875f, 0.875f, 0.5f);
436 if (mSpeed.y > 0.25f) {
437 landonEffect(-8.0f);
438 if (mBc.getFootAttr() == 3) {
439 mSpeed.y = 0.0f;
440 }
441 }
442 if (!mPipoTouchedGround) {
444 dAudio::g_pSndObjEmy->startSound(SE_OBJ_PAIPO_LAND, mPos, 0);
445 mAngle.y = smc_ANGLE_Y[mDirection];
447 } else if (mSpeed.y == 0.0f && mTimer1 == 0) {
448 mAngle.y = smc_ANGLE_Y[mDirection];
450 }
451 } else {
452 // Wait a bit after landing before unrolling.
453 mTimer1 = 12;
454 }
455}
456
457void daEnTogezoBase_c::initializeState_Walk() {
458 if (
459 *mStateMgr.getOldStateID() != StateID_Turn &&
460 *mStateMgr.getOldStateID() != daEnShell_c::StateID_WakeupTurn &&
462 ) {
463 nw4r::g3d::ResAnmChr anm = mTogezoResFile.GetResAnmChr("walk");
465 mTogezoModel.setAnm(mTogezoAnim, 2.0f);
466 mTogezoAnim.setRate(1.0f);
467 }
468 mShellMode = SHELL_MODE_TOGEZO;
469 mAccelY = -0.1875f;
470 mAngle.y = smc_ANGLE_Y[mDirection];
471 mSpeed.x = smc_WALK_SPEED_DAT[mDirection];
472 mSpeed.z = 0.0f;
473 mSpeedMax.y = -4.0f;
475 m_894 = 2;
476}
477
478void daEnTogezoBase_c::finalizeState_Walk() {}
479
480void daEnTogezoBase_c::executeState_Walk() {
481 mTogezoModel.play();
482 if (!mInLiquid) {
483 mAccelY = -0.1875f;
484 mSpeedMax.set(0.0f, -4.0f, 0.0f);
485 }
486 calcSpeedY();
487 posMove();
488 u32 prevFoot = mBc.isFoot();
489 EnBgCheckFoot();
490 mBc.checkHead(mBc.mFlags);
491 EnBgCheckWall();
492
493 if (mBc.isFoot()) {
494 mSpeed.y = 0.0f;
495 if (*mStateMgr.getOldStateID() == StateID_Change_Togezo) {
496 if (!mPipoTouchedGround) {
497 landonEffect(0.0f);
498 }
499 if (mDirection == mPipoDir) {
500 mSpeed.x = smc_WALK_SPEED_DAT[mDirection];
501 } else {
503 return;
504 }
505 }
506 if (dAudio::isBgmAccentSign(1)) {
507 mSpeed.y = 1.85f;
508 }
510 } else if (prevFoot && !mInLiquid && mSpeed.y <= 0.0f) {
511 mFootPush2.x += m_1eb.x;
512 }
513
514 if (mBc.isWall(mDirection)) {
516 }
517}
518
519void daEnTogezoBase_c::initializeState_Turn() {
520 if (*mStateMgr.getOldStateID() == StateID_Wakeup) {
521 nw4r::g3d::ResAnmChr anm = mTogezoResFile.GetResAnmChr("walk");
523 mTogezoModel.setAnm(mTogezoAnim, 2.0f);
524 mTogezoAnim.setRate(1.0f);
525 }
526 mSpeed.x = 0.0f;
527 mSpeed.z = 0.0f;
528 mDirection ^= 1;
529}
530
531void daEnTogezoBase_c::finalizeState_Turn() {}
532
533void daEnTogezoBase_c::executeState_Turn() {
534 mTogezoModel.play();
535 if (!mInLiquid) {
536 mAccelY = -0.1875f;
537 mSpeedMax.set(0.0f, -4.0f, 0.0f);
538 }
539 calcSpeedY();
540 posMove();
541 EnBgCheckFoot();
542 mBc.checkHead(mBc.mFlags);
543 EnBgCheckWall();
544 if (mBc.isFoot()) {
545 if (dAudio::isBgmAccentSign(1)) {
546 mSpeed.y = 1.85f;
547 } else {
548 mSpeed.y = 0.0f;
549 }
550 }
551 if (turnProc()) {
553 }
554}
555
556void daEnTogezoBase_c::initializeState_Change_Pipo() {
557 mChangeTimer = 0x8000;
558 mSpeedMax.x = 0.0f;
559}
560
561void daEnTogezoBase_c::finalizeState_Change_Pipo() {
562 if (mShellMode != SHELL_MODE_PAIPO) {
563 mShellMode = SHELL_MODE_PAIPO;
564 mAngle.y = smc_ANGLE_Y[mDirection];
565
566 mSensorHead = smc_pipo_head;
567 mSensorFootNormal = smc_pipo_foot;
568 mSensorWall = smc_pipo_wall;
569
570 mCc.mCcData.mBase.mSize.x = 6.0f;
571 }
572 mAccelF = 0.0f;
573}
574
575void daEnTogezoBase_c::executeState_Change_Pipo() {
576 calcSpeedX();
578 posMove();
579 EnBgCheckFoot();
580 mBc.checkHead(mBc.mFlags);
581 EnBgCheckWall();
582 Bound(0.1875f, 1.0f, 0.5f);
583 if (mBc.isHead()) {
584 mSpeed.y = 0.0f;
585 }
586 if (mBc.isWall()) {
587 pipoWallBound();
588 }
589 mAngle.x = (u16) mAngle.x.mAngle - 0x800; // [fake match]
590 mChangeTimer -= 0x800;
591 if (mChangeTimer == 0) {
593 }
594}
595
596void daEnTogezoBase_c::initializeState_Change_Togezo() {
597 mIsFlipped = false;
598 mSpeed.y = 2.0f;
599 mAngle.x = -0x8000;
600 mChangeTimer = 0x8000;
601 mSpeedMax.x = 0.0f;
602 mMaxFallSpeed = -4.0f;
603 mShellMode = SHELL_MODE_TOGEZO;
604 dAudio::g_pSndObjEmy->startSound(SE_OBJ_PAIPO_TO_TOGEZO, mPos, 0);
605
606 mSensorHead = smc_toge_head;
607 mSensorFootNormal = smc_toge_foot;
608 mSensorWall = smc_toge_wall;
609
610 mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall);
611
612 mCc.mCcData.mBase.mOffset.y = 6.0f;
613 mCc.mCcData.mBase.mSize.x = 8.0f;
614}
615
616void daEnTogezoBase_c::finalizeState_Change_Togezo() {
617 mCenterOffs.set(0.0f, 6.0f, 0.0f);
618 mAccelF = 0.0f;
619}
620
621void daEnTogezoBase_c::executeState_Change_Togezo() {
623 posMove();
624 EnBgCheckFoot();
625 mBc.checkHead(mBc.mFlags);
626 EnBgCheckWall();
627 Bound(0.1875f, 1.0f, 0.5f);
628
629 if (mBc.isHead()) {
630 mSpeed.y = 0.0f;
631 }
632 if (mBc.isFoot()) {
633 mSpeed.y = 0.0f;
634 }
635 if (mBc.isWall()) {
636 pipoWallBound();
637 }
638
639 mAngle.x = (u16) mAngle.x.mAngle + 0xc00; // [fake match]
640 mChangeTimer -= 0xc00;
641 if (mChangeTimer > 0x8000) {
643 }
644}
645
646void daEnTogezoBase_c::initializeState_Wakeup() {
647 mShellMode = SHELL_MODE_TOGEZO;
648 daEnShell_c::initializeState_Wakeup();
649}
650
651void daEnTogezoBase_c::finalizeState_Wakeup() {
652 daEnShell_c::finalizeState_Wakeup();
653}
654
655void daEnTogezoBase_c::executeState_Wakeup() {
656 mTogezoModel.play();
657 daEnShell_c::executeState_Wakeup();
658}
659
660void daEnTogezoBase_c::initializeState_WakeupTurn() {
661 nw4r::g3d::ResAnmChr anm = mTogezoResFile.GetResAnmChr("walk");
663 mTogezoModel.setAnm(mTogezoAnim, 2.0f);
664 mTogezoAnim.setRate(1.0f);
665 daEnShell_c::initializeState_WakeupTurn();
666}
667
668void daEnTogezoBase_c::finalizeState_WakeupTurn() {
669 daEnShell_c::finalizeState_WakeupTurn();
670}
671
672void daEnTogezoBase_c::executeState_WakeupTurn() {
673 mTogezoModel.play();
674 daEnShell_c::executeState_WakeupTurn();
675}
676
677void daEnTogezoBase_c::initializeState_WakeupReverse() {
678 nw4r::g3d::ResAnmChr anm = mTogezoResFile.GetResAnmChr("walk");
680 mTogezoModel.setAnm(mTogezoAnim, 2.0f);
681 mTogezoAnim.setRate(1.0f);
682
683 mShellMode = SHELL_MODE_TOGEZO;
684 mSpeed.set(0.0f, 2.5f, 0.0);
686
687 mSensorFootNormal = smc_toge_foot;
688 mSensorHead = smc_toge_head;
689 mSensorWall = smc_toge_wall;
690
691 mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall);
692
693 m_23b = 1;
694}
695
696void daEnTogezoBase_c::finalizeState_WakeupReverse() {}
697
698void daEnTogezoBase_c::executeState_WakeupReverse() {
699 mTogezoModel.play();
700 calcSpeedY();
701 posMove();
702 EnBgCheckFoot();
703 mBc.checkHead(mBc.mFlags);
704 EnBgCheckWall();
705
706 bool isFoot = false;
707 if (mBc.isFoot()) {
708 mSpeed.y = 0.0f;
709 isFoot = true;
710 }
711
712 bool limitReached = false;
713 if (mAngle.y > smc_ANGLE_Y[mDirection]) {
714 mAngle.y -= 0x400;
715 if (mAngle.y <= smc_ANGLE_Y[mDirection]) {
716 mAngle.y = smc_ANGLE_Y[mDirection];
717 limitReached = true;
718 }
719 } else if (mAngle.y < smc_ANGLE_Y[mDirection]) {
720 mAngle.y += 0x400;
721 if (mAngle.y >= smc_ANGLE_Y[mDirection]) {
722 mAngle.y = smc_ANGLE_Y[mDirection];
723 limitReached = true;
724 }
725 } else {
726 limitReached = true;
727 }
728
729 switch (m_23b) {
730 case 1: {
731 s16 prevAngle = mAngle.x;
732 mAngle.x += 0xc00;
733 if (prevAngle < 0 && mAngle.x >= 0) {
734 mAngle.x = 0;
735 m_23b = 2;
736 }
737 break;
738 }
739 case 2:
740 if (isFoot && limitReached) {
741 mIsFlipped = false;
743 }
744 break;
745 }
746}
bool isState(const sStateIDIf_c &other) const
Checks if the actor is currently in the given state.
sFStateStateMgr_c< dActorMultiState_c, sStateMethodUsr_FI_c, sStateMethodUsr_FI_c > mStateMgr
The state manager.
The minimum required implementation for a stage actor.
Definition d_actor.hpp:15
virtual s8 & getPlrNo()
Gets the player number associated with the actor. See mPlayerNo.
Definition d_actor.hpp:105
bool mNoRespawn
Whether the actor should not respawn after being deleted.
Definition d_actor.hpp:378
virtual void reviveCc()
Enables the actor's collision.
Definition d_actor.cpp:804
bool HasamareBgCheck()
Returns whether the actor is colliding with any enabled collision sides.
Definition d_actor.cpp:457
dBc_c mBc
The actor-to-tile collision sensor.
Definition d_actor.hpp:342
static bool getTrgToSrcDir_Main(float trgX, float srcX)
See getTrgToSrcDirFunc.
Definition d_actor.cpp:276
static void setSoftLight_Enemy(m3d::bmdl_c &mdl)
Sets the soft light effect for enemies.
Definition d_actor.cpp:325
mVec2_c m_1eb
Definition d_actor.hpp:345
static void changePosAngle(mVec3_c *pos, mAng3_c *ang, int param3)
Adjusts the actor's position to account for looping stages.
Definition d_actor.cpp:297
u8 mDirection
The actor's facing direction.
Definition d_actor.hpp:351
dCc_c mCc
The actor-to-actor collision sensor.
Definition d_actor.hpp:341
mVec2_c mVisibleAreaSize
The size of the area inside which the actor is visible.
Definition d_actor.hpp:347
s8 mPlayerNo
The player associated with the actor, -1 if not associated to any player.
Definition d_actor.hpp:375
int m_23b
Definition d_actor.hpp:360
virtual void calcSpitOutPos(dActor_c *eatingActor)
Calculates the position where the actor will be spat out.
Definition d_actor.cpp:651
u8 mLayer
The actor's layer.
Definition d_actor.hpp:377
mVec2_c mVisibleAreaOffset
The offset applied to the area size.
Definition d_actor.hpp:348
mMtx_c mMatrix
The actor's partial transformation matrix. See makeMtx() for details.
mVec3_c mScale
The actor's scale (defaults to 1).
float mAccelF
The actor's horizontal acceleration.
mVec3_c mSpeed
The actor's speed.
mVec3_c mPos
The actor's position.
mVec3_c mSpeedMax
The actor's maximum speed.
void calcSpeedX()
Updates the actor's X speed. See here for details.
mVec3_c mCenterOffs
The offset from the position to the center of the actor (defaults to 0).
void calcFallSpeed()
Updates the actor's falling speed. See here for details.
void posMove()
Moves the actor by its speed.
float mMaxFallSpeed
The actor's maximum fall speed.
mVec3_c getCenterPos() const
Gets the actor's centered position.
mAng3_c mAngle
The actor's rotation (for 2D actors).
u32 mActorProperties
The actor's properties. See fProfile::fActorProfile_c::mActorProperties.
float mAccelY
The actor's vertical acceleration.
void calcSpeedY()
Updates the actor's Y speed. See here for details.
bool getPl_LRflag(const mVec3_c &pos)
Checks whether the nearest player is to the left of pos.
Definition d_enemy.cpp:398
u8 mDeathFallDirection
The X direction to move towards on death.
Definition d_enemy.hpp:276
u8 mIceDeathDirection
The X direction to move towards on ice death.
Definition d_enemy.hpp:277
dIceMng_c mIceMng
The ice manager for this enemy.
Definition d_enemy.hpp:285
u16 mTimer1
[Used in EN_HATENA_BALLON, for example]
Definition d_enemy.hpp:290
virtual void changeState(const sStateIDIf_c &newState)
Changes the actor's state to the given state.
virtual void block_hit_init()
Callback for when a block directly beneath the actor is hit.
Definition d_enemy.cpp:1005
bool mInLiquid
Whether the enemy is in a liquid.
Definition d_enemy.hpp:281
static dResMng_c * m_instance
The instance of this class.
Definition d_res_mng.hpp:61
bool mIsFlipped
Whether the shell is flipped upside down from a block hit.
static sFStateVirtualID_c< daEnShell_c > StateID_Slide
Sliding across the ground after being kicked.
static sFStateVirtualID_c< daEnShell_c > StateID_WakeupReverse
Waking up after being flipped upside down.
static sFStateVirtualID_c< daEnShell_c > StateID_Sleep
Remaining stationary after being jumped on.
void createShell(const char *arcName, const char *resPath, const char *modelName, const char *anmTexName, float animFrame)
Loads the resources for the shell model and animation.
static sFStateVirtualID_c< daEnShell_c > StateID_WakeupTurn
Turning around after waking up.
Base class for spinys.
nw4r::g3d::ResFile mTogezoResFile
The resource file for the spiny.
m3d::anmChr_c mTogezoAnim
The spiny's animation.
u32 mChangeTimer
Timer used for transforming between spiny and rolled up spiny.
u32 mPipoTouchedGround
Whether the rolled up spiny has touched the ground since rolling up.
virtual int doDelete()
do method for the delete operation.
virtual void deleteReady()
Informs the base that it's about to be deleted.
virtual int draw()
do method for the draw operation.
static sFStateID_c< daEnTogezoBase_c > StateID_Walk
Walking on the ground.
virtual int create()
do method for the create operation.
m3d::smdl_c mPaipoMdl
The model for the rolled up spiny.
virtual void block_hit_init()
Callback for when a block directly beneath the actor is hit.
static sFStateID_c< daEnTogezoBase_c > StateID_Change_Togezo
Transforming into a regular spiny.
static sFStateID_c< daEnTogezoBase_c > StateID_Pipo
Rolled up in a ball.
virtual int execute()
do method for the execute operation.
nw4r::g3d::ResFile mPaipoResFile
The resource file for the rolled up spiny.
dHeapAllocator_c mAllocator
The allocator used for the resources of this actor.
virtual bool setEatSpitOut(dActor_c *eatingActor)
Callback for when the actor is about to be spat out.
s16 mPipoRollSpeed
The speed at which the spiny unrolls.
m3d::mdl_c mTogezoModel
The spiny model.
u8 mPipoDir
The direction the rolled up spiny is moving. Used to determine if the spiny should turn around when i...
static sFStateID_c< daEnTogezoBase_c > StateID_Turn
Turning around while walking.
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:46
mAng y
The rotation on the Y axis.
Definition m_angle.hpp:126
mAng z
The rotation on the Z axis.
Definition m_angle.hpp:127
mAng x
The rotation on the X axis.
Definition m_angle.hpp:125
A two-dimensional floating point vector.
Definition m_vec.hpp:26
A three-dimensional floating point vector.
Definition m_vec.hpp:122
@ FORWARD_LOOP
Play the animation forward in a loop.
Definition banm.hpp:8
@ GAME_HEAP_DEFAULT
The default game heap (alias of MEM1 or MEM2).
Definition m_heap.hpp:38
EGG::ExpHeap * g_gameHeaps[GAME_HEAP_COUNT]
The game heaps.
Definition m_heap.cpp:13
#define STATE_DEFINE(class, name)
Defines a state.
Definition s_State.hpp:36
#define STATE_VIRTUAL_DEFINE(class, name)
Defines a virtual state.
Definition s_State.hpp:46
A structure that contains information about a collider.
Definition d_cc.hpp:98