SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
BallRail.cpp
1#include "Game/MapObj/BallRail.hpp"
2#include <JSystem/JMath/JMath.hpp>
3
4BallRail::BallRail(const char *pName) : LiveActor(pName) {
5 mRailPoints = nullptr;
6 _90 = nullptr;
7 mNumPoints = 0;
8 mAcceleration = 1.5f;
9 mDeceleration = 0.995f;
10 _AC = 100.0f;
11}
12
13void BallRail::init(const JMapInfoIter &rIter) {
14 if (MR::getJMapInfoArg0NoInit(rIter, &mAcceleration)) {
15 mAcceleration /= 1000.0f;
16 }
17
18 if (MR::getJMapInfoArg1NoInit(rIter, &mDeceleration)) {
19 mDeceleration /= 1000.0f;
20 }
21
22 MR::connectToSceneMapObjMovement(this);
23 MR::invalidateClipping(this);
24 MR::onCalcGravity(this);
25 initRailRider(rIter);
26 initRailPoints();
27 MR::moveCoordToStartPos(this);
28 MR::setRailCoordSpeed(this, 0.0f);
29 initHitSensor(1);
30 TVec3f offs;
31 offs.y = _AC;
32 offs.x = 0.0f;
33 offs.z = 0.0f;
34 MR::addHitSensor(this, "bind", 0x7B, 8, _AC, offs);
35 initNerve(&NrvBallRail::BallRailNrvWait::sInstance);
36 appear();
37}
38
39void BallRail::control() {
40
41}
42
43bool BallRail::receiveOtherMsg(u32 msg, HitSensor *a2, HitSensor *a3) {
44 if (msg == 173 && isNerve(&NrvBallRail::BallRailNrvWait::sInstance)) {
45 TVec3f v9(a2->mActor->mVelocity);
46 TVec3f v8 = a2->mPosition - a3->mPosition;
47
48 if (v8.dot(v9) > 0.0f) {
49 return false;
50 }
51
52 if (mGravity.dot(v8) > 0.0f) {
53 MR::normalizeOrZero(&v8);
54 v8.dot(v9);
55 MR::zeroVelocity(a2->mActor);
56 return false;
57 }
58 else {
59 _90 = a2;
60 return true;
61 }
62 }
63
64 return false;
65}
66
67// there is a minor regswap here but I'm marking it as done anyways
68// TODO -- fix regswap
69void BallRail::initRailPoints() {
70 #warning "BallRail::initRailPoints has a regswap"
71 u32 numPoints = (u32)(MR::getRailTotalLength(this) / 100.0f) + 2;
72 mNumPoints = numPoints;
73 mRailPoints = new BallRailPoint[numPoints];
74 MR::moveCoordToStartPos(this);
75 MR::setRailCoordSpeed(this, 100.0f);
76
77 for (u32 i = 0; i < mNumPoints - 1; i++) {
78 mRailPoints[i]._0 = MR::getRailPos(this);
79 mRailPoints[i]._24 = MR::getRailDirection(this);
80 MR::moveRailRider(this);
81 }
82
83 MR::moveCoordToEndPos(this);
84 mRailPoints[mNumPoints - 1]._0 = MR::getRailPos(this);
85 mRailPoints[mNumPoints - 1]._24 = MR::getRailDirection(this);
86 MR::moveCoordToStartPos(this);
87 MR::setRailCoordSpeed(this, 0.0f);
88
89 TVec3f v17(0, 1, 0);
90
91 if (mNumPoints >= 2) {
92 BallRailPoint* pnt = mRailPoints;
93 PSVECCrossProduct(pnt->_24.toCVec(), v17.toCVec(), pnt->_C.toVec());
94 MR::normalizeOrZero(&pnt->_C);
95 }
96
97 for (u32 i = 0; i < mNumPoints; i++) {
98 BallRailPoint* pnt = &mRailPoints[i];
99 PSVECCrossProduct(pnt->_24.toCVec(), v17.toCVec(), pnt->_C.toVec());
100 MR::normalizeOrZero(&pnt->_C);
101 }
102
103 if (mNumPoints >= 2) {
104 BallRailPoint* lastPnt = &mRailPoints[mNumPoints - 1];
105 PSVECCrossProduct(lastPnt->_24.toCVec(), v17.toCVec(), lastPnt->_C.toVec());
106 MR::normalizeOrZero(&lastPnt->_C);
107 }
108}
109
110void BallRail::exeWait() {
111 MR::moveCoordToNearestPos(this, *MR::getPlayerPos());
112 MR::moveTransToCurrentRailPos(this);
113
114 if (_90 != nullptr) {
115 setNerve(&NrvBallRail::BallRailNrvSetUp::sInstance);
116 }
117}
118
119void BallRail::exeSetUp() {
120 if (MR::isFirstStep(this)) {
121 _94 = _90->mPosition;
122 MR::zeroVelocity(_90->mActor);
123 MR::setRailCoordSpeed(this, 0.0f);
124 }
125
126 MR::moveCoord(this, 3.0f);
127 MR::moveTransToCurrentRailPos(this);
128
129 TVec3f v7;
130
131 if (MR::isLessStep(this, 15)) {
132 TVec3f v6;
133 JMAVECScaleAdd(mGravity.toCVec(), mPosition.toCVec(), v6.toVec(), -_90->mRadius);
134 f32 rate = MR::calcNerveEaseInRate(this, 15);
135 MR::vecBlend(_94, v6, &v7, rate);
136 }
137 else {
138 JMAVECScaleAdd(mGravity.toCVec(), mPosition.toCVec(), v7.toVec(), -_90->mRadius);
139 }
140
141 if (MR::isStep(this, 15)) {
142 MR::tryRumblePadStrong(this, 0);
143 }
144
145 MR::subtractAndSet(_90->mActor->mVelocity, v7, &_90->mPosition);
146
147 if (MR::isGreaterStep(this, 45)) {
148 setNerve(&NrvBallRail::BallRailNrvRun::sInstance);
149 }
150}
151
152void BallRail::exeRun() {
153 if (MR::isFirstStep(this)) {
154 MR::setRailCoordSpeed(this, 0.0f);
155 }
156
157 TVec3f v14(MR::getRailDirection(this));
158 TVec3f v13 = mGravity * mAcceleration;
159 TVec3f v12;
160 MR::accelerateRailCoordSpeed(this, v13.dot(v14));
161 MR::slowDownRailCoordSpeed(this, mDeceleration);
162
163 if (!MR::isRailGoingToEnd(this) || MR::getRailCoordSpeed(this) < 6.0f) {
164 if (!MR::isRailGoingToEnd(this)) {
165 MR::setRailDirectionToEnd(this);
166 }
167
168 MR::setRailCoordSpeed(this, 6.0f);
169 }
170
171 MR::moveRailRider(this);
172 MR::moveTransToCurrentRailPos(this);
173 JMAVECScaleAdd(mGravity.toCVec(), mPosition.toCVec(), v12.toVec(), -_90->mRadius);
174 MR::subtractAndSet(_90->mActor->mVelocity, v12, &_90->mPosition);
175
176 if (MR::isRailReachedGoal(this)) {
177 LiveActor* actor = _90->mActor;
178 TVec3f* vec = &actor->mVelocity;
179 MR::multAndSet(vec, MR::getRailDirection(this), MR::getRailCoordSpeed(this));
180 getSensor("bind")->receiveMessage(178, _90);
181 _90 = nullptr;
182 setNerve(&NrvBallRail::BallRailNrvNoBind::sInstance);
183 }
184}
185
186void BallRail::exeNoBind() {
187 if (getNerveStep() > 60) {
188 setNerve(&NrvBallRail::BallRailNrvWait::sInstance);
189 }
190}
191
192BallRailPoint::BallRailPoint() : _0(0, 0, 0), _C(1, 0, 0), _18(0, 1, 0), _24(0, 0, 1) {
193
194}
195
196BallRail::~BallRail() {
197
198}
199
200namespace NrvBallRail {
201 INIT_NERVE(BallRailNrvWait);
202 INIT_NERVE(BallRailNrvSetUp);
203 INIT_NERVE(BallRailNrvRun);
204 INIT_NERVE(BallRailNrvNoBind);
205};
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
Definition BallRail.cpp:13
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 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
HitSensor * getSensor(const char *pSensorName) const
Gets a sensor.