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 = EGG::egg_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 = EGG::egg_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 setPos(m_railInterpolator->curPos());
73 m_railInterpolator->setCurrVel(
static_cast<f32
>(m_mapObj->setting(0)));
77void ObjectBirdLeader::calc() {
78 m_railInterpolator->calc();
79 setPos(m_railInterpolator->curPos());
83void ObjectBirdLeader::loadAnims() {
84 std::array<const char *, 1> names = {{
88 std::array<Render::AnmType, 1> types = {{
92 linkAnims(names, types);
96ObjectBirdFollower::ObjectBirdFollower(
const System::MapdataGeoObj ¶ms, ObjectBird *bird,
98 : ObjectBirdLeader(params, bird), m_idx(idx) {}
101ObjectBirdFollower::~ObjectBirdFollower() =
default;
104void ObjectBirdFollower::init() {
105 constexpr f32 POS_DELTA_RANGE = 1000.0f;
106 constexpr f32 POS_DELTA_CENTER = 500.0f;
108 auto *anmMgr = m_drawMdl->anmMgr();
109 anmMgr->playAnim(0.0f, 1.0f, 0);
110 f32 frameCount = anmMgr->activeAnim(Render::AnmType::Chr)->frameCount();
112 auto &rand = System::RaceManager::Instance()->random();
113 f32 rate = rand.getF32(
static_cast<f32
>(frameCount));
114 anmMgr->playAnim(rate, 1.0f, 0);
116 m_baseSpeed =
static_cast<f32
>(m_mapObj->setting(0));
117 m_velocity = EGG::Vector3f::ez * m_baseSpeed;
119 f32 z = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
120 f32 y = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
121 f32 x = rand.getF32(POS_DELTA_RANGE) - POS_DELTA_CENTER;
122 EGG::Vector3f delta = EGG::Vector3f(x, y, z);
124 setPos(m_bird->leader()->pos() + delta);
128void ObjectBirdFollower::calc() {
133 if (CollisionDirector::Instance()->checkSphereFull(100.0f, pos(), EGG::Vector3f::inf,
135 addPos(info.tangentOff);
140void ObjectBirdFollower::calcPos() {
141 constexpr f32 MAX_SPEED_FACTOR = 1.2f;
143 EGG::Vector3f leaderPos = m_bird->leader()->pos();
144 const auto &follower = m_bird->followers();
146 for (u32 i = 0; i < follower.size(); ++i) {
148 leaderPos += follower[i]->pos();
152 EGG::Vector3f posDelta = leaderPos * (1.0f /
static_cast<f32
>(follower.size())) - pos();
153 posDelta.normalise();
156 m_velocity += posDelta;
158 if (m_velocity.length() > m_baseSpeed * MAX_SPEED_FACTOR) {
159 m_velocity.normalise();
160 m_velocity *= m_baseSpeed * MAX_SPEED_FACTOR;
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.