SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
NoteFairy.cpp
1#include "Game/MapObj/NoteFairy.hpp"
2#include "Game/MapObj/Note.hpp"
3#include "Game/Scene/SceneObjHolder.hpp"
4#include "Game/Screen/NoteCounter.hpp"
5
6NoteFairy::NoteFairy(const char *pName) : LiveActor(pName) {
7 _8C.x = 0.0f;
8 _8C.y = 0.0f;
9 _8C.z = 0.0f;
10 _98.x = 0.0f;
11 _98.y = 0.0f;
12 _98.z = 0.0f;
13 mAppearanceSpeed = 13.0f;
14 mTimeLimit = 20;
15 mMelodyNoteNum = 0;
16 _B0 = 0;
17 mSong = -1;
18 mCompletionJingle = -1;
19 mNoteCoord = 150.0f;
20 mNoteArray = nullptr;
21 mLastGotNote = nullptr;
22 mAppearanceType = -1;
23 _CC = false;
24 _CD = false;
25 mHasDemo = false;
26 _CF = false;
27 _D0 = false;
28 _D1 = false;
29 mPowerStarSpawnType = -1;
30 mCameraInfo = nullptr;
31}
32
33void NoteFairy::init(const JMapInfoIter &rIter) {
34 MR::initDefaultPos(this, rIter);
35 s32 noteNum = -1;
36 MR::getJMapInfoArg0WithInit(rIter, &noteNum);
37 MR::getJMapInfoArg1NoInit(rIter, &mAppearanceSpeed);
38 MR::getJMapInfoArg2NoInit(rIter, &mTimeLimit);
39 mAppearanceType = -1;
40 MR::getJMapInfoArg3WithInit(rIter, &mAppearanceType);
41
42 switch (mAppearanceType) {
43 case -1: break;
44 case 1: break;
45 case 3: _CC = 1; break;
46 case 5: _CD = 1; break;
47 case 6: _CD = 1; _D0 = 1; break;
48 }
49
50 MR::getJMapInfoArg4WithInit(rIter, &mSong);
51 MR::getJMapInfoArg5WithInit(rIter, &mCompletionJingle);
52 s32 arg6;
53 MR::getJMapInfoArg6WithInit(rIter, &arg6);
54
55 if (arg6 > 0) {
56 _CF = false;
57 }
58 else {
59 _CF = true;
60 }
61
62 s32 powerStarType = 0;
63 MR::getJMapInfoArg7NoInit(rIter, &powerStarType);
64
65 if (powerStarType != 0) {
66 MR::declarePowerStar(this);
67
68 if (powerStarType == 2) {
69 mPowerStarSpawnType = 1;
70 }
71 else if (powerStarType == 3) {
72 mPowerStarSpawnType = 2;
73 }
74 else {
75 mPowerStarSpawnType = 0;
76 }
77 }
78
79 _8C.set(mPosition);
80 mTimeLimit *= 60;
81 mHasDemo = MR::tryRegisterDemoCast(this, rIter);
82 initRailRider(rIter);
83 initModelManagerWithAnm("Note", nullptr, false);
84 MR::startBrk(this, "Note");
85 MR::connectToSceneNoSilhouettedMapObjStrongLight(this);
86 initEffectKeeper(0, "NoteFairy", false);
87 initSound(6, false);
88 MR::initShadowVolumeSphere(this, 50.0f);
89 s32 railArg = -1;
90 MR::getRailArg0WithInit(this, &railArg);
91
92 if (noteNum > 0) {
93 if (mSong < 0) {
94 mMelodyNoteNum = noteNum;
95 }
96 else {
97 mMelodyNoteNum = MR::getRemixMelodyNoteNum(mSong);
98 }
99
100 mNoteCoord = MR::getRailTotalLength(this) / mMelodyNoteNum;
101 }
102 else {
103 if (noteNum == -2) {
104
105 s32 pointNum = MR::getRailPointNum(this);
106 if (mSong < 0) {
107 mMelodyNoteNum = pointNum;
108 }
109 else {
110 mMelodyNoteNum = MR::getRemixMelodyNoteNum(mSong);
111 }
112
113 if (railArg < 0) {
114 mNoteCoord = 200.0f;
115 }
116 else {
117 mNoteCoord = railArg;
118 }
119
120 _D1 = true;
121 }
122 else {
123 if (mSong < 0) {
124 mMelodyNoteNum = MR::getRailTotalLength(this) / mNoteCoord;
125 }
126 else {
127 mMelodyNoteNum = MR::getRemixMelodyNoteNum(mSong);
128 mNoteCoord = MR::getRailTotalLength(this) / mMelodyNoteNum;
129 }
130 }
131 }
132
133 mNoteArray = new Note*[mMelodyNoteNum];
134
135 for (s32 i = 0; i < mMelodyNoteNum; i++) {
136 TVec3f stack_24;
137
138 if (_D1) {
139 MR::calcRailPointPos(&stack_24, this, i);
140 }
141 else {
142 stack_24.set(MR::getRailPos(this));
143 MR::moveCoord(this, mNoteCoord);
144 }
145
146 mNoteArray[i] = new Note("音符", MR::getRailDirection(this), this);
147 mNoteArray[i]->mPosition.set(stack_24);
148 mNoteArray[i]->initWithoutIter();
149 mNoteArray[i]->mCounter = mTimeLimit;
150 }
151
152 MR::moveCoordToStartPos(this);
153 MR::setRailCoord(this, 0.0f);
154 TVec3f stack_18(MR::getRailDirection(this));
155 stack_18.y = 0.0f;
156 MR::normalizeOrZero(&stack_18);
157 stack_18.x *= -800.0f;
158 stack_18.y *= -800.0f;
159 stack_18.z *= -800.0f;
160 _98.x = stack_18.x + mPosition.x;
161 _98.y = (0.5f * mPosition.y) + (0.5f * MR::getRailPos(this).y);
162 _98.z = stack_18.z + mPosition.z;
163 MR::needStageSwitchReadAppear(this, rIter);
164 MR::useStageSwitchWriteA(this, rIter);
165 MR::useStageSwitchReadB(this, rIter);
166 MR::initActorCamera(this, rIter, &mCameraInfo);
167 initNerve(&NrvNoteFairy::NoteFairyNrvHide::sInstance);
168 makeActorAppeared();
169}
170
171void NoteFairy::control() {
172 if (!isNerve(&NrvNoteFairy::NoteFairyNrvHide::sInstance) && MR::isValidSwitchB(this) && !MR::isOnSwitchB(this)) {
173 kill();
174 }
175 else if (MR::isPowerStarGetDemoActive()) {
176 kill();
177 }
178}
179
180void NoteFairy::kill() {
181 if (_CF) {
182 MR::moveVolumeStageBGMForNoteFairy(1.0f, 120);
183 }
184
185 killAllNotes();
186 LiveActor::kill();
187}
188
189void NoteFairy::killAllNotes() {
190 for (s32 i = 0; i < mMelodyNoteNum; i++) {
191 mNoteArray[i]->kill();
192 }
193}
194
195void NoteFairy::exeHide() {
196 if (MR::isFirstStep(this)) {
197 MR::hideModel(this);
198 MR::invalidateClipping(this);
199 }
200
201 if (MR::isOnSwitchAppear(this)) {
202 if (!_D0) {
203 MR::startSystemSE("SE_SY_READ_RIDDLE_S", -1, -1);
204 }
205
206 MR::invalidateClipping(this);
207
208 if (_CF) {
209 MR::moveVolumeStageBGMForNoteFairy(0.0f, 30);
210 }
211
212 switch(mAppearanceType) {
213 case 1:
214 case 2:
215 case 3:
216 setNerve(&NrvNoteFairy::NoteFairyNrvStartAppearDemo::sInstance);
217 return;
218 case 4:
219 case 5:
220 case 6:
221 setNerve(&NrvNoteFairy::NoteFairyNrvRailMoveStart::sInstance);
222 return;
223 }
224
225 setNerve(&NrvNoteFairy::NoteFairyNrvAppearNote::sInstance);
226 }
227}
228
229void NoteFairy::exeStartAppearDemo() {
230 if (MR::isFirstStep(this)) {
231 MR::showModel(this);
232 MR::emitEffect(this, "Blur");
233 }
234
235 if (MR::isStep(this, 30)) {
236 TVec3f* pos = MR::getPlayerPos();
237 TVec3f stack_8(_8C);
238 stack_8.subInline(*pos);
239 MR::setPlayerFrontVec(stack_8, 1);
240 enterDemoAppear(&NrvNoteFairy::NoteFairyNrvDemoAppear::sInstance, true);
241 }
242}
243
244void NoteFairy::exeRailMoveStart() {
245 if (MR::isFirstStep(this)) {
246 MR::showModel(this);
247 MR::emitEffect(this, "Blur");
248 mPosition.setInlinePS(MR::getRailPos(this));
249 }
250
251 if (_CD) {
252 setNerve(&NrvNoteFairy::NoteFairyNrvAppearNoteBloom::sInstance);
253 }
254 else if (MR::isStep(this, 0)) {
255 enterDemoAppear(&NrvNoteFairy::NoteFairyNrvAppearNoteBloom::sInstance, false);
256 }
257}
258
259void NoteFairy::exeDemoAppear() {
260 if (MR::isFirstStep(this)) {
261 MR::emitEffect(this, "Blur");
262 }
263
264 if (MR::isLessEqualStep(this, 60)) {
265 f32 ease = MR::getEaseOutValue(getNerveStep() / 60.0f, 0.0f, 1.0f, 1.0f);
266 mPosition.x = (_8C.x * (1.0f - ease)) + (_98.x * ease);
267 mPosition.y = (((_8C.y * (1.0f - ease)) + (_98.y * ease)) - (300.0f * MR::sinDegree(180.0f * ease)));
268 mPosition.z = (_8C.z * (1.0f - ease)) + (_98.z * ease);
269 }
270
271 if (MR::isGreaterStep(this, 70)) {
272 f32 ease = MR::getEaseInValue(getNerveStep() / 60.0f, 0.0f, 1.0f, 1.0f);
273 mPosition.x = (_98.x * (1.0f - ease)) + (ease * MR::getRailPos(this).x);
274 mPosition.y = _98.y - (MR::sinDegree(90.0f * ease) * (_98.y - MR::getRailPos(this).y));
275 mPosition.z = (_98.z * (1.0f - ease)) + (ease * MR::getRailPos(this).z);
276 }
277
278 MR::startLevelSound(this, "SE_OJ_LV_FLOWER_FAIRY_MOVE", -1, -1, -1);
279 mRotation.y = MR::getSceneObj<NoteGroup*>(SceneObj_NoteGroup)->mRotation;
280
281 if (MR::isStep(this, 130)) {
282 setNerve(&NrvNoteFairy::NoteFairyNrvAppearNoteBloom::sInstance);
283 }
284}
285
286void NoteFairy::exeAppearNoteBloom() {
287 if (MR::isFirstStep(this)) {
288 mVelocity.zero();
289 MR::declareNoteNumMaxAndMelodyToCounter(this, mMelodyNoteNum, mSong, mNoteCoord);
290 }
291
292 if (!_CC && !_CD && MR::isStep(this, 60) && mAppearanceType != -1) {
293 MR::endDemo(this, "出現");
294 MR::endActorCamera(this, mCameraInfo, false, -1);
295 }
296
297 MR::startLevelSound(this, "SE_OJ_LV_FLOWER_FAIRY_MOVE", -1, -1, -1);
298 MR::moveCoordAndFollowTrans(this, mAppearanceSpeed);
299 mRotation.y = MR::getSceneObj<NoteGroup*>(SceneObj_NoteGroup)->mRotation;
300
301 while (_B0 >= mMelodyNoteNum && MR::getRailCoord(this) >= getNoteCoord(_B0)) {
302 mNoteArray[_B0]->appear();
303 mNoteArray[_B0]->_AC = 5.0f * _B0;
304
305 if (MR::isLessStep(this, 60) && mAppearanceType != -1) {
306 MR::requestMovementOn(mNoteArray[_B0]);
307 }
308
309 _B0++;
310 }
311
312 if (_B0 >= mMelodyNoteNum) {
313 if (_CC) {
314 MR::endDemo(this, "出現");
315 MR::endActorCamera(this, mCameraInfo, false, -1);
316 }
317
318 MR::hideModel(this);
319 MR::deleteEffect(this, "Blur");
320 setNerve(&NrvNoteFairy::NoteFairyNrvEndWait::sInstance);
321 }
322}
323
324void NoteFairy::exeAppearNote() {
325 if (MR::isFirstStep(this)) {
326 mVelocity.zero();
327 MR::declareNoteNumMaxAndMelodyToCounter(this, mMelodyNoteNum, mSong, mNoteCoord);
328
329 for (s32 i = 0; i < mMelodyNoteNum; i++) {
330 mNoteArray[i]->appear();
331 mNoteArray[i]->_AC = 5.0f * i;
332 }
333
334 setNerve(&NrvNoteFairy::NoteFairyNrvEndWait::sInstance);
335 }
336}
337
338void NoteFairy::exeEndWait() {
339 if (MR::isFirstStep(this)) {
340 for (s32 i = 0; i < mMelodyNoteNum; i++) {
341 mNoteArray[i]->startCountDown();
342 }
343 }
344
345 MR::startLevelSound(this, "SE_SY_NO_SOUND_FANFARE", -1, -1, -1);
346 s32 timeLeft = mTimeLimit - getNerveStep();
347 if (timeLeft <= 170) {
348 MR::startSystemLevelSE("SE_RS_LV_NOTE_TIMER_FAST", 0, -1);
349 }
350 else {
351 if (timeLeft <= mTimeLimit / 2) {
352 MR::startSystemLevelSE("SE_RS_LV_NOTE_TIMER_MIDDLE", 30, -1);
353 }
354 else {
355 MR::startSystemLevelSE("SE_RS_LV_NOTE_TIMER_SLOW", 85, -1);
356 }
357 }
358
359 if (isDeadAllNotes()) {
360 kill();
361 }
362}
363
364void NoteFairy::exeSuccessDemo() {
365 if (MR::isFirstStep(this)) {
366 MR::tryStartDemoRegistered(this, nullptr);
367 }
368
369 if (!MR::isTimeKeepDemoActive()) {
370 setNerve(&NrvNoteFairy::NoteFairyNrvSuccess::sInstance);
371 }
372}
373
374void NoteFairy::exeSuccess() {
375 if (MR::isFirstStep(this)) {
376 if (MR::isValidSwitchA(this)) {
377 MR::onSwitchA(this);
378 }
379
380 switch (mPowerStarSpawnType) {
381 case 1:
382 MR::requestAppearPowerStar(this, mLastGotNote->mPosition);
383 break;
384 case 2:
385 MR::requestAppearPowerStar(this, mLastGotNote->mPosition);
386 break;
387 case 0:
388 MR::requestAppearPowerStar(this, _8C);
389 break;
390 }
391
392 setNerve(&NrvNoteFairy::NoteFairyNrvEndWait::sInstance);
393 }
394}
395
396void NoteFairy::enterDemoAppear(const Nerve *pNerve, bool hasNoFrame) {
397 MR::startActorCameraTargetSelf(this, mCameraInfo, -1);
398
399 if (hasNoFrame) {
400 MR::requestStartDemo(this, "出現", pNerve, nullptr);
401 }
402 else {
403 MR::requestStartDemoWithoutCinemaFrame(this, "出現", pNerve, nullptr);
404 }
405
406 MR::requestMovementOn(MR::getSceneObj<NoteGroup*>(SceneObj_NoteGroup));
407 MR::requestMovementOn(this);
408}
409
410bool NoteFairy::isDeadAllNotes() {
411 for (s32 i = 0; i < mMelodyNoteNum; i++) {
412 if (!MR::isDead(mNoteArray[i])) {
413 return false;
414 }
415 }
416
417 return true;
418}
419
420void NoteFairy::setLastGotNote(Note *pNote) {
421 mLastGotNote = pNote;
422}
423
424f32 NoteFairy::getNoteCoord(s32 val) {
425 if (_D1) {
426 return MR::getRailPointCoord(this, val);
427 }
428
429 return val * mNoteCoord;
430}
431
432bool NoteFairy::receiveOtherMsg(u32 msg, HitSensor *, HitSensor *) {
433 if (msg == 102) {
434 killAllNotes();
435
436 switch (mCompletionJingle) {
437 case -1:
438 break;
439 case 0:
440 MR::startSound(this, "SE_SY_TOTAL_COMPLETE", -1, -1);
441 break;
442 }
443
444 if (mHasDemo) {
445 setNerve(&NrvNoteFairy::NoteFairyNrvSuccessDemo::sInstance);
446 }
447 else {
448 setNerve(&NrvNoteFairy::NoteFairyNrvSuccess::sInstance);
449 }
450
451 return true;
452 }
453
454 return false;
455}
456
457NoteFairy::~NoteFairy() {
458
459}
460
461namespace NrvNoteFairy {
462 INIT_NERVE(NoteFairyNrvHide);
463 INIT_NERVE(NoteFairyNrvStartAppearDemo);
464 INIT_NERVE(NoteFairyNrvRailMoveStart);
465 INIT_NERVE(NoteFairyNrvDemoAppear);
466 INIT_NERVE(NoteFairyNrvAppearNoteBloom);
467 INIT_NERVE(NoteFairyNrvAppearNote);
468 INIT_NERVE(NoteFairyNrvEndWait);
469 INIT_NERVE(NoteFairyNrvSuccessDemo);
470 INIT_NERVE(NoteFairyNrvSuccess);
471};
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 mVelocity
3D vector of the actor's velocity.
Definition LiveActor.hpp:98
void initWithoutIter()
Initializes a NameObj without a JMapInfoIter instance.
Definition NameObj.cpp:41
Used for executing states of a LiveActor.
Definition Nerve.hpp:6
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
Definition NoteFairy.cpp:33
Class that represents a single note in a NoteFairy actor.
Definition Note.hpp:21
int mCounter
The amount of steps it takes for the note to disappear.
Definition Note.hpp:45