A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectHeyhoBall.cc
1#include "ObjectHeyhoBall.hh"
2
3#include "game/field/ObjectDirector.hh"
4
5namespace Field {
6
8ObjectHeyhoBall::ObjectHeyhoBall(const System::MapdataGeoObj &params)
9 : ObjectProjectile(params), StateManager(this, STATE_ENTRIES),
10 m_airtime(static_cast<f32>(params.setting(1))), m_initPos(params.pos()) {
11 registerManagedObject();
12}
13
15ObjectHeyhoBall::~ObjectHeyhoBall() = default;
16
18void ObjectHeyhoBall::init() {
19 m_nextStateId = 0;
20 m_shipPos.setZero();
21 m_workingPos = m_pos;
22 m_intensity = ExplosionIntensity::ExplosionLoseItem;
23
24 resize(BLAST_RADIUS, 0.0f);
25
26 const auto &flowTable = ObjectDirector::Instance()->flowTable();
27 m_blastRadiusRatio = BLAST_RADIUS /
28 static_cast<f32>(parse<s16>(flowTable.set(flowTable.slot(id()))->params.sphere.radius));
29}
30
32void ObjectHeyhoBall::calc() {
33 StateManager::calc();
34
35 m_flags.setBit(eFlags::Position);
36 m_pos = m_workingPos;
37}
38
40Kart::Reaction ObjectHeyhoBall::onCollision(Kart::KartObject * /*kartObj*/,
41 Kart::Reaction /*reactionOnKart*/, Kart::Reaction /*reactionOnObj*/,
42 EGG::Vector3f &hitDepth) {
43 if (m_currentStateId == 3) {
44 if (m_intensity == ExplosionIntensity::ExplosionLoseItem) {
45 return Kart::Reaction::ExplosionLoseItem;
46 }
47
48 hitDepth.setZero();
49 return Kart::Reaction::SpinSomeSpeed;
50 }
51
52 return Kart::Reaction::WallAllSpeed;
53}
54
56void ObjectHeyhoBall::initProjectile(const EGG::Vector3f &pos) {
57 m_shipPos = pos;
58 m_xzDir = (m_initPos + EGG::Vector3f::ey * -BALL_RADIUS) - m_shipPos;
59 m_xzDir.y = 0.0f;
60 m_xzDir.normalise2();
61
62 EGG::Vector2f xzDist = EGG::Vector2f(m_shipPos.x - m_initPos.x, m_shipPos.z - m_initPos.z);
63 m_xzSpeed = EGG::Mathf::sqrt(xzDist.dot()) / m_airtime;
64 m_yDist = m_initPos.y + -BALL_RADIUS - m_shipPos.y;
65 m_initYSpeed = m_yDist / m_airtime + 0.5f * 4.0f * m_airtime;
66}
67
69void ObjectHeyhoBall::enterFalling() {
70 if (!getUnit()) {
71 loadAABB(0.0f);
72 resize(BLAST_RADIUS, 0.0f);
73 }
74}
75
77void ObjectHeyhoBall::calcFalling() {
78 f32 currentHeight = m_workingPos.y + (m_initYSpeed - 4.0f * static_cast<f32>(m_currentFrame));
79 if (currentHeight > m_initPos.y + -BALL_RADIUS) {
80 m_workingPos.y = currentHeight;
81 m_workingPos.x += m_xzDir.x * m_xzSpeed;
82 m_workingPos.z += m_xzDir.z * m_xzSpeed;
83 } else {
84 m_nextStateId = 2;
85 m_workingPos = (m_workingPos + m_initPos + EGG::Vector3f::ey * -BALL_RADIUS) * 0.5f;
86 }
87}
88
90void ObjectHeyhoBall::calcExploding() {
91 constexpr u32 EXPLODE_FRAMES = 46;
92 constexpr EGG::Vector3f BALL_SCALE = EGG::Vector3f(1.001f, 1.001f, 1.001f);
93
95 constexpr u32 SPIN_FRAME = 32;
96
97 if (m_currentFrame >= EXPLODE_FRAMES) {
98 m_flags.setBit(eFlags::Scale);
99 m_scale = BALL_SCALE;
100
101 if (getUnit()) {
102 unregisterCollision();
103 }
104
105 m_nextStateId = 0;
106 m_intensity = ExplosionIntensity::ExplosionLoseItem;
107 } else {
108 f32 shrinkFrames = static_cast<f32>(m_currentFrame) - 40.0f;
109 f32 scale = 1.2f * m_blastRadiusRatio + -m_scaleChangeRate * shrinkFrames * shrinkFrames;
110
111 scale = std::min(m_blastRadiusRatio, scale);
112 m_flags.setBit(eFlags::Scale);
113 m_scale = EGG::Vector3f(scale, scale, scale);
114
115 m_intensity = m_currentFrame >= SPIN_FRAME ? ExplosionIntensity::SpinSomeSpeed :
116 ExplosionIntensity::ExplosionLoseItem;
117 }
118}
119
120} // namespace Field
The highest level abstraction for a kart.
Definition KartObject.hh:11
Pertains to collision.
A 2D float vector.
Definition Vector.hh:12
A 3D float vector.
Definition Vector.hh:88