1#include "ObjectKuribo.hh"
3#include "game/field/CollisionDirector.hh"
11 : ObjectCollidable(params), StateManager(this) {
12 m_animStep =
static_cast<f32
>(m_mapObj->setting(2)) / 100.0f;
13 m_speedStep =
static_cast<f32
>(m_mapObj->setting(1)) / 100.0f;
17ObjectKuribo::~ObjectKuribo() =
default;
20void ObjectKuribo::init() {
22 m_origin = m_transform.base(2);
24 m_railInterpolator->init(0.0f, 0);
25 m_railInterpolator->setCurrVel(0.0f);
31 auto *anmMgr = m_drawMdl->anmMgr();
32 anmMgr->playAnim(0.0f, m_animStep, 0);
33 m_maxAnimTimer = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
38void ObjectKuribo::calc() {
39 m_animTimer = ::fmodf(
static_cast<f32
>(m_frameCount) * m_animStep, m_maxAnimTimer);
41 if (m_nextStateId >= 0) {
42 m_currentStateId = m_nextStateId;
46 auto enterFunc = m_entries[m_entryIds[m_currentStateId]].onEnter;
52 auto calcFunc = m_entries[m_entryIds[m_currentStateId]].onCalc;
59void ObjectKuribo::loadAnims() {
60 std::array<const char *, 2> names = {{
65 std::array<Render::AnmType, 2> types = {{
70 linkAnims(names, types);
73void ObjectKuribo::enterStateStub() {}
75void ObjectKuribo::calcStateStub() {}
79void ObjectKuribo::calcStateReroute() {
80 if (m_railInterpolator->curPoint().setting[0] < m_currentFrame) {
86 setMatrixTangentTo(m_rot, m_origin);
91void ObjectKuribo::calcStateWalk() {
96void ObjectKuribo::calcAnim() {
99 if (m_railInterpolator->isMovementDirectionForward()) {
100 shouldMove = m_animTimer > 15.0f && m_animTimer < 25.0f;
102 shouldMove = m_animTimer > 45.0f && m_animTimer < 55.0f;
106 m_currSpeed = std::min(10.0f, m_currSpeed + m_speedStep);
108 m_currSpeed = std::max(0.0f, m_currSpeed - m_speedStep);
111 m_railInterpolator->setCurrVel(m_currSpeed);
113 const auto &curPos = m_railInterpolator->curPos();
117 if (m_railInterpolator->calc() == RailInterpolator::Status::ChangingDirection) {
124 setMatrixTangentTo(m_rot, m_origin);
128void ObjectKuribo::calcRot() {
129 m_rot = interpolate(0.1f, m_rot, m_floorNrm);
131 if (m_rot.squaredLength() > std::numeric_limits<f32>::epsilon()) {
134 m_rot = EGG::Vector3f::ey;
139void ObjectKuribo::checkSphereFull() {
140 constexpr f32 RADIUS = 50.0f;
143 if (m_currentStateId != 0) {
148 CollisionInfo colInfo;
152 bool hasCol = CollisionDirector::Instance()->checkSphereFull(RADIUS, pos, EGG::Vector3f::inf,
156 m_pos += colInfo.tangentOff;
159 if (colInfo.floorDist > -std::numeric_limits<f32>::min()) {
160 m_floorNrm = colInfo.floorNrm;
168 return v0 + (v1 - v0) * scale;
171const std::array<StateManagerEntry<ObjectKuribo>, 4> StateManager<ObjectKuribo>::STATE_ENTRIES = {{
172 {0, &ObjectKuribo::enterStateStub, &ObjectKuribo::calcStateReroute},
173 {1, &ObjectKuribo::enterStateStub, &ObjectKuribo::calcStateWalk},
174 {2, &ObjectKuribo::enterStateStub, &ObjectKuribo::calcStateStub},
175 {3, &ObjectKuribo::enterStateStub, &ObjectKuribo::calcStateStub},
178StateManager<ObjectKuribo>::StateManager(ObjectKuribo *obj) {
179 constexpr size_t ENTRY_COUNT = 4;
182 m_entries = std::span{STATE_ENTRIES};
183 m_entryIds = std::span(
new u16[ENTRY_COUNT], ENTRY_COUNT);
186 for (
auto &
id : m_entryIds) {
190 for (
size_t i = 0; i < m_entryIds.size(); ++i) {
191 m_entryIds[STATE_ENTRIES[i].id] = i;
195StateManager<ObjectKuribo>::~StateManager() {
196 delete[] m_entryIds.data();
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.