1#include "ObjectBird.hh"
3#include "game/field/CollisionDirector.hh"
5#include "game/system/RaceManager.hh"
10ObjectBird::ObjectBird(
const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) {
11 m_leader =
new ObjectBirdLeader(params,
this);
14 u32 count = params.setting(1);
19 m_followers = owning_span<ObjectBirdFollower *>(count);
21 for (u32 i = 0; i < count; ++i) {
22 auto *bird =
new ObjectBirdFollower(params,
this, i);
23 m_followers[i] = bird;
29ObjectBird::~ObjectBird() =
default;
32void ObjectBird::calc() {
33 constexpr f32 MIN_SPACING = 300.0f;
35 for (u32 i = 0; i < m_followers.size() - 1; ++i) {
36 const EGG::Vector3f &firstPos = m_followers[i]->pos();
38 for (u32 j = i + 1; j < m_followers.size(); ++j) {
39 const EGG::Vector3f &secondPos = m_followers[j]->pos();
40 EGG::Vector3f posDelta = firstPos - secondPos;
41 f32 len = posDelta.length();
43 if (len >= MIN_SPACING) {
48 m_followers[j]->setPos(secondPos - posDelta * (MIN_SPACING - len));
54ObjectBirdLeader::ObjectBirdLeader(
const System::MapdataGeoObj ¶ms, ObjectBird *bird)
55 : ObjectCollidable(params), m_bird(bird) {}
58ObjectBirdLeader::~ObjectBirdLeader() =
default;
61void ObjectBirdLeader::init() {
62 auto *anmMgr = m_drawMdl->anmMgr();
63 anmMgr->playAnim(0.0f, 1.0f, 0);
64 f32 frameCount = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
66 auto &rand = System::RaceManager::Instance()->random();
67 f32 rate = rand.getF32(
static_cast<f32
>(frameCount));
68 anmMgr->playAnim(rate, 1.0f, 0);
70 m_railInterpolator->init(0.0f, 0);
71 m_railInterpolator->calc();
72 m_pos = m_railInterpolator->curPos();
73 m_flags.setBit(eFlags::Position);
74 m_railInterpolator->setCurrVel(
static_cast<f32
>(m_mapObj->setting(0)));
78void ObjectBirdLeader::calc() {
79 m_railInterpolator->calc();
80 m_pos = m_railInterpolator->curPos();
81 m_flags.setBit(eFlags::Position);
85void ObjectBirdLeader::loadAnims() {
86 std::array<const char *, 1> names = {{
90 std::array<Render::AnmType, 1> types = {{
94 linkAnims(names, types);
98ObjectBirdFollower::ObjectBirdFollower(
const System::MapdataGeoObj ¶ms, ObjectBird *bird,
100 : ObjectBirdLeader(params, bird), m_idx(idx) {}
103ObjectBirdFollower::~ObjectBirdFollower() =
default;
106void ObjectBirdFollower::init() {
107 constexpr f32 POS_DELTA_RANGE = 1000.0f;
108 constexpr f32 POS_DELTA_CENTER = 500.0f;
110 auto *anmMgr = m_drawMdl->anmMgr();
111 anmMgr->playAnim(0.0f, 1.0f, 0);
112 f32 frameCount = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
114 auto &rand = System::RaceManager::Instance()->random();
115 f32 rate = rand.getF32(
static_cast<f32
>(frameCount));
116 anmMgr->playAnim(rate, 1.0f, 0);
118 m_baseSpeed =
static_cast<f32
>(m_mapObj->setting(0));
119 m_velocity = EGG::Vector3f::ez * m_baseSpeed;
121 f32 z = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
122 f32 y = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
123 f32 x = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
124 EGG::Vector3f delta = EGG::Vector3f(x, y, z);
126 m_pos = m_bird->leader()->pos() + delta;
127 m_flags.setBit(eFlags::Position);
131void ObjectBirdFollower::calc() {
136 if (CollisionDirector::Instance()->checkSphereFull(100.0f, m_pos, EGG::Vector3f::inf,
138 m_pos += info.tangentOff;
139 m_flags.setBit(eFlags::Position);
144void ObjectBirdFollower::calcPos() {
145 constexpr f32 MAX_SPEED_FACTOR = 1.2f;
147 EGG::Vector3f pos = m_bird->leader()->pos();
148 const auto &follower = m_bird->followers();
150 for (u32 i = 0; i < follower.size(); ++i) {
152 pos += follower[i]->pos();
156 EGG::Vector3f posDelta = pos * (1.0f /
static_cast<f32
>(follower.size())) - m_pos;
157 posDelta.normalise();
160 m_velocity += posDelta;
162 if (m_velocity.length() > m_baseSpeed * MAX_SPEED_FACTOR) {
163 m_velocity.normalise();
164 m_velocity *= m_baseSpeed * MAX_SPEED_FACTOR;
168 m_flags.setBit(eFlags::Position);
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.