SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
MarblePlanet.cpp
1#include "Game/MapObj/MarblePlanet.hpp"
2#include "Game/LiveActor/ModelObj.hpp"
3#include "JSystem/JMath.hpp"
4
5MarblePlanet::MarblePlanet(const char *pName) : LiveActor(pName) {
6 mCorePlanetModel = 0;
7 mPlanetElectrons = 0;
8 mWatermelonCollision = 0;
9 mNumElectrons = 3;
10 mRemainingElectrons = 3;
11}
12
13void MarblePlanet::init(const JMapInfoIter &rIter) {
14 MR::initDefaultPos(this, rIter);
15 initModelManagerWithAnm("MarblePlanet", 0, false);
16 MR::connectToScenePlanet(this);
17 initHitSensor(1);
18 MR::addHitSensorEnemy(this, "core", 8, 50.0f, TVec3f(0.0f, 0.0f, 0.0f));
19 MR::initCollisionParts(this, "MarblePlanet", getSensor(0), 0);
20 mWatermelonCollision = MR::createCollisionPartsFromLiveActor(this, "WaterMelon", getSensor(0), (MR::CollisionScaleType)2);
21 initEffectKeeper(0, 0, false);
22 initSound(4, false);
23 MR::setClippingTypeSphereContainsModelBoundingBox(this, 100.0f);
24 MR::setClippingFar(this, -1.0f);
25 MR::needStageSwitchWriteDead(this, rIter);
26 MR::getJMapInfoArg0NoInit(rIter, &mNumElectrons);
27 mRemainingElectrons = mNumElectrons;
28 initCoreAndElectron();
29 MR::declarePowerStar(this);
30 initNerve(&NrvMarblePlanet::MarblePlanetNrvWait::sInstance);
31 makeActorAppeared();
32}
33
34void MarblePlanet::exeScaleUpCore() {
35 if (MR::isFirstStep(this)) {
36 MR::tryRumblePadMiddle(this, 0);
37 MR::shakeCameraNormal();
38 mRemainingElectrons = mRemainingElectrons - 1;
39 switch (mRemainingElectrons) {
40 case 0:
41 MR::emitEffect(this, "Break");
42 MR::startSound(this, "SE_OJ_MARBLE_HIT_CORE_3", -1, -1);
43 MR::startSystemSE("SE_SY_MARBLE_HIT_CORE_3", -1, -1);
44 break;
45 case 1:
46 MR::emitEffect(this, "Smoke6f");
47 MR::startSound(this, "SE_OJ_MARBLE_HIT_CORE_2", -1, -1);
48 MR::startSystemSE("SE_SY_MARBLE_HIT_CORE_2", -1, -1);
49 break;
50 case 2:
51 default:
52 MR::emitEffect(this, "Smoke3f");
53 MR::startSound(this, "SE_OJ_MARBLE_HIT_CORE_1", -1, -1);
54 MR::startSystemSE("SE_SY_MARBLE_HIT_CORE_1", -1, -1);
55 break;
56 }
57
58 if (mRemainingElectrons <= 0) {
59 setNerve(&NrvMarblePlanet::MarblePlanetNrvBreakCore::sInstance);
60 return;
61 }
62 else {
63 s32 electronCount = mNumElectrons;
64 f32 frameMax = MR::getBckFrameMax(mCorePlanetModel);
65 f32 frame = ((electronCount - mRemainingElectrons) * frameMax) / electronCount;
66 MR::setBckFrameAndStop(mCorePlanetModel, frame);
67 MR::setBtkFrameAndStop(mCorePlanetModel, frame);
68 }
69 }
70
71 f32 nerveRate = MR::calcNerveRate(this, 0x1E);
72 f32 scale = MR::getScaleWithReactionValueZeroToOne(nerveRate, 0.5f, -0.5f);
73 mCorePlanetModel->mScale.setAll(MR::getLinerValue(scale, 1.3f, 1.0f, 1.0f));
74
75 if (MR::isStep(this, 0x1E)) {
76 setNerve(&NrvMarblePlanet::MarblePlanetNrvWait::sInstance);
77 }
78}
79
80void MarblePlanet::exeBreakCore() {
81 if (MR::isFirstStep(this)) {
82 MR::setBckFrameAndStop(mCorePlanetModel, MR::getBckFrameMax(mCorePlanetModel));
83 MR::setBtkFrameAndStop(mCorePlanetModel, MR::getBtkFrameMax(mCorePlanetModel));
84 }
85
86 if (MR::isStep(this, 1)) {
87 MR::tryRumblePadStrong(this, 0);
88 MR::shakeCameraStrong();
89 MR::startAfterBossBGM();
90 MR::requestAppearPowerStar(this, mPosition);
91 MR::hideModel(this);
92 MR::invalidateCollisionParts(this);
93 MR::validateCollisionParts(mWatermelonCollision);
94 MR::onSwitchDead(this);
95 }
96}
97
98void MarblePlanet::startClipped() {
99 mCorePlanetModel->startClipped();
100
101 for (int i = 0; i < mNumElectrons; i++) {
102 mPlanetElectrons[i]->startClipped();
103 }
104
105 LiveActor::startClipped();
106}
107
108void MarblePlanet::endClipped() {
109 mCorePlanetModel->endClipped();
110
111 for (int i = 0; i < mNumElectrons; i++) {
112 mPlanetElectrons[i]->endClipped();
113 }
114
115 LiveActor::endClipped();
116}
117
118void MarblePlanet::kill() {
119 MR::onSwitchDead(this);
120 mCorePlanetModel->kill();
121 LiveActor::kill();
122}
123
124bool MarblePlanet::receiveMsgEnemyAttack(u32 msg, HitSensor *a1, HitSensor *a2) {
125 if (isNerve(&NrvMarblePlanet::MarblePlanetNrvScaleUpCore::sInstance)) {
126 return 0;
127 }
128
129 if (isNerve(&NrvMarblePlanet::MarblePlanetNrvBreakCore::sInstance)) {
130 return 0;
131 }
132
133 setNerve(&NrvMarblePlanet::MarblePlanetNrvScaleUpCore::sInstance);
134 return 1;
135}
136
137void MarblePlanet::initCoreAndElectron() {
138 mCorePlanetModel = MR::createModelObjMapObj("ビー玉惑星コア", "MarblePlanetCore", getBaseMtx());
139 MR::invalidateClipping(mCorePlanetModel);
140 MR::startBck(mCorePlanetModel, "MarblePlanetCore", 0);
141 MR::startBtk(mCorePlanetModel, "MarblePlanetCore");
142 MR::setBckFrameAndStop(mCorePlanetModel, 0.0f);
143 MR::setBtkFrameAndStop(mCorePlanetModel, 0.0f);
144 mPlanetElectrons = new MarblePlanetElectron*[mNumElectrons];
145
146 TVec3f front;
147 MR::calcFrontVec(&front, this);
148
149 TVec3f* pos;
150 int i = 0;
151
152 if (mNumElectrons > 0) {
153 pos = &mPosition;
154 for (; i < mNumElectrons; i++) {
155 if (i != 0) {
156 TVec3f up;
157 MR::calcUpVec(&up, this);
158 MR::rotateVecDegree(&front, up, (360.0f / mNumElectrons));
159 }
160
161 TVec3f position;
162 JMAVECScaleAdd(front.toCVec(), pos->toCVec(), position.toVec(), 1000.0f);
163 TVec3f rotation;
164 rotation.setAll((360.0f * i) / mNumElectrons);
165 mPlanetElectrons[i] = new MarblePlanetElectron(this, position, rotation, "ビー玉惑星電子");
166 mPlanetElectrons[i]->initWithoutIter();
167 }
168 }
169}
170
171MarblePlanetElectron::MarblePlanetElectron(LiveActor *pPlanet, const TVec3f &rPosition, const TVec3f &rRotation, const char *pName) : LiveActor(pName) {
172 mParentPlanet = static_cast<MarblePlanet*>(pPlanet);
173 mElectronShadow = 0;
174 _94.x = 0.0f;
175 _94.y = 0.0f;
176 _94.z = 1.0f;
177 mPosition.set(rPosition);
178 mRotation.set(rRotation);
179}
180
182 initModelManagerWithAnm("MarblePlanetElectron", 0, false);
183 MR::connectToScenePlanet(this);
184 initHitSensor(1);
185 MR::addHitSensorEnemy(this, "body", 8, 500.0f, TVec3f(0.0f, 0.0f, 0.0f));
186 initBinder(200.0f, 0.0f, 0);
187 initEffectKeeper(1, 0, false);
188 MR::addEffectHitNormal(this, 0);
189 initSound(4, false);
190 MR::invalidateClipping(this);
191 mElectronShadow = new MarblePlanetElectronShadow(this, mParentPlanet->mPosition, "電子影");
192 mElectronShadow->initWithoutIter();
193 MR::calcGravity(this);
194 mGravity.negate();
195
196 TPos3f mtx;
197 MR::makeMtxUpNoSupportPos(&mtx, mGravity, mPosition);
198 MR::setBaseTRMtx(this, mtx);
199 MR::calcFrontVec(&_94, this);
200 MR::startBck(this, "MarblePlanetElectron", 0);
201 initNerve(&NrvMarblePlanetElectron::MarblePlanetElectronNrvMove::sInstance);
202 makeActorAppeared();
203}
204
205void MarblePlanetElectron::exeMove() {
206 MR::turnDirectionToGround(this, &_94);
207 MR::attenuateVelocity(this, 0.99000001f);
208 f32 mag = PSVECMag(mVelocity.toCVec());
209 f32 scale = (mag >= 13.0f ? mag : 13.0f);
210 mVelocity.scale(scale, _94);
211 MR::startLevelSound(this, "SE_OJ_LV_MARBLE_ROTATE", -1, -1, -1);
212}
213
214void MarblePlanetElectron::exeAttack() {
215 if (MR::isFirstStep(this)) {
216 MR::startSound(this, "SE_OJ_MARBLE_FLIP", -1, -1);
217 }
218
219 TVec3f velocity;
220 velocity.sub(mParentPlanet->mPosition, mPosition);
221 MR::normalize(&velocity);
222 mVelocity.scale(40.0f, velocity);
223}
224
225void MarblePlanetElectron::control() {
226 MR::calcGravity(this);
227 mGravity.negate();
228
229 if (isNerve(&NrvMarblePlanetElectron::MarblePlanetElectronNrvMove::sInstance)) {
230 MR::restrictVelocity(this, 30.0f);
231 }
232}
233
234void MarblePlanetElectron::attackSensor(HitSensor *a1, HitSensor *a2) {
235 if (MR::isSensorEnemy(a2)) {
236 if (MR::sendMsgEnemyAttack(a2, a1)) {
237 mElectronShadow->kill();
238 kill();
239 }
240 else {
241 bool isNear = !MR::isNear(this, a2->mActor->mPosition, 440.0f);
242
243 if (!isNear) {
244 if (MR::sendMsgPush(a2, a1)) {
245 MR::tryRumblePadVeryWeak(this, 0);
246
247 if (!MR::isEffectValid(this, "HitMarkNormal")) {
248 MR::emitEffectHitBetweenSensors(this, a1, a2, 0.0f, 0);
249 }
250
251 MR::killVelocityToTarget(this, a2->mActor->mPosition);
252 }
253 }
254 }
255 }
256}
257
258bool MarblePlanetElectron::receiveMsgPlayerAttack(u32 msg, HitSensor *a2, HitSensor *a3) {
259 if (isNerve(&NrvMarblePlanetElectron::MarblePlanetElectronNrvAttack::sInstance)) {
260 return 0;
261 }
262
263 if (MR::isMsgPlayerHipDrop(msg)) {
264 setNerve(&NrvMarblePlanetElectron::MarblePlanetElectronNrvAttack::sInstance);
265 return 1;
266 }
267
268 return 0;
269}
270
271bool MarblePlanetElectron::receiveMsgPush(HitSensor *a1, HitSensor *a2) {
272 if (!MR::isSensorEnemy(a1)) {
273 return 0;
274 }
275
276 crashElectron(a1);
277 return 1;
278}
279
280void MarblePlanetElectron::crashElectron(HitSensor *pSensor) {
281 TVec3f stack_8;
282 stack_8.sub(pSensor->mActor->mPosition, mPosition);
283 MR::normalize(&stack_8);
284 JMAVECScaleAdd(stack_8.toCVec(), mVelocity.toCVec(), mVelocity.toVec(), -5.0f);
285 MR::normalize(mVelocity, &_94);
286 mVelocity.x *= 1.2f;
287 mVelocity.y *= 1.2f;
288 mVelocity.z *= 1.2f;
289 MR::startSound(this, "SE_OJ_MARBLE_HIT_EACH", -1, -1);
290}
291
292MarblePlanetElectronShadow::MarblePlanetElectronShadow(LiveActor *pElectronPtr, const TVec3f &rVec, const char *pName) : LiveActor(pName) {
293 mParentElectron = static_cast<MarblePlanetElectron*>(pElectronPtr);
294 _90 = &rVec;
295}
296
298 initModelManagerWithAnm("MarblePlanetElectronShadow", 0, false);
299 MR::connectToScenePlanet(this);
300 MR::invalidateClipping(this);
301 makeActorAppeared();
302}
303
305 mPosition.set(*_90);
306 TVec3f stack_8;
307 stack_8.sub(mParentElectron->mPosition, *_90);
308 MR::normalize(&stack_8);
309 TPos3f up_mtx;
310 MR::makeMtxUpNoSupportPos(&up_mtx, stack_8, *_90);
311 MR::setBaseTRMtx(this, up_mtx);
312}
313
314MarblePlanet::~MarblePlanet() {
315
316}
317
318MarblePlanetElectron::~MarblePlanetElectron() {
319
320}
321
322MarblePlanetElectronShadow::~MarblePlanetElectronShadow() {
323
324}
325
326namespace NrvMarblePlanet {
327 INIT_NERVE(MarblePlanetNrvWait);
328 INIT_NERVE(MarblePlanetNrvScaleUpCore);
329 INIT_NERVE(MarblePlanetNrvBreakCore);
330};
331
332namespace NrvMarblePlanetElectron {
333 INIT_NERVE(MarblePlanetElectronNrvMove);
334 INIT_NERVE(MarblePlanetElectronNrvAttack);
335
336 void MarblePlanetElectronNrvAttack::execute(Spine *pSpine) const {
337 MarblePlanetElectron* electron = reinterpret_cast<MarblePlanetElectron*>(pSpine->mExecutor);
338 electron->exeAttack();
339 }
340
341 void MarblePlanetElectronNrvMove::execute(Spine *pSpine) const {
342 MarblePlanetElectron* electron = reinterpret_cast<MarblePlanetElectron*>(pSpine->mExecutor);
343 electron->exeMove();
344 }
345};
346
347namespace NrvMarblePlanet {
348 void MarblePlanetNrvBreakCore::execute(Spine *pSpine) const {
349 MarblePlanet* marble = reinterpret_cast<MarblePlanet*>(pSpine->mExecutor);
350 marble->exeBreakCore();
351 }
352
353 void MarblePlanetNrvScaleUpCore::execute(Spine *pSpine) const {
354 MarblePlanet* marble = reinterpret_cast<MarblePlanet*>(pSpine->mExecutor);
355 marble->exeScaleUpCore();
356 }
357
358 void MarblePlanetNrvWait::execute(Spine *pSpine) const {
359
360 }
361};
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
TVec3f mGravity
3D vector of the actor's gravity.
Definition LiveActor.hpp:99
virtual MtxPtr getBaseMtx() const
Gets the base matrix of the model used for the actor.
HitSensor * getSensor(const char *pSensorName) const
Gets a sensor.
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.
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
void initWithoutIter()
Initializes a NameObj without a JMapInfoIter instance.
Definition NameObj.cpp:41
Definition Spine.hpp:9