SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
PackunPetit.cpp
1#include "Game/Enemy/PackunPetit.hpp"
2#include "Game/LiveActor/ModelObj.hpp"
3#include <JSystem/JMath/JMath.hpp>
4
5PackunPetit::PackunPetit(const char *pName) : LiveActor(pName) {
6 mScaleController = nullptr;
7 mStarPointerState = nullptr;
8 _94.x = 0.0f;
9 _94.y = 0.0f;
10 _94.z = 1.0f;
11 mBlownModel = nullptr;
12 mDontTurn = false;
13}
14
15void PackunPetit::init(const JMapInfoIter &rIter) {
16 MR::initDefaultPos(this, rIter);
17 initModelManagerWithAnm("PackunPetit", nullptr, false);
18 MR::connectToSceneEnemy(this);
19 initHitSensor(3);
20 MR::addHitSensorAtJointMapObj(this, "body", "Head", 8, 90.0f, TVec3f(50.0f, 0.0f, 0.0f));
21 MR::addHitSensorAtJointEnemyAttack(this, "attack", "Head", 8, 50.0f, TVec3f(50.0f, 0.0f, 0.0f));
22 MR::addHitSensorMapObj(this, "stalk", 8, 100.0f, TVec3f(0.0f, 0.0f, 0.0f));
23 initEffectKeeper(2, nullptr, false);
24 MR::addEffectHitNormal(this, nullptr);
25 initSound(4, false);
26 MR::initLightCtrl(this);
27 MR::initShadowFromCSV(this, "Shadow");
28 MR::calcGravity(this);
29 MR::useStageSwitchWriteDead(this, rIter);
30 MR::declareCoin(this, 1);
31 MR::declareStarPiece(this, 6);
32 TVec3f offs;
33 offs.x = 0.0f;
34 offs.y = 0.0f;
35 offs.z = 0.0f;
36 MR::initStarPointerTargetAtJoint(this, "Head", 100.0f, offs);
37 mScaleController = new AnimScaleController(nullptr);
38 mStarPointerState = new WalkerStateBindStarPointer(this, mScaleController);
39 MR::getJMapInfoArg0NoInit(rIter, &mDontTurn);
40 MR::calcFrontVec(&_94, this);
41 initBlowModel();
42 initNerve(&NrvPackunPetit::PackunPetitNrvWait::sInstance);
43 makeActorAppeared();
44}
45
46void PackunPetit::initAfterPlacement() {
47 MR::initEffectAfterPlacement(this);
48}
49
50void PackunPetit::exeNonActive() {
51 if (MR::isFirstStep(this)) {
52 MR::invalidateHitSensors(this);
53 MR::offCalcAnim(this);
54 MR::offCalcShadow(this, "JawA");
55 }
56
57 if (MR::isNearPlayerAnyTime(this, 5000.0f)) {
58 setNerve(&NrvPackunPetit::PackunPetitNrvWait::sInstance);
59 }
60}
61
62void PackunPetit::exeWait() {
63 if (MR::isFirstStep(this)) {
64 MR::startBckWithInterpole(this, "Wait", 60);
65 }
66
67 if (MR::isNearPlayer(this, 1700.0f)) {
68 setNerve(&NrvPackunPetit::PackunPetitNrvFind::sInstance);
69 }
70 else {
71 tryNonActive();
72 }
73}
74
75void PackunPetit::exeFind() {
76 if (MR::isFirstStep(this)) {
77 MR::startBck(this, "Suspect", nullptr);
78 }
79
80 if (MR::isBckStopped(this)) {
81 setNerve(&NrvPackunPetit::PackunPetitNrvThreat::sInstance);
82 }
83}
84
85void PackunPetit::exeThreat() {
86 if (MR::isFirstStep(this)) {
87 MR::startBck(this, "Threat", nullptr);
88 }
89
90 MR::startLevelSound(this, "SE_EM_LV_PACKUNPETIT_THREAT", -1, -1, -1);
91 if (!mDontTurn) {
92 if (tryTurn()) {
93 return;
94 }
95
96 TVec3f* pos = MR::getPlayerPos();
97 MR::turnDirectionToTargetUseGroundNormalDegree(this, &_94, *pos, 2.0f);
98 }
99
100 if (MR::isGreaterStep(this, 50) && MR::isNearPlayer(this, 1100.0f) && (MR::isFaceToPlayerHorizontalDegree(this, _94, 10.0f) || mDontTurn)) {
101 setNerve(&NrvPackunPetit::PackunPetitNrvAttackStart::sInstance);
102 }
103 else if (!MR::isNearPlayer(this, 2000.0f)) {
104 setNerve(&NrvPackunPetit::PackunPetitNrvWait::sInstance);
105 }
106}
107
108void PackunPetit::exeTurn() {
109 if (MR::isFirstStep(this)) {
110 if (isNerve(&NrvPackunPetit::PackunPetitNrvLeftTurn::sInstance)) {
111 MR::startBck(this, "TurnLeft", nullptr);
112 }
113 else {
114 MR::startBck(this, "TurnRight", nullptr);
115 }
116 }
117
118 f32 step = getNerveStep();
119 step = (10.0f - step);
120 if (step < 2.0f) {
121 step = 2.0f;
122 }
123 TVec3f* pos = MR::getPlayerPos();
124 MR::turnDirectionToTargetUseGroundNormalDegree(this, &_94, *pos, step);
125 if (MR::isBckStopped(this)) {
126 setNerve(&NrvPackunPetit::PackunPetitNrvThreat::sInstance);
127 }
128}
129
130void PackunPetit::exeAttackStart() {
131 if (MR::isFirstStep(this)) {
132 MR::startBck(this, "Attack", nullptr);
133 }
134
135 if (MR::isStep(this, 70)) {
136 setNerve(&NrvPackunPetit::PackunPetitNrvAttack::sInstance);
137 }
138}
139
140void PackunPetit::exeHitWaitForAttack() {
141 if (MR::isFirstStep(this) && !MR::isBckPlaying(this, "Attack")) {
142 MR::startBck(this, "Impact", nullptr);
143 }
144
145 if (MR::isBckStopped(this)) {
146 setNerve(&NrvPackunPetit::PackunPetitNrvHit::sInstance);
147 }
148}
149
150void PackunPetit::exeHit() {
151 if (MR::isFirstStep(this)) {
152 MR::startBck(this, "Hit", nullptr);
153 }
154
155 if (MR::isBckStopped(this) && !tryTurn()) {
156 selectNrvWait();
157 }
158}
159
160void PackunPetit::exeTrampleDown() {
161 if (MR::isFirstStep(this)) {
162 MR::startBck(this, "Press", nullptr);
163 MR::startSound(this, "SE_EM_STOMPED_S", -1, -1);
164 MR::invalidateHitSensors(this);
165 }
166
167 if (MR::isBckStopped(this)) {
168 kill();
169 }
170}
171
172void PackunPetit::exePunchDown() {
173 if (MR::isFirstStep(this)) {
174 MR::invalidateHitSensor(this, "body");
175 MR::invalidateHitSensor(this, "attack");
176 mBlownModel->makeActorAppeared();
177 MR::copyJointPos(this, "Head", &mBlownModel->mPosition);
178 MR::startBck(mBlownModel, "BlowHead", nullptr);
179 MR::startBck(this, "Blow", nullptr);
180 MR::startBlowHitSound(this);
181 }
182
183 JMAVECScaleAdd(mGravity.toCVec(), mBlownModel->mVelocity.toCVec(), mBlownModel->mVelocity.toVec(), 2.5f);
184
185 if (!MR::isHiddenModel(mBlownModel) && (MR::isStep(this, 20) || MR::checkStikeBallToMap(mBlownModel->mPosition, 50.0f))) {
186 MR::emitEffect(mBlownModel, "Death");
187 MR::appearStarPiece(this, mBlownModel->mPosition, 3, 10.0f, 40.0f, false);
188 MR::startSound(this, "SE_OJ_STAR_PIECE_BURST", -1, -1);
189 MR::hideModel(mBlownModel);
190 }
191
192 if (MR::isStep(this, 30)) {
193 kill();
194 }
195}
196
197void PackunPetit::exeSwoonStart() {
198 if (MR::isFirstStep(this)) {
199 MR::startBck(this, "SwoonStart", nullptr);
200 }
201
202 if (MR::isBckStopped(this)) {
203 setNerve(&NrvPackunPetit::PackunPetitNrvSwoon::sInstance);
204 }
205}
206
207void PackunPetit::exeSwoon() {
208 if (MR::isFirstStep(this)) {
209 MR::startBck(this, "Swoon", nullptr);
210 }
211
212 MR::startLevelSound(this, "SE_EM_LV_SWOON_S", -1, -1, -1);
213
214 if (MR::isStep(this, 250)) {
215 selectNrvWait();
216 }
217}
218
219void PackunPetit::exeSwoonToThreat() {
220 if (MR::isFirstStep(this)) {
221 MR::startBck(this, "SwoonToThreat", nullptr);
222 }
223
224 if (MR::isBckStopped(this)) {
225 setNerve(&NrvPackunPetit::PackunPetitNrvThreat::sInstance);
226 }
227}
228
229void PackunPetit::exeSwoonOnEnd() {
230 mStarPointerState->kill();
231}
232
233void PackunPetit::exeDPDSwoon() {
234 if (MR::updateActorState(this, mStarPointerState)) {
235 selectNrvWait();
236 }
237}
238
239void PackunPetit::exeAttackBack() {
240 if (MR::isBckStopped(this)) {
241 if (!tryTurn()) {
242 selectNrvWait();
243 }
244 }
245}
246
247void PackunPetit::exeAttack() {
248 if (MR::isStep(this, 0xC)) {
249 setNerve(&NrvPackunPetit::PackunPetitNrvAttackBack::sInstance);
250 }
251}
252
253void PackunPetit::exeNonActiveOnEnd() {
254 MR::validateHitSensors(this);
255 MR::onCalcAnim(this);
256 MR::onCalcShadow(this, "JawA");
257}
258
259void PackunPetit::kill() {
260 if (!MR::isDead(mBlownModel)) {
261 if (!MR::isHiddenModel(mBlownModel)) {
262 MR::emitEffect(mBlownModel, "Death");
263 MR::appearStarPiece(this, mBlownModel->mPosition, 3, 10.0f, 40.0f, false);
264 MR::startSound(mBlownModel, "SE_OJ_STAR_PIECE_BURST", -1, -1);
265 }
266
267 mBlownModel->kill();
268 }
269 else {
270 if (!MR::isValidSwitchDead(this)) {
271 MR::appearCoinPop(this, mPosition, 1);
272 }
273 }
274
275 if (MR::isValidSwitchDead(this)) {
276 MR::onSwitchDead(this);
277 }
278
279 MR::emitEffect(this, "Death");
280 MR::startSound(this, "SE_EM_EXPLODE_S", -1, -1);
281 LiveActor::kill();
282}
283
285 TVec3f up;
286 MR::calcUpVec(&up, this);
287 TPos3f mtxUp;
288 mtxUp.identity();
289 MR::makeMtxUpFrontPos(&mtxUp, up, _94, mPosition);
290 TVec3f mult;
291 mult.multPS(mScale, mScaleController->_C);
292 MR::setBaseScale(this, mult);
293}
294
295void PackunPetit::control() {
296 mScaleController->update();
297 tryDPDSwoon();
298}
299
300/*
301void PackunPetit::attackSensor(HitSensor *a2, HitSensor *a3) {
302 if (MR::isSensorPlayer(a3)) {
303 bool isTrampleOrPunch = false;
304
305 if (isNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance)) {
306 isTrampleOrPunch = true;
307 }
308
309
310 }
311}*/
312
313bool PackunPetit::receiveMsgPlayerAttack(u32 msg, HitSensor *a2, HitSensor *a3) {
314 bool isTrampleOrPunch = false;
315
316 if (isNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance)) {
317 isTrampleOrPunch = true;
318 }
319
320 if (isTrampleOrPunch) {
321 return false;
322 }
323
324 if (MR::isMsgLockOnStarPieceShoot(msg)) {
325 return true;
326 }
327
328 if (MR::isMsgStarPieceAttack(msg)) {
329 setNerve(&NrvPackunPetit::PackunPetitNrvSwoonStart::sInstance);
330 return true;
331 }
332 else {
333 bool isWaitOrHit = false;
334
335 if (isNerve(&NrvPackunPetit::PackunPetitNrvHitWaitForAttack::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvHit::sInstance)) {
336 isWaitOrHit = true;
337 }
338
339 if (isWaitOrHit) {
340 return false;
341 }
342 else if (MR::isMsgInvincibleAttack(msg) || MR::isMsgFireBallAttack(msg)) {
343 punchDown(a2, a3);
344 return true;
345 }
346 else if (isNerve(&NrvPackunPetit::PackunPetitNrvAttack::sInstance)) {
347 return false;
348 }
349 else if (MR::isMsgPlayerTrample(msg)) {
350 MR::tryRumbleDefaultHit(this, 0);
351 setNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance);
352 return true;
353 }
354 else if (MR::isMsgPlayerHipDrop(msg)) {
355 MR::tryRumbleDefaultHit(this, 0);
356 setNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance);
357 return true;
358 }
359 else if (MR::isMsgPlayerHitAll(msg)) {
360 MR::stopSceneForDefaultHit(5);
361 punchDown(a2, a3);
362 return true;
363 }
364
365 return false;
366 }
367}
368
369bool PackunPetit::receiveMsgEnemyAttack(u32 msg, HitSensor *a2, HitSensor *a3) {
370 bool isTrampleOrPunch = false;
371
372 if (isNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance)) {
373 isTrampleOrPunch = true;
374 }
375
376 if (isTrampleOrPunch) {
377 return false;
378 }
379
380 if (MR::isMsgToEnemyAttackBlow(msg)) {
381 punchDown(a2, a3);
382 setNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance);
383 return true;
384 }
385 else if (MR::isMsgToEnemyAttackTrample(msg)) {
386 setNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance);
387 return true;
388 }
389
390 return false;
391}
392
393bool PackunPetit::receiveOtherMsg(u32 msg, HitSensor *a2, HitSensor *a3) {
394 bool isSwoon = false;
395
396 if (isNerve(&NrvPackunPetit::PackunPetitNrvSwoonStart::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvSwoonStart::sInstance)) {
397 isSwoon = true;
398 }
399
400 if (!isSwoon) {
401 return false;
402 }
403
404 if (!MR::isSensorPlayer(a2)) {
405 return false;
406 }
407
408 if (MR::isMsgPlayerKick(msg)) {
409 MR::stopSceneForDefaultHit(5);
410 punchDown(a2, a3);
411 return true;
412 }
413
414 return false;
415}
416
417void PackunPetit::initBlowModel() {
418 mBlownModel = MR::createModelObjMapObjStrongLight("吹っ飛びモデル", "PackunPetitHead", nullptr);
419 mBlownModel->initWithoutIter();
420 MR::initShadowVolumeSphere(mBlownModel, 70.0f);
421 MR::invalidateClipping(mBlownModel);
422 MR::initLightCtrl(mBlownModel);
423 mBlownModel->makeActorDead();
424}
425
426void PackunPetit::punchDown(HitSensor *a1, HitSensor *a2) {
427 TVec3f v6;
428 v6.subtract(a2->mPosition, a1->mPosition);
429 TVec3f* grav = &mGravity;
430 f32 dot = grav->dot(v6);
431 JMAVECScaleAdd(grav->toCVec(), v6.toCVec(), v6.toVec(), -dot);
432 MR::normalize(&v6);
433
434 TVec3f v5;
435 v5.scale(20.0f, v6);
436 JMAVECScaleAdd(mGravity.toCVec(), v5.toCVec(), v5.toVec(), -40.0f);
437 mBlownModel->mVelocity.setInline(v5);
438 setNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance);
439}
440
441void PackunPetit::selectNrvWait() {
442 if (!MR::isNearPlayer(this, 1700.0f)) {
443 setNerve(&NrvPackunPetit::PackunPetitNrvWait::sInstance);
444 }
445 else {
446 if (isNerve(&NrvPackunPetit::PackunPetitNrvSwoon::sInstance)) {
447 setNerve(&NrvPackunPetit::PackunPetitNrvSwoonToThreat::sInstance);
448 }
449 else {
450 setNerve(&NrvPackunPetit::PackunPetitNrvThreat::sInstance);
451 }
452 }
453}
454
455bool PackunPetit::tryNonActive() {
456 if (MR::isNearPlayerAnyTime(this, 5000.0f)) {
457 return false;
458 }
459
460 setNerve(&NrvPackunPetit::PackunPetitNrvNonActive::sInstance);
461 return true;
462}
463
464bool PackunPetit::tryTurn() {
465 if (mDontTurn) {
466 return false;
467 }
468
469 if (MR::isFaceToPlayerHorizontalDegree(this, _94, 90.0f)) {
470 return false;
471 }
472
473 TVec3f* pos = MR::getPlayerPos();
474 TVec3f playerDist;
475 playerDist.subtract(*pos, mPosition);
476 TVec3f sideVec;
477 MR::calcSideVec(&sideVec, this);
478
479 if (playerDist.dot(sideVec) > 0.0f) {
480 setNerve(&NrvPackunPetit::PackunPetitNrvLeftTurn::sInstance);
481 }
482 else {
483 setNerve(&NrvPackunPetit::PackunPetitNrvRightTurn::sInstance);
484 }
485
486 return true;
487}
488
489bool PackunPetit::tryDPDSwoon() {
490 if (isNerve(&NrvPackunPetit::PackunPetitNrvDPDSwoon::sInstance)) {
491 return false;
492 }
493
494 bool isSwoon = false;
495
496 if (isNerve(&NrvPackunPetit::PackunPetitNrvSwoonStart::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvSwoon::sInstance)) {
497 isSwoon = true;
498 }
499
500 if (isSwoon) {
501 return false;
502 }
503
504 bool isTrampleOrPunch = false;
505
506 if (isNerve(&NrvPackunPetit::PackunPetitNrvTrampleDown::sInstance) || isNerve(&NrvPackunPetit::PackunPetitNrvPunchDown::sInstance)) {
507 isTrampleOrPunch = true;
508 }
509
510 if (isTrampleOrPunch) {
511 return false;
512 }
513
514 if (!mStarPointerState->tryStartPointBind()) {
515 return false;
516 }
517
518 setNerve(&NrvPackunPetit::PackunPetitNrvDPDSwoon::sInstance);
519 return true;
520}
521
522PackunPetit::~PackunPetit() {
523
524}
525
526namespace NrvPackunPetit {
527 INIT_NERVE(PackunPetitNrvNonActive);
528 INIT_NERVE(PackunPetitNrvWait);
529 INIT_NERVE(PackunPetitNrvFind);
530 INIT_NERVE(PackunPetitNrvThreat);
531 INIT_NERVE(PackunPetitNrvLeftTurn);
532 INIT_NERVE(PackunPetitNrvRightTurn);
533 INIT_NERVE(PackunPetitNrvAttackStart);
534 INIT_NERVE(PackunPetitNrvAttack);
535 INIT_NERVE(PackunPetitNrvAttackBack);
536 INIT_NERVE(PackunPetitNrvHitWaitForAttack);
537 INIT_NERVE(PackunPetitNrvHit);
538 INIT_NERVE(PackunPetitNrvTrampleDown);
539 INIT_NERVE(PackunPetitNrvPunchDown);
540 INIT_NERVE(PackunPetitNrvSwoonStart);
541 INIT_NERVE(PackunPetitNrvSwoon);
542 INIT_NERVE(PackunPetitNrvSwoonToThreat);
543 INIT_NERVE(PackunPetitNrvDPDSwoon);
544};
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
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
TVec3f mGravity
3D vector of the actor's gravity.
Definition LiveActor.hpp:99
void initWithoutIter()
Initializes a NameObj without a JMapInfoIter instance.
Definition NameObj.cpp:41
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.