A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
KartAction.cc
1#include "KartAction.hh"
2
3#include "game/kart/KartMove.hh"
4#include "game/kart/KartPhysics.hh"
5#include "game/kart/KartState.hh"
6
7#include <egg/math/Math.hh>
8
9namespace Kart {
10
12KartAction::KartAction()
13 : m_currentAction(Action::None), m_hitDepth(EGG::Vector3f::zero), m_onStart(nullptr),
14 m_onCalc(nullptr), m_onEnd(nullptr), m_actionParams(nullptr), m_rotationParams(nullptr),
15 m_priority(0) {}
16
18KartAction::~KartAction() = default;
19
21void KartAction::init() {
22 m_currentAction = Action::None;
23 m_flags.makeAllZero();
24}
25
27void KartAction::calc() {
28 if (m_currentAction == Action::None || !m_onCalc) {
29 return;
30 }
31
32 if (calcCurrentAction()) {
33 calcEndAction(false);
34 }
35}
36
38void KartAction::calcVehicleSpeed() {
39 move()->setSpeed(m_actionParams->calcSpeedMult * move()->speed());
40}
41
46bool KartAction::start(Action action) {
47 ASSERT(action != Action::None);
48
49 if (state()->isInRespawn() || state()->isAfterRespawn() || state()->isBeforeRespawn() ||
50 state()->isInCannon()) {
51 return false;
52 }
53
54 size_t actionIdx = static_cast<size_t>(action);
55 if (m_currentAction != Action::None && s_actionParams[actionIdx].priority <= m_priority) {
56 return false;
57 }
58
59 calcEndAction(true);
60 m_currentAction = action;
61 m_actionParams = &s_actionParams[actionIdx];
62 m_priority = m_actionParams->priority;
63 m_onStart = s_onStart[actionIdx];
64 m_onCalc = s_onCalc[actionIdx];
65 m_onEnd = s_onEnd[actionIdx];
66 state()->setInAction(true);
67 m_frame = 0;
68 m_flags.makeAllZero();
69 m_up = move()->up();
70 move()->clear();
71
72 applyStartSpeed();
73 (this->*m_onStart)();
74 return true;
75}
76
82void KartAction::startRotation(size_t idx) {
83 m_rotation = EGG::Quatf::ident;
84
85 EGG::Vector3f dir = move()->dir();
86 if (speed() < 0.0f) {
87 dir = -dir;
88 }
89
90 m_rotationDirection = dir.cross(bodyFront()).dot(bodyUp()) > 0.0f ? 1.0f : -1.0f;
91 setRotation(idx);
92 m_flags.setBit(eFlags::Rotating);
93}
94
95void KartAction::setHitDepth(const EGG::Vector3f &hitDepth) {
96 m_hitDepth = hitDepth;
97}
98
99const KartAction::Flags &KartAction::flags() const {
100 return m_flags;
101}
102
104void KartAction::end() {
105 state()->setInAction(false);
106 dynamics()->setForceUpright(true);
107
108 m_currentAction = Action::None;
109 m_priority = 0;
110 m_flags.makeAllZero();
111}
112
116bool KartAction::calcCurrentAction() {
117 ++m_frame;
118 return (this->*m_onCalc)();
119}
120
122void KartAction::calcEndAction(bool endArg) {
123 if (m_currentAction == Action::None) {
124 return;
125 }
126
127 if (m_onEnd) {
128 (this->*m_onEnd)(endArg);
129 end();
130 }
131}
132
134bool KartAction::calcRotation() {
135 if (!m_rotationParams) {
136 return false;
137 }
138
139 // Slow the rotation down as we approach the end of the spinout
140 if (m_currentAngle > m_finalAngle * m_rotationParams->slowdownThreshold) {
141 m_angleIncrement *= m_multiplier;
142 if (m_rotationParams->minAngleIncrement > m_angleIncrement) {
143 m_angleIncrement = m_rotationParams->minAngleIncrement;
144 }
145
146 m_multiplier -= m_multiplierDecrement;
147 if (m_rotationParams->minMultiplier > m_multiplier) {
148 m_multiplier = m_rotationParams->minMultiplier;
149 }
150 }
151
152 m_currentAngle += m_angleIncrement;
153 if (m_finalAngle < m_currentAngle) {
154 m_currentAngle = m_finalAngle;
155 return true;
156 }
157
158 return false;
159}
160
162void KartAction::calcUp() {
163 m_up += (move()->up() - m_up) * 0.3f;
164 m_up.normalise();
165}
166
168void KartAction::applyStartSpeed() {
169 move()->setSpeed(m_actionParams->startSpeedMult * move()->speed());
170 if (m_actionParams->startSpeedMult == 0.0f) {
171 move()->clearDrift();
172 }
173}
174
176void KartAction::setRotation(size_t idx) {
177 ASSERT(idx - 1 < s_rotationParams.size());
178 m_rotationParams = &s_rotationParams[--idx];
179
180 m_finalAngle = m_rotationParams->finalAngle;
181 m_angleIncrement = m_rotationParams->initialAngleIncrement;
182 m_multiplierDecrement = m_rotationParams->initialMultiplierDecrement;
183 m_currentAngle = 0.0f;
184 m_multiplier = 1.0f;
185}
186
187/* ================================ *
188 * START FUNCTIONS
189 * ================================ */
190
191void KartAction::startStub() {}
192
194void KartAction::startAction1() {
195 startRotation(2);
196}
197
198/* ================================ *
199 * CALC FUNCTIONS
200 * ================================ */
201
202bool KartAction::calcStub() {
203 return false;
204}
205
207bool KartAction::calcAction1() {
208 calcUp();
209 bool finished = calcRotation();
210
211 m_rotation.setAxisRotation(DEG2RAD * (m_currentAngle * m_rotationDirection), m_up);
212 physics()->composeExtraRot(m_rotation);
213 return finished;
214}
215
216/* ================================ *
217 * END FUNCTIONS
218 * ================================ */
219
220void KartAction::endStub(bool /*arg*/) {}
221
223void KartAction::endAction1(bool arg) {
224 if (arg) {
225 physics()->composeDecayingExtraRot(m_rotation);
226 }
227}
228
229/* ================================ *
230 * ACTION TABLES
231 * ================================ */
232
233const std::array<KartAction::ActionParams, KartAction::MAX_ACTION> KartAction::s_actionParams = {{
234 {0.98f, 0.98f, 1},
235 {0.98f, 0.98f, 2},
236 {0.96f, 0.96f, 4},
237 {0.0f, 0.96f, 4},
238 {0.0f, 0.98f, 4},
239 {0.0f, 0.96f, 4},
240 {0.0f, 0.96f, 4},
241 {0.0f, 0.0f, 6},
242 {0.0f, 0.99f, 6},
243 {0.98f, 0.98f, 3},
244 {0.98f, 0.98f, 3},
245 {1.0f, 1.0f, 5},
246 {0.0f, 0.0f, 3},
247 {0.0f, 0.0f, 3},
248 {0.0f, 0.0f, 3},
249 {0.98f, 0.98f, 3},
250 {0.0f, 0.0f, 3},
251 {0.98f, 0.98f, 3},
252}};
253
254const std::array<KartAction::RotationParams, 5> KartAction::s_rotationParams = {{
255 {10.0f, 1.5f, 0.9f, 0.005f, 0.6f, 360.0f},
256 {11.0f, 1.5f, 0.9f, 0.0028f, 0.7f, 720.0f},
257 {11.0f, 1.5f, 0.9f, 0.0028f, 0.8f, 1080.0f},
258 {7.0f, 1.5f, 0.9f, 0.005f, 0.6f, 450.0f},
259 {9.0f, 1.5f, 0.9f, 0.0028f, 0.7f, 810.0f},
260}};
261
262const std::array<KartAction::StartActionFunc, KartAction::MAX_ACTION> KartAction::s_onStart = {{
263 &KartAction::startStub,
264 &KartAction::startAction1,
265 &KartAction::startStub,
266 &KartAction::startStub,
267 &KartAction::startStub,
268 &KartAction::startStub,
269 &KartAction::startStub,
270 &KartAction::startStub,
271 &KartAction::startStub,
272 &KartAction::startStub,
273 &KartAction::startStub,
274 &KartAction::startStub,
275 &KartAction::startStub,
276 &KartAction::startStub,
277 &KartAction::startStub,
278 &KartAction::startStub,
279 &KartAction::startStub,
280 &KartAction::startStub,
281}};
282
283const std::array<KartAction::CalcActionFunc, KartAction::MAX_ACTION> KartAction::s_onCalc = {{
284 &KartAction::calcStub,
285 &KartAction::calcAction1,
286 &KartAction::calcStub,
287 &KartAction::calcStub,
288 &KartAction::calcStub,
289 &KartAction::calcStub,
290 &KartAction::calcStub,
291 &KartAction::calcStub,
292 &KartAction::calcStub,
293 &KartAction::calcStub,
294 &KartAction::calcStub,
295 &KartAction::calcStub,
296 &KartAction::calcStub,
297 &KartAction::calcStub,
298 &KartAction::calcStub,
299 &KartAction::calcStub,
300 &KartAction::calcStub,
301 &KartAction::calcStub,
302}};
303
304const std::array<KartAction::EndActionFunc, KartAction::MAX_ACTION> KartAction::s_onEnd = {{
305 &KartAction::endStub,
306 &KartAction::endAction1,
307 &KartAction::endStub,
308 &KartAction::endStub,
309 &KartAction::endStub,
310 &KartAction::endStub,
311 &KartAction::endStub,
312 &KartAction::endStub,
313 &KartAction::endStub,
314 &KartAction::endStub,
315 &KartAction::endStub,
316 &KartAction::endStub,
317 &KartAction::endStub,
318 &KartAction::endStub,
319 &KartAction::endStub,
320 &KartAction::endStub,
321 &KartAction::endStub,
322 &KartAction::endStub,
323}};
324
325} // namespace Kart
EGG core library.
Definition Archive.cc:6
Pertains to kart-related functionality.
A 3D float vector.
Definition Vector.hh:83
f32 normalise()
Normalizes the vector and returns the original length.
Definition Vector.cc:44
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:182