A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectBasabasa.cc
1#include "ObjectBasabasa.hh"
2
3#include "game/field/ObjectDirector.hh"
4#include "game/field/RailManager.hh"
5
6#include "game/system/RaceConfig.hh"
7#include "game/system/RaceManager.hh"
8
9namespace Kinoko::Field {
10
12ObjectBasabasaDummy::ObjectBasabasaDummy(const System::MapdataGeoObj &params)
13 : ObjectCollidable(params), StateManager(this, STATE_ENTRIES),
14 m_bigBump(params.setting(7) == 1) {
15 m_active = true;
16}
17
19ObjectBasabasaDummy::~ObjectBasabasaDummy() = default;
20
22void ObjectBasabasaDummy::init() {
23 m_railInterpolator->init(0.0f, 0);
24 m_pos = m_railInterpolator->curPos();
25 m_flags.setBit(eFlags::Position);
26
27 auto &rng = System::RaceManager::Instance()->random();
28 rng.next();
29 f32 y = rng.getF32(ObjectBasabasa::initialYRange());
30 f32 x = rng.getF32(ObjectBasabasa::initialXRange());
31
32 m_initialPos = EGG::Vector3f(x - ObjectBasabasa::initialXRange() * 0.5f, y, 0.0f);
33
34 m_nextStateId = 0;
35}
36
38Kart::Reaction ObjectBasabasaDummy::onCollision(Kart::KartObject * /*kartObj*/,
39 Kart::Reaction reactionOnKart, Kart::Reaction /*reactionOnObj*/,
40 EGG::Vector3f & /*hitDepth*/) {
41 auto course = System::RaceConfig::Instance()->raceScenario().course;
42 if (course == Course::Dry_Dry_Ruins && m_bigBump) {
43 const auto &hitTable = ObjectDirector::Instance()->hitTableKart();
44 reactionOnKart = hitTable.reaction(hitTable.slot(ObjectId::BasabasaDummy));
45 }
46
47 return reactionOnKart;
48}
49
51void ObjectBasabasaDummy::calcState0() {
52 if (!m_active) {
53 return;
54 }
55
56 if (m_railInterpolator->calc() == RailInterpolator::Status::ChangingDirection) {
57 m_active = false;
58 unregisterCollision();
59 } else {
60 setMatrixFromOrthonormalBasisAndPos(m_railInterpolator->curTangentDir());
61 calcTransform();
62
63 EGG::Matrix34f mat = m_transform;
64 mat.setBase(3, EGG::Vector3f::zero);
65 m_pos = m_railInterpolator->curPos() + mat.ps_multVector(m_initialPos);
66 m_flags.setBit(eFlags::Position);
67 }
68}
69
71ObjectBasabasa::ObjectBasabasa(const System::MapdataGeoObj &params)
72 : ObjectCollidable(params), m_initialTimer(params.setting(1)),
73 m_batsPerGroup(params.setting(2)), m_startFrame(params.setting(6)),
74 m_batSpacing(static_cast<u32>(static_cast<f32>(params.setting(5)) /
75 static_cast<f32>(params.setting(0)) / static_cast<f32>(m_batsPerGroup))) {
76 f32 railLen = RailManager::Instance()->rail(params.pathId())->getPathLength();
77 u32 groupCount = static_cast<u32>(railLen / static_cast<f32>(params.setting(0)) /
78 static_cast<f32>(m_initialTimer)) +
79 1;
80 u32 batCount = groupCount * m_batsPerGroup;
81
82 m_bats = owning_span<ObjectBasabasaDummy *>(batCount);
83
84 for (auto *&bat : m_bats) {
85 bat = new ObjectBasabasaDummy(params);
86 bat->load();
87 }
88
89 s_initialXRange = params.setting(3);
90 s_initialYRange = params.setting(4);
91}
92
94ObjectBasabasa::~ObjectBasabasa() = default;
95
97void ObjectBasabasa::init() {
98 for (auto *&bat : m_bats) {
99 if (bat->active()) {
100 bat->setActive(false);
101 bat->unregisterCollision();
102 }
103 }
104
105 m_cycleTimer = m_initialTimer;
106 m_batsActive = 0;
107}
108
110void ObjectBasabasa::calc() {
111 if (System::RaceManager::Instance()->timer() <= m_startFrame) {
112 return;
113 }
114
115 if (m_cycleTimer == m_initialTimer + m_batSpacing * (m_batsActive % m_batsPerGroup)) {
116 auto *&bat = m_bats[m_batsActive++];
117 bat->init();
118 bat->setActive(true);
119 bat->loadAABB(0.0f);
120
121 if ((m_batsActive % m_batsPerGroup) == 0) {
122 m_cycleTimer = m_batSpacing * m_batsPerGroup;
123 }
124 }
125
126 m_batsActive %= m_bats.size();
127
128 ++m_cycleTimer;
129}
130
131f32 ObjectBasabasa::s_initialXRange;
132f32 ObjectBasabasa::s_initialYRange;
133
134} // namespace Kinoko::Field
Pertains to collision.