A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectDossunSyuukai.cc
1#include "ObjectDossunSyuukai.hh"
2
3namespace Field {
4
6ObjectDossunSyuukai::ObjectDossunSyuukai(const System::MapdataGeoObj &params)
7 : ObjectDossun(params) {}
8
10ObjectDossunSyuukai::~ObjectDossunSyuukai() = default;
11
13void ObjectDossunSyuukai::init() {
14 ObjectDossun::init();
15
16 m_state = State::Moving;
17 m_initRotY = m_rot.y;
18 m_rotating = true;
19}
20
22void ObjectDossunSyuukai::calc() {
23 m_touchingGround = false;
24
25 switch (m_state) {
26 case State::Moving:
27 calcMoving();
28 break;
29 case State::RotatingBeforeStomp:
30 case State::RotatingAfterStomp:
31 calcRotating();
32 break;
33 case State::Stomping:
34 ObjectDossun::calcStomp();
35 break;
36 default:
37 break;
38 }
39}
40
42void ObjectDossunSyuukai::calcMoving() {
43 if (m_railInterpolator->calc() == RailInterpolator::Status::SegmentEnd) {
44 m_state = State::RotatingBeforeStomp;
45 }
46
47 m_pos = m_railInterpolator->curPos();
48 m_flags.setBit(eFlags::Position);
49}
50
52void ObjectDossunSyuukai::calcRotating() {
53 constexpr f32 ANG_VEL = 0.08726646f;
54 constexpr f32 BEFORE_FALL_FRAMES = 10;
55
56 m_flags.setBit(eFlags::Rotation);
57 m_rot.y += ANG_VEL;
58
59 if (m_state == State::RotatingBeforeStomp) {
60 f32 targetRot = m_initRotY;
61 if (targetRot < 0.0f) {
62 targetRot += F_TAU;
63 } else if (targetRot >= F_TAU) {
64 targetRot -= F_TAU;
65 }
66
67 if (targetRot < m_rot.y) {
68 m_flags.setBit(eFlags::Rotation);
69
70 if (m_rotating) {
71 m_rot.y -= F_TAU;
72 } else {
73 m_rot.y = m_initRotY;
74 m_anmState = AnmState::BeforeFall;
75 m_beforeFallTimer = BEFORE_FALL_FRAMES;
76
77 m_currRot = m_rot.y;
78 if (m_currRot >= F_PI) {
79 m_currRot -= F_TAU;
80 }
81
82 m_cycleTimer = m_fullDuration;
83 m_state = State::Stomping;
84 }
85 }
86
87 m_rotating = false;
88 } else if (m_state == State::RotatingAfterStomp) {
89 const auto &curTan = m_railInterpolator->curTangentDir();
90 f32 targetRot = FIDX2RAD * EGG::Mathf::Atan2FIdx(curTan.x, curTan.z);
91
92 if (targetRot < 0.0f) {
93 targetRot += F_TAU;
94 } else if (targetRot >= F_TAU) {
95 targetRot -= F_TAU;
96 }
97
98 if (targetRot < m_rot.y) {
99 m_flags.setBit(eFlags::Rotation);
100 m_rot.y = targetRot;
101 m_state = State::Moving;
102 m_rotating = true;
103 }
104 }
105}
106
107} // namespace Field
Pertains to collision.