Files
ss/src/d/a/d_a_bird_base.cpp
T
2025-09-16 22:32:05 -04:00

185 lines
5.4 KiB
C++

#include "d/a/d_a_bird_base.h"
#include "c/c_math.h"
#include "common.h"
#include "d/col/bg/d_bg_s.h"
#include "d/col/bg/d_bg_s_lin_chk.h"
#include "m/m3d/m_fanm.h"
#include "m/m_mtx.h"
#include "m/m_vec.h"
void dAcBirdBase_c::callback_c::timingB(u32, nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl) {
// TODO
}
int dAcBirdBase_c::doDelete() {
return SUCCEEDED;
}
int dAcBirdBase_c::draw() {
drawModelType1(&mMdl.getModel());
return SUCCEEDED;
}
void dAcBirdBase_c::updateMatrixBird() {
mWorldMtx.transS(mPosition);
mWorldMtx.concat(field_0xF80);
mWorldMtx.ZrotM(mRotation.z);
mWorldMtx.scaleM(field_0xF50.x, field_0xF50.y, field_0xF50.z);
mMdl.getModel().setLocalMtx(mWorldMtx);
mMdl.getModel().calc(false);
}
bool dAcBirdBase_c::changeBirdAction(const char *animName, s32 action, m3d::playMode_e playMode, f32 blend) {
void *data;
if (action < BIRD_ACTION_HOVER) {
data = getOarcResFile(getAnmArcNameBase());
} else if (action < BIRD_ACTION_BASE_MAX) {
data = getOarcResFile(getAnmArcNameLink());
} else {
data = getOarcResFile(getAnmArcNameSpecial());
}
mMdl.setAnmFile(data);
bool ret = false;
if (mBirdAction != action) {
mMdl.setAnm(animName, playMode, blend);
mBirdAction = action;
ret = true;
}
return ret;
}
void dAcBirdBase_c::executeBirdAction() {
if (mBirdAction == BIRD_ACTION_GLIDE) {
if (--mBirdActionTimer <= 0) {
changeBirdAction("Flap", BIRD_ACTION_FLAP, m3d::PLAY_MODE_4, 5.0f);
mBirdActionTimer = cM::rndInt(100) + 100;
} else if (field_0xF5C.y < -0.3f) {
changeBirdAction("SwitchToDive", BIRD_ACTION_SWITCH_DIVE, m3d::PLAY_MODE_4, 5.0f);
}
} else if (mBirdAction == BIRD_ACTION_GLIDE_DIVE) {
if (field_0xF5C.y >= -0.2f) {
changeBirdAction("SwitchToDive", BIRD_ACTION_SWITCH_DIVE, m3d::PLAY_MODE_3, 5.0f);
}
} else if (mBirdAction == BIRD_ACTION_SWITCH_DIVE) {
if (mMdl.getAnm().isStop()) {
if (mMdl.getAnm().getPlayMode() == m3d::PLAY_MODE_3) {
changeBirdAction("Glide", BIRD_ACTION_GLIDE, m3d::PLAY_MODE_4, 5.0f);
} else {
changeBirdAction("GlideDive", BIRD_ACTION_GLIDE_DIVE, m3d::PLAY_MODE_4, 5.0f);
}
} else if (field_0xF5C.y >= -0.15f) {
changeBirdAction("SwitchToDive", BIRD_ACTION_SWITCH_DIVE, m3d::PLAY_MODE_3, 5.0f);
}
} else {
if ((mMdl.getAnm().isStop() && mBirdAction == BIRD_ACTION_FLAP) ||
(mMdl.getAnm().isStop() && mBirdAction == BIRD_ACTION_DAMAGE) ||
(mMdl.getAnm().isStop() && mBirdAction == BIRD_ACTION_HOVER)) {
changeBirdAction("Glide", BIRD_ACTION_GLIDE, m3d::PLAY_MODE_4, 5.0f);
mBirdActionTimer = cM::rndInt(100) + 100;
}
}
}
bool dAcBirdBase_c::chkWallGndRoofHit() {
mVec3_c tmp;
tmp.set(mPosition); // unused
if (--mChkWallGndRoofTimer <= 0) {
mChkWallGndRoofTimer = cM::rndInt(10) + 20;
if (mObjAcch2.ChkWallHit(nullptr) || mObjAcch2.ChkGndHit() || mObjAcch2.ChkRoofHit()) {
mChkWallGndRoofTimer = 60;
handleWallGndRoofHit();
return true;
}
}
return false;
}
void dAcBirdBase_c::handleWallGndRoofHit() {
dBgS_ObjLinChk linChk;
mVec3_c start, end;
start.set(mPosition);
end.set(mPosition);
mVec3_c v1;
mMtx_c m1;
mMtx_c m2;
mAng rot1 = field_0xF5C.atan2sX_Z();
if (mObjAcch2.ChkGndHit()) {
end.set(mPosition);
v1.set(0.0f, 0.0f, 10000.0f);
m1.YrotS(rot1);
m1.XrotM(-0x4000);
MTXMultVec(m1, v1, v1);
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
end.set(mPosition);
v1.set(0.0f, 0.0f, 10000.0f);
m1.YrotS(rot1);
m1.XrotM(0x4000);
MTXMultVec(m1, v1, v1);
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
}
v1.set(0.0f, 0.0f, 10000.0f);
v1.rotY(rot1 + mAng(0x4000));
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
end.set(mPosition);
v1.set(0.0f, 0.0f, 10000.0f);
v1.rotY(rot1 - mAng(0x4000));
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
end.set(mPosition);
v1.set(0.0f, 0.0f, 10000.0f);
m2.YrotS(rot1);
m2.XrotM(0xC000);
MTXMultVec(m2, v1, v1);
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
end.set(mPosition);
v1.set(0.0f, 0.0f, 10000.0f);
m2.YrotS(rot1);
m2.XrotM(0x4000);
MTXMultVec(m2, v1, v1);
end += v1;
linChk.Set(&start, &end, nullptr);
if (!dBgS::GetInstance()->LineCross(&linChk)) {
field_0xF68.set(v1);
field_0xF68.normalizeRS();
return;
}
}