1#include "ObjectPress.hh"
3#include "game/field/CollisionDirector.hh"
4#include "game/field/ObjectDirector.hh"
6#include "game/kart/KartObject.hh"
12 : ObjectCollidable(params), m_loweringVelocity(0.0f) {}
15ObjectPress::~ObjectPress() =
default;
18void ObjectPress::init() {
19 constexpr f32 FLOOR_CHECK_SPEED = 100.0f;
20 constexpr f32 HEIGHT = 20.0f;
23 m_state = State::Raised;
24 m_startingRise =
false;
26 m_raisedTimer =
static_cast<u32>(m_mapObj->setting(1));
28 m_raisedHeight = m_pos.y;
32 auto *colDir = CollisionDirector::Instance();
38 m_flags.setBit(eFlags::Position);
39 m_pos.y -= FLOOR_CHECK_SPEED;
41 hasCol = colDir->checkSphereFull(HEIGHT, m_pos + HITBOX_OFFSET, EGG::Vector3f::inf,
46 m_pos.x = loweredPos.x;
47 m_pos.z = loweredPos.z;
48 m_loweredHeight = loweredPos.y;
49 m_flags.setBit(eFlags::Position);
50 m_pos.y = m_raisedHeight;
51 m_startedLowered =
false;
55void ObjectPress::calc() {
56 m_startedLowered =
false;
78void ObjectPress::loadAnims() {
79 std::array<const char *, 1> names = {{
83 std::array<Render::AnmType, 1> types = {{
87 linkAnims(names, types);
91void ObjectPress::createCollision() {
92 constexpr f32 POINT_SCALE = 10.0f;
93 constexpr std::array<EGG::Vector3f, 16> POINTS = {{
112 m_collision =
new ObjectCollisionConvexHull(POINTS);
116Kart::Reaction ObjectPress::onCollision(
Kart::KartObject *kartObj, Kart::Reaction reactionOnKart,
118 constexpr f32 CRUSH_THRESHOLD = 430.0f;
122 EGG::Mathf::abs(diff.x) < CRUSH_THRESHOLD && EGG::Mathf::abs(diff.z) < CRUSH_THRESHOLD;
126 if (close && (m_state == State::Lowering || m_startedLowered)) {
127 const auto &hitTable = ObjectDirector::Instance()->hitTableKart();
128 return hitTable.reaction(hitTable.slot(ObjectId::PressSoko));
131 return reactionOnKart;
135void ObjectPress::calcRaised() {
136 constexpr u32 WINDUP_FRAMES = 10;
138 if (--m_raisedTimer == 0) {
139 m_state = State::WindUp;
140 m_windUpTimer = WINDUP_FRAMES;
144void ObjectPress::calcWindUp() {
145 constexpr f32 SPEED = 10.0f;
147 m_flags.setBit(eFlags::Position);
150 if (--m_windUpTimer == 0) {
151 m_state = State::Lowering;
156void ObjectPress::calcLowering() {
157 constexpr f32 ACCEL = 3.0f;
159 m_loweringVelocity -= ACCEL;
160 m_flags.setBit(eFlags::Position);
161 m_pos.y += m_loweringVelocity;
163 checkCollisionLowering();
166void ObjectPress::calcLowered() {
167 if (--m_anmDuration > 0) {
171 if (m_startingRise) {
172 m_state = State::Raising;
174 auto *anmMgr = m_drawMdl->anmMgr();
175 f32 frameCount = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
176 anmMgr->playAnim(frameCount, -ANM_RATE, 0);
178 m_startingRise =
true;
179 m_anmDuration = frameCount / ANM_RATE;
183void ObjectPress::calcRaising() {
184 constexpr f32 SPEED = 10.0f;
186 f32 height = m_pos.y + SPEED;
188 if (height < m_raisedHeight) {
191 m_pos.y = m_raisedHeight;
192 m_state = State::Raised;
193 m_raisedTimer =
static_cast<u32>(m_mapObj->setting(2));
196 m_flags.setBit(eFlags::Position);
200void ObjectPress::checkCollisionLowering() {
201 constexpr f32 RADIUS = 10.0f;
206 if (!CollisionDirector::Instance()->checkSphereFull(RADIUS, m_pos + HITBOX_OFFSET,
211 m_loweringVelocity = 0.0f;
212 m_pos = m_pos + info.tangentOff;
213 m_flags.setBit(eFlags::Position);
215 auto *anmMgr = m_drawMdl->anmMgr();
216 anmMgr->playAnim(0.0f, ANM_RATE, 0);
218 m_state = State::Lowered;
219 m_startingRise =
false;
220 m_anmDuration = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount() / ANM_RATE;
221 m_startedLowered =
true;
226 : ObjectPress(params), m_startingWindup(false) {}
229ObjectPressSenko::~ObjectPressSenko() =
default;
232void ObjectPressSenko::calcRaised() {
233 if (m_startingWindup) {
235 m_startingWindup =
false;
240void ObjectPressSenko::startWindup() {
241 constexpr u32 WINDUP_DURATION = 10;
243 m_state = State::WindUp;
244 m_windUpTimer = WINDUP_DURATION;
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.
The highest level abstraction for a kart.