1#include "ObjectKoopaBall.hh"
3#include "game/field/CollisionDirector.hh"
5#include "game/kart/KartCollide.hh"
10ObjectKoopaBall::ObjectKoopaBall(
const System::MapdataGeoObj ¶ms)
14ObjectKoopaBall::~ObjectKoopaBall() {
15 EGG::egg_delete(m_bombCoreDrawMdl);
19void ObjectKoopaBall::init() {
20 constexpr u32 START_COOLDOWN = 221;
22 m_state = State::Intangible;
23 m_cooldownTimer = START_COOLDOWN;
25 m_railInterpolator->init(0.0f, 0);
26 m_railInterpolator->setCurrVel(INITIAL_VELOCITY);
27 m_railInterpolator->calc();
29 m_initPosY = m_railInterpolator->curPos().y;
30 setPos(EGG::Vector3f(pos().x, m_initPosY, pos().z));
32 EGG::Vector3f curTanDirNorm = m_railInterpolator->curTangentDir();
33 curTanDirNorm.normalise();
34 setMatrixFromOrthonormalBasisAndPos(curTanDirNorm);
38 m_angSpeed = INITIAL_ANGULAR_SPEED;
39 m_vel.y = INITIAL_Y_VEL;
41 m_bombCoreDrawMdl = EGG::egg_new<Render::DrawMdl>();
43 auto *resMgr = System::ResourceManager::Instance();
44 const void *file = resMgr->getFile(
"bombCore.brres",
nullptr, System::ArchiveId::Core);
46 Abstract::g3d::ResFile resFile = Abstract::g3d::ResFile(file);
48 m_bombCoreDrawMdl->linkAnims(0, &resFile,
"bombCore", Render::AnmType::Chr);
49 auto *anmMgr = m_bombCoreDrawMdl->anmMgr();
50 anmMgr->playAnim(0.0f, 1.0f, 0);
51 m_animFramecount = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
57 resize(RADIUS_AABB, 0.0f);
61void ObjectKoopaBall::calc() {
66 case State::Intangible:
69 case State::Exploding:
78 EGG::Vector3f railVel = m_railInterpolator->curTangentDir() * m_railInterpolator->getCurrVel();
84Kart::Reaction ObjectKoopaBall::onCollision(Kart::KartObject * ,
85 Kart::Reaction reactionOnKart, Kart::Reaction ,
87 return m_explodeTimer > 0 ? Kart::Reaction::ExplosionLoseItem : reactionOnKart;
91void ObjectKoopaBall::calcTangible() {
92 constexpr f32 END_VELOCITY = 60.0f;
93 constexpr f32 GRAVITY = 2.0f;
95 auto railStatus = m_railInterpolator->calc();
98 case RailInterpolator::Status::SegmentEnd:
99 m_vel.y = END_VELOCITY;
100 m_railInterpolator->setCurrVel(INITIAL_VELOCITY / INITIAL_ANGULAR_SPEED);
102 case RailInterpolator::Status::ChangingDirection: {
103 m_state = State::Exploding;
104 m_curScale = SCALE_INITIAL;
105 setScale(SCALE_INITIAL);
106 m_explodeTimer = m_animFramecount;
112 m_vel.y = m_vel.y - GRAVITY;
113 const auto &railPos = m_railInterpolator->curPos();
114 setPos(EGG::Vector3f(railPos.x, m_vel.y + pos().y, railPos.z));
118 m_angleRad += -m_angSpeed * DEG2RAD;
120 EGG::Matrix34f mat = EGG::Matrix34f::ident;
121 mat.makeR(EGG::Vector3f(m_angleRad, 0.0f, 0.0f));
122 mat = transform().multiplyTo(mat);
123 mat.setBase(3, pos());
128void ObjectKoopaBall::calcExploding() {
129 constexpr s32 EXPLODE_COLLISION_DURATION = 20;
130 constexpr s32 EXPLOSION_EXPAND_FRAME = 30;
131 constexpr f32 INIT_FACTOR = 1.01f;
132 constexpr EGG::Vector3f INIT_SCALE = EGG::Vector3f(INIT_FACTOR, INIT_FACTOR, INIT_FACTOR);
134 if (m_explodeTimer > EXPLOSION_EXPAND_FRAME) {
135 m_curScale += SCALE_DELTA;
136 setScale(m_curScale);
139 if (m_explodeTimer == EXPLODE_COLLISION_DURATION) {
143 if (--m_explodeTimer == 0) {
144 m_curScale = INIT_FACTOR;
145 setScale(INIT_SCALE);
146 m_railInterpolator->init(0.0f, 0);
147 const auto &railPos = m_railInterpolator->curPos();
148 setPos(EGG::Vector3f(railPos.x, m_initPosY, railPos.z));
150 m_state = State::Intangible;
155void ObjectKoopaBall::calcIntangible() {
156 constexpr s32 COOLDOWN_FRAMES = 210;
158 if (m_cooldownTimer >= 0) {
162 m_state = State::Tangible;
163 m_railInterpolator->setCurrVel(INITIAL_VELOCITY);
164 m_angSpeed = INITIAL_ANGULAR_SPEED;
165 m_vel.y = INITIAL_Y_VEL;
166 m_cooldownTimer = COOLDOWN_FRAMES;
170void ObjectKoopaBall::checkSphereFull() {
171 constexpr EGG::Vector3f POS_OFFSET = EGG::Vector3f(0.0f, -900.0f, 0.0f);
172 constexpr f32 RADIUS = 100.0f;
173 constexpr f32 BOUNCE_FACTOR = -0.4f;
174 constexpr f32 MIN_ANG_SPEED = 10.0f;
177 EGG::Vector3f colPos = pos() + POS_OFFSET;
179 if (CollisionDirector::Instance()->checkSphereFull(RADIUS, colPos, EGG::Vector3f::inf,
181 m_vel.y *= BOUNCE_FACTOR;
182 m_angSpeed = std::max(MIN_ANG_SPEED, m_angSpeed);
183 addPos(info.tangentOff);
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.