mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-28 07:54:51 -04:00
1395 lines
40 KiB
C++
1395 lines
40 KiB
C++
/**
|
|
* d_a_e_ge.cpp
|
|
* Enemy - Guay
|
|
*/
|
|
|
|
#include "d/dolzel_rel.h" // IWYU pragma: keep
|
|
|
|
#include "d/actor/d_a_boomerang.h"
|
|
#include "d/actor/d_a_e_ge.h"
|
|
#include "d/d_cc_d.h"
|
|
#include "f_op/f_op_actor_enemy.h"
|
|
#include "f_op/f_op_camera_mng.h"
|
|
|
|
|
|
class daE_GE_HIO_c : public JORReflexible {
|
|
public:
|
|
daE_GE_HIO_c();
|
|
virtual ~daE_GE_HIO_c() {}
|
|
|
|
void genMessage(JORMContext*);
|
|
|
|
/* 0x04 */ s8 id;
|
|
/* 0x08 */ f32 player_recognition_distance;
|
|
/* 0x0C */ f32 arrow_recognition_distance;
|
|
/* 0x10 */ f32 peer_recognition_distance;
|
|
/* 0x14 */ f32 attack_speed;
|
|
/* 0x18 */ f32 turning_speed;
|
|
/* 0x1C */ f32 attack_turn_altitude;
|
|
/* 0x20 */ f32 attack_turn_radius;
|
|
/* 0x24 */ f32 attack_start_angle;
|
|
/* 0x28 */ f32 add_attack_descent_speed;
|
|
/* 0x2C */ f32 minimum_attack_radius;
|
|
/* 0x30 */ f32 next_attack_timer;
|
|
};
|
|
|
|
enum daE_GE_Action {
|
|
/* 0 */ ACTION_WAIT,
|
|
/* 1 */ ACTION_FLY,
|
|
/* 2 */ ACTION_ATTACK,
|
|
/* 3 */ ACTION_BACK,
|
|
/* 4 */ ACTION_DOWN,
|
|
/* 5 */ ACTION_SURPRISE,
|
|
/* 6 */ ACTION_CAW,
|
|
/* 7 */ ACTION_WIND,
|
|
/* 8 */ ACTION_SHIELD,
|
|
/* 9 */ ACTION_MAX
|
|
};
|
|
|
|
static u8 hio_set;
|
|
|
|
static daE_GE_HIO_c l_HIO;
|
|
|
|
daE_GE_HIO_c::daE_GE_HIO_c() {
|
|
id = -1;
|
|
player_recognition_distance = 1000.0f;
|
|
arrow_recognition_distance = 300.0f;
|
|
peer_recognition_distance = 600.0f;
|
|
attack_speed = 15.0f;
|
|
turning_speed = 15.0f;
|
|
attack_turn_altitude = 600.0f;
|
|
attack_turn_radius = 1000.0f;
|
|
attack_start_angle = 28000.0f;
|
|
add_attack_descent_speed = 1.3f;
|
|
minimum_attack_radius = 500.0f;
|
|
next_attack_timer = 110.0f;
|
|
}
|
|
|
|
void daE_GE_c::bckSet(int i_index, f32 i_morf, u8 i_attr, f32 i_rate) {
|
|
J3DAnmTransform* transform = (J3DAnmTransform*)dComIfG_getObjectRes("E_GE", i_index);
|
|
mpMorfSO->setAnm(transform, i_attr, i_morf, i_rate, 0.0f, -1.0f);
|
|
}
|
|
|
|
bool daE_GE_c::bckCheck(int i_index) {
|
|
J3DAnmTransform* transform = (J3DAnmTransform*)dComIfG_getObjectRes("E_GE", i_index);
|
|
|
|
if (mpMorfSO->getAnm() == transform) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int daE_GE_c::draw() {
|
|
J3DModel* model = mpMorfSO->getModel();
|
|
g_env_light.settingTevStruct(0, ¤t.pos, &tevStr);
|
|
g_env_light.setLightTevColorType_MAJI(model, &tevStr);
|
|
mpMorfSO->entryDL();
|
|
cXyz modified_pos;
|
|
modified_pos.set(current.pos.x, current.pos.y + 100.0f, current.pos.z);
|
|
mShadowKey = dComIfGd_setShadow(mShadowKey, 1, model, &modified_pos, 400.0f, 0.0f,
|
|
current.pos.y, mObjAcch.GetGroundH(), mObjAcch.m_gnd, &tevStr,
|
|
0, 1.0f, dDlst_shadowControl_c::getSimpleTex());
|
|
return 1;
|
|
}
|
|
|
|
static int daE_GE_Draw(daE_GE_c* i_this) {
|
|
return i_this->draw();
|
|
}
|
|
|
|
bool daE_GE_c::checkBeforeBg(int param_0, f32 param_1) {
|
|
cXyz end;
|
|
if (param_0 == 0) {
|
|
cXyz vec(param_1, 0.0f, 300.0f);
|
|
cLib_offsetPos(&end, ¤t.pos, shape_angle.y, &vec);
|
|
} else {
|
|
mDoMtx_stack_c::copy(daPy_getLinkPlayerActorClass()->getModelJointMtx(0));
|
|
mDoMtx_stack_c::multVecZero(&end);
|
|
}
|
|
|
|
dBgS_LinChk linChk;
|
|
linChk.Set(¤t.pos, &end, NULL);
|
|
if (dComIfG_Bgsp().LineCross(&linChk)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void* s_arrow_sub(void* i_actor, void* i_data) {
|
|
if (fopAcM_IsActor(i_actor)) {
|
|
if (!fpcM_IsCreating(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_ARROW_e) {
|
|
if (fopAcM_GetSpeedF((fopAc_ac_c*)i_actor) &&
|
|
fopAcM_searchActorDistance((fopAc_ac_c*)i_actor, (fopAc_ac_c*)i_data) <
|
|
l_HIO.arrow_recognition_distance)
|
|
{
|
|
static_cast<daE_GE_c*>(i_data)->setSurpriseTime(cM_rndF(10.0f));
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void* s_ge_surprise(void* i_actor, void* i_data) {
|
|
if (fopAcM_IsActor(i_actor)) {
|
|
if (!fpcM_IsCreating(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_GE_e) {
|
|
if (fopAcM_searchActorDistance((fopAc_ac_c*)i_actor, (fopAc_ac_c*)i_data) <
|
|
l_HIO.peer_recognition_distance &&
|
|
static_cast<daE_GE_c*>(i_actor)->getSurpriseTime() == 0)
|
|
{
|
|
static_cast<daE_GE_c*>(i_actor)->setSurpriseTime(cM_rndF(5.0f) + 5.0f);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void* s_ge_caw(void* i_actor, void* i_data) {
|
|
if (fopAcM_IsActor(i_actor)) {
|
|
if (!fpcM_IsCreating(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_GE_e) {
|
|
if (i_actor != i_data &&
|
|
fopAcM_searchActorDistance((fopAc_ac_c*)i_actor, (fopAc_ac_c*)i_data) <
|
|
l_HIO.peer_recognition_distance)
|
|
{
|
|
static_cast<daE_GE_c*>(i_actor)->setCaw();
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static s32 target_count;
|
|
|
|
static void* s_ge_attack(void* i_actor, void* i_data) {
|
|
if (fopAcM_IsActor(i_actor)) {
|
|
if (!fpcM_IsCreating(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_GE_e) {
|
|
if (static_cast<daE_GE_c*>(i_actor)->getActionMode() == 2) {
|
|
target_count++;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void* s_ge_attack2(void* i_actor, void* i_data) {
|
|
if (fopAcM_IsActor(i_actor)) {
|
|
if (!fpcM_IsCreating(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_GE_e) {
|
|
if (static_cast<daE_GE_c*>(i_actor)->checkOtherAttacker()) {
|
|
target_count++;
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void daE_GE_c::setActionMode(int i_actionMode) {
|
|
mPrevActionMode = mActionMode;
|
|
mActionMode = i_actionMode;
|
|
mAnmChangeTimer = 0;
|
|
mSubMode = 0;
|
|
mMode = 0;
|
|
field_0xb8e[1] = 0;
|
|
field_0xb8e[0] = 0;
|
|
shape_angle.z = 0;
|
|
shape_angle.x = 0;
|
|
attention_info.distances[fopAc_attn_BATTLE_e] = 3;
|
|
}
|
|
|
|
void daE_GE_c::damage_check() {
|
|
if (mDamageCooldownTimer == 0) {
|
|
mStts.Move();
|
|
if (mActionMode != ACTION_DOWN) {
|
|
mAtInfo.mpCollider = NULL;
|
|
if (mSphere.ChkTgHit()) {
|
|
mAtInfo.mpCollider = mSphere.GetTgHitObj();
|
|
} else if (mSphere2.ChkTgHit()) {
|
|
mAtInfo.mpCollider = mSphere2.GetTgHitObj();
|
|
}
|
|
|
|
if (mAtInfo.mpCollider != NULL) {
|
|
cc_at_check(this, &mAtInfo);
|
|
|
|
if (mAtInfo.mpCollider->ChkAtType(AT_TYPE_UNK)) {
|
|
mDamageCooldownTimer = 20;
|
|
} else {
|
|
mDamageCooldownTimer = 10;
|
|
}
|
|
|
|
if (mAtInfo.mAttackPower <= 1) {
|
|
mDamageCooldownTimer = 10;
|
|
}
|
|
|
|
if (mAtInfo.mpCollider->ChkAtType(AT_TYPE_SHIELD_ATTACK)) {
|
|
setActionMode(ACTION_SHIELD);
|
|
} else if (mMoveType != 2 && mAtInfo.mpCollider->ChkAtType(AT_TYPE_BOOMERANG)) {
|
|
if (mActionMode != ACTION_WIND) {
|
|
setActionMode(ACTION_WIND);
|
|
}
|
|
} else {
|
|
cXyz position;
|
|
|
|
mDoMtx_stack_c::copy(mpMorfSO->getModel()->getAnmMtx(3));
|
|
mDoMtx_stack_c::multVecZero(&position);
|
|
dComIfGp_setHitMark(3, this, &position, NULL, NULL, 0);
|
|
|
|
setActionMode(ACTION_DOWN);
|
|
|
|
if (!mAtInfo.mpCollider->ChkAtType(AT_TYPE_ARROW)) {
|
|
speedF = cM_rndF(5.0f) + 15.0f;
|
|
speed.y = cM_rndF(5.0f) + 55.0f;
|
|
} else {
|
|
fpcM_Search(s_ge_surprise, this);
|
|
speedF = cM_rndF(5.0f) + 5.0f;
|
|
speed.y = cM_rndF(5.0f) + 25.0f;
|
|
}
|
|
shape_angle.y = mAtInfo.mHitDirection.y + 0x8000;
|
|
field_0xb68 = 30.0f;
|
|
mHitDirectionY = mAtInfo.mHitDirection.y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool daE_GE_c::checkOtherAttacker() {
|
|
if (mActionMode != ACTION_ATTACK) {
|
|
return false;
|
|
}
|
|
if (mMode != 2) {
|
|
return false;
|
|
}
|
|
|
|
if (!(field_0xb8e[0] < 200.0f - l_HIO.next_attack_timer)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool daE_GE_c::searchNextAttacker() {
|
|
if (mMoveType == 2) {
|
|
return false;
|
|
}
|
|
|
|
target_count = 0;
|
|
fpcM_Search(s_ge_attack, this);
|
|
if (target_count >= 2) {
|
|
return false;
|
|
}
|
|
|
|
setActionMode(ACTION_ATTACK);
|
|
field_0xb8e[1] = cM_rndF(300.0f) + 700.0f;
|
|
return true;
|
|
}
|
|
|
|
bool daE_GE_c::checkCircleSpeedAdd(cXyz* i_src, cXyz* param_1) {
|
|
cXyz position;
|
|
cLib_offsetPos(&position, i_src, field_0xb8c, param_1);
|
|
s16 targetAngleY = cLib_targetAngleY(i_src, &position);
|
|
|
|
return abs((s16)(field_0xb8c - targetAngleY)) < 0x2000;
|
|
}
|
|
|
|
void daE_GE_c::setAddCalcSpeed(cXyz& param_0, cXyz const& param_1, f32 param_2, f32 param_3,
|
|
f32 param_4, f32 param_5) {
|
|
// Can't prove that this exists in debug but it seems necessary for the logic
|
|
cXyz diff_vec = param_1 - param_0;
|
|
f32 diff = diff_vec.abs();
|
|
cXyz speed_vec(0.0f, 0.0f, 0.0f);
|
|
|
|
if (param_0 != param_1 && diff >= param_4) {
|
|
diff *= param_2;
|
|
diff_vec *= param_2;
|
|
if (!cLib_IsZero(diff)) {
|
|
if (diff > param_3) {
|
|
speed_vec = (diff_vec * param_3) / diff;
|
|
} else if (diff < param_4) {
|
|
speed_vec = (diff_vec * param_4) / diff;
|
|
}
|
|
}
|
|
}
|
|
|
|
speedF = speed_vec.absXZ();
|
|
cLib_chaseF(&speed.y, speed_vec.y, param_5);
|
|
}
|
|
|
|
cXyz daE_GE_c::calcCircleFly(cXyz* i_src, cXyz* i_vec, s16 i_angle, f32 param_3, s16 i_scale,
|
|
f32 param_5) {
|
|
cXyz position;
|
|
|
|
if (i_vec != 0x0) {
|
|
cLib_offsetPos(&position, i_src, i_angle, i_vec);
|
|
} else {
|
|
position = *i_src;
|
|
}
|
|
cLib_addCalcAngleS(&shape_angle.y, (s16)cLib_targetAngleY(¤t.pos, &position), i_scale,
|
|
0x800, 0x100);
|
|
current.angle.y = shape_angle.y;
|
|
setAddCalcSpeed(current.pos, position, 8.0f, param_3, 1.0f, param_5);
|
|
|
|
return current.pos - position;
|
|
}
|
|
|
|
void daE_GE_c::executeWait() {
|
|
fpcM_Search(s_arrow_sub, this);
|
|
|
|
switch (mMode) {
|
|
case 0:
|
|
bckSet(0xC, 3.0f, 2, 1.0f);
|
|
mMode = 1;
|
|
field_0xb8e[0] = (s16)(cM_rndF(300.f) + 300.0f);
|
|
speedF = 0.0f;
|
|
speed.y = 0.0f;
|
|
/* fallthrough */
|
|
|
|
case 1:
|
|
if (field_0xb8e[0] == 0) {
|
|
mMode = 3;
|
|
} else if (field_0xb8e[1] == 0 &&
|
|
fopAcM_searchPlayerDistanceXZ(this) < l_HIO.player_recognition_distance)
|
|
{
|
|
bckSet(5, 3.0f, 0, 1.0f);
|
|
mMode = 2;
|
|
fpcM_Search(s_ge_caw, this);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (mpMorfSO->checkFrame(6.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_NAKU, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
setActionMode(ACTION_CAW);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
bckSet(5, 3.0f, 0, 1.0f);
|
|
mMode = 4;
|
|
break;
|
|
|
|
case 4:
|
|
if (mpMorfSO->checkFrame(6.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_NAKU, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
mMode = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::executeFly() {
|
|
daPy_py_c* player = daPy_getPlayerActorClass();
|
|
cXyz position;
|
|
|
|
f32 turning_speed = l_HIO.turning_speed;
|
|
if (mMoveType == 2) {
|
|
turning_speed = 8.0f;
|
|
}
|
|
|
|
switch (mMode) {
|
|
case 10:
|
|
case 0:
|
|
field_0xb9e = 0;
|
|
if (mMode == 10) {
|
|
bckSet(7, 10.0f, 2, 1.0f);
|
|
} else {
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
}
|
|
mMode = 1;
|
|
if (cM_rnd() < 0.5f) {
|
|
field_0xb9d = true;
|
|
} else {
|
|
field_0xb9d = false;
|
|
}
|
|
|
|
if (field_0xb9d) {
|
|
field_0xb8a = (s16)(cM_rndFX(5.0f) * 20.0f + 400.0f);
|
|
} else {
|
|
field_0xb8a = (s16)(cM_rndFX(5.0f) * 20.0f + -400.0f);
|
|
}
|
|
mAnmChangeTimer = (s16)(cM_rndF(30.0f) + 30.0f);
|
|
mSubMode = 0;
|
|
field_0xb5c = 0.0f;
|
|
break;
|
|
|
|
case 1:
|
|
if (mSubMode == 0) {
|
|
field_0xb5c += 4.0f;
|
|
if (mpMorfSO->checkFrame(0.0f) && field_0xb5c >= 0.0f) {
|
|
bckSet(10, 10.0f, 2, 1.0f);
|
|
mAnmChangeTimer = (s16)(cM_rndF(50.0f) + 50.0f);
|
|
mSubMode = 1;
|
|
}
|
|
} else {
|
|
field_0xb5c -= 3.0f;
|
|
if (mAnmChangeTimer == 0) {
|
|
bckSet(7, 10.0f, 2, 1.0f);
|
|
mSubMode = 0;
|
|
}
|
|
}
|
|
|
|
position.set(0.0f, field_0xb5c, 1000.0f);
|
|
|
|
if (checkCircleSpeedAdd(&home.pos, &position)) {
|
|
field_0xb8c += field_0xb8a;
|
|
}
|
|
|
|
calcCircleFly(&home.pos, &position, field_0xb8c, turning_speed, 6, 1.0f);
|
|
|
|
if (field_0xb8e[1] == 0) {
|
|
if (player->current.pos.absXZ(home.pos) < 2000.0f &&
|
|
fopAcM_searchPlayerDistanceXZ(this) < l_HIO.player_recognition_distance)
|
|
{
|
|
bckSet(4, 3.0f, 0, 1.0f);
|
|
mMode = 2;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
position.set(0.0f, 0.0f, 1000.0f);
|
|
|
|
if (checkCircleSpeedAdd(&home.pos, &position)) {
|
|
field_0xb8c += field_0xb8a;
|
|
}
|
|
|
|
calcCircleFly(&home.pos, &position, field_0xb8c, turning_speed, 6, 1.0f);
|
|
|
|
if (mpMorfSO->checkFrame(3.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_NAKU, -1);
|
|
}
|
|
|
|
if (mpMorfSO->isStop() && !searchNextAttacker()) {
|
|
mMode = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool daE_GE_c::checkAttackPossible(s16 i_angle, bool param_1) {
|
|
if (field_0xb8e[0] == 0 && (i_angle > (s16)l_HIO.attack_start_angle || param_1)) {
|
|
if (fopAcM_searchPlayerDistanceXZ(this) < l_HIO.minimum_attack_radius) {
|
|
return false;
|
|
}
|
|
target_count = 0;
|
|
fpcM_Search(s_ge_attack2, this);
|
|
if (target_count == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void daE_GE_c::executeAttack() {
|
|
daPy_py_c* player = daPy_getPlayerActorClass();
|
|
cXyz position;
|
|
mDoMtx_stack_c::copy(daPy_getLinkPlayerActorClass()->getModelJointMtx(0));
|
|
mDoMtx_stack_c::multVecZero(&position);
|
|
|
|
camera_process_class* camera = dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0));
|
|
s16 distAngleS =
|
|
cLib_distanceAngleS(fopCamM_GetAngleY(camera), fopAcM_searchPlayerAngleY(this));
|
|
|
|
cXyz flyVec;
|
|
|
|
// I don't think these cXyz's are correct like this in debug but I have no better solution
|
|
cXyz temp;
|
|
cXyz temp2;
|
|
|
|
temp = position - home.pos;
|
|
if (temp.absXZ() > 2500.0f) {
|
|
setActionMode(ACTION_BACK);
|
|
return;
|
|
}
|
|
|
|
bool bVar = false;
|
|
if (dComIfGp_getAttention()->LockonTruth() && dComIfGp_getAttention()->LockonTarget(0) == this)
|
|
{
|
|
bVar = true;
|
|
}
|
|
|
|
switch (mMode) {
|
|
case 0:
|
|
field_0xb9e = 0;
|
|
field_0xb8e[0] = (s16)(cM_rndF(100.0f) + 100.0f);
|
|
field_0xb8a = (s16)(260892.0f / l_HIO.attack_turn_radius + cM_rndFX(128.0f));
|
|
if (cM_rnd() < 0.5f) {
|
|
field_0xb8a = -field_0xb8a;
|
|
}
|
|
mMode = 1;
|
|
mAnmChangeTimer = (s16)(cM_rndF(30.0f) + 30.0f);
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
attention_info.distances[fopAc_attn_BATTLE_e] = 4;
|
|
field_0xb5c = 0.0f;
|
|
/* fallthrough */
|
|
|
|
case 1:
|
|
if (field_0xb8e[1] == 0 && getMoveType() == 0) {
|
|
temp2 = current.pos - home.pos;
|
|
if (temp2.absXZ() > 1000.0f) {
|
|
setActionMode(ACTION_BACK);
|
|
return;
|
|
}
|
|
}
|
|
switch (mSubMode) {
|
|
case 0:
|
|
field_0xb5c += 4.0f;
|
|
if (field_0xb5c >= 0.0f) {
|
|
bckSet(10, 10.0f, 2, 1.0f);
|
|
mAnmChangeTimer = (s16)(cM_rndF(50.0f) + 50.0f);
|
|
mSubMode = 1;
|
|
}
|
|
|
|
break;
|
|
case 1:
|
|
field_0xb5c -= 3.0f;
|
|
if (mAnmChangeTimer == 0) {
|
|
bckSet(7, 10.0f, 2, 1.0f);
|
|
mSubMode = 0;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
bckSet(8, 3.0f, 0, 1.0f);
|
|
mSubMode = 3;
|
|
/* fallthrough */
|
|
|
|
case 3:
|
|
mSound.startCreatureSoundLevel(Z2SE_EN_GE_GLIDE, 0, -1);
|
|
if (mpMorfSO->checkFrame(12.0f) || mpMorfSO->checkFrame(19.0f) ||
|
|
mpMorfSO->checkFrame(26.0f))
|
|
{
|
|
mSound.startCreatureSound(Z2SE_EN_GE_WING, 0, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
mSubMode = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (checkAttackPossible(distAngleS, bVar)) {
|
|
bckSet(4, 10.0f, 0, 1.0f);
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_ATTACK, -1);
|
|
field_0xb4c = position;
|
|
field_0xb8c += 0x8000;
|
|
mMode = 2;
|
|
mSubMode = 0;
|
|
field_0xb8e[0] = 200;
|
|
mCircleFlyScale = 14;
|
|
return;
|
|
}
|
|
flyVec.set(0.0f, l_HIO.attack_turn_altitude + field_0xb5c, l_HIO.attack_turn_radius);
|
|
if (checkCircleSpeedAdd(&position, &flyVec)) {
|
|
field_0xb8c += field_0xb8a;
|
|
}
|
|
calcCircleFly(&position, &flyVec, field_0xb8c, l_HIO.turning_speed, 6, 1.0f);
|
|
break;
|
|
|
|
case 2:
|
|
if (mSubMode == 0) {
|
|
if (mpMorfSO->checkFrame(3.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_NAKU, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
bckSet(10, 3.0f, 2, 1.0f);
|
|
mSubMode = 1;
|
|
}
|
|
}
|
|
mSphere.OnAtSetBit();
|
|
flyVec.set(0.0f, 0.0f, 0.0f);
|
|
|
|
temp = calcCircleFly(&field_0xb4c, &flyVec, 0x0, l_HIO.attack_speed, mCircleFlyScale, 1.0f);
|
|
if (temp.abs() > 300.0f) {
|
|
field_0xb4c = position;
|
|
field_0xb8c = shape_angle.y;
|
|
if (temp.y >= 200.0f) {
|
|
speed.y -= l_HIO.add_attack_descent_speed;
|
|
}
|
|
if (distAngleS < (s16)(l_HIO.attack_start_angle - 4096.0f) && !bVar) {
|
|
field_0xb8e[0] = 0;
|
|
}
|
|
} else {
|
|
mCircleFlyScale = 8;
|
|
}
|
|
|
|
if (temp.abs() < 100.0f || field_0xb8e[0] == 0 || checkBeforeBg(1, 0.0f)) {
|
|
bckSet(7, 1.0f, 2, 1.0f);
|
|
mMode = 3;
|
|
field_0xb8e[0] = 0;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
mSphere.OnAtSetBit();
|
|
flyVec.set(0.0f, l_HIO.attack_turn_altitude, l_HIO.attack_turn_radius);
|
|
// I don't think this cXyz is correct in debug but abs() and y are needed from this
|
|
// variable.
|
|
temp = calcCircleFly(&position, &flyVec, field_0xb8c, l_HIO.attack_speed, 6, 0.5f);
|
|
if (temp.abs() < 400.0f || mObjAcch.ChkWallHit()) {
|
|
mMode = 0;
|
|
}
|
|
break;
|
|
}
|
|
cLib_chaseAngleS(&shape_angle.x, cM_atan2s(speedF, speed.y) - 0x4000, 0x180);
|
|
}
|
|
|
|
void daE_GE_c::setBackAnime(int param_0) {
|
|
if (speed.y > 0.0f || mBackAnimeTimer != 0) {
|
|
J3DAnmTransform* anm = (J3DAnmTransform*)dComIfG_getObjectRes("E_GE", 7);
|
|
if (mpMorfSO->getAnm() != anm) {
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
}
|
|
} else if (speed.y < 0.0f) {
|
|
if (param_0) {
|
|
bckSet(6, 20.0f, 2, 1.0f);
|
|
} else {
|
|
bckSet(10, 20.0f, 2, 1.0f);
|
|
}
|
|
}
|
|
|
|
if (bckCheck(6)) {
|
|
mSound.startCreatureSoundLevel(Z2SE_EN_GE_GLIDE, 0, -1);
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::executeBack() {
|
|
cXyz position;
|
|
cXyz position2;
|
|
s16 chaseAngle = 0x0;
|
|
s16 distAngleS;
|
|
|
|
switch (mMode) {
|
|
case 0:
|
|
case 10:
|
|
field_0xb9e = 0;
|
|
if (getMoveType() != 0) {
|
|
setActionMode(ACTION_FLY);
|
|
} else {
|
|
if (mMode == 10) {
|
|
bckSet(7, 10.0f, 2, 1.0f);
|
|
} else {
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
}
|
|
if (current.pos.absXZ(home.pos) < 1500.0f) {
|
|
mMode = 1;
|
|
field_0xb8a = 32;
|
|
} else {
|
|
mMode = 2;
|
|
}
|
|
field_0xb58 = l_HIO.turning_speed;
|
|
field_0xb8c = cLib_targetAngleY(&home.pos, ¤t.pos);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
setBackAnime(0);
|
|
|
|
if (field_0xb8a > 8) {
|
|
field_0xb8a--;
|
|
}
|
|
|
|
position2.set(0.0f, 200.0f, 1000.0f);
|
|
position =
|
|
calcCircleFly(&home.pos, &position2, field_0xb8c, field_0xb58, field_0xb8a, 1.0f);
|
|
|
|
distAngleS =
|
|
cLib_distanceAngleS(cLib_targetAngleY(¤t.pos, &home.pos), shape_angle.y);
|
|
if (position.y > 100.0f || mObjAcch.ChkWallHit() || distAngleS >= 0x5000) {
|
|
field_0xb8c += 0x190;
|
|
}
|
|
|
|
if (position.abs() < 50.0f) {
|
|
mMode = 2;
|
|
}
|
|
|
|
chaseAngle = cM_atan2s(speedF, speed.y) - 0x4000;
|
|
break;
|
|
|
|
case 2:
|
|
if (mSubMode == 0) {
|
|
s16 targetAngleY = cLib_targetAngleY(¤t.pos, &home.pos);
|
|
if ((s16)cLib_distanceAngleS(targetAngleY, shape_angle.y) <= 0x800) {
|
|
field_0xb8c = targetAngleY + 0x8000;
|
|
mSubMode = 1;
|
|
}
|
|
}
|
|
position2.set(0.0f, 100.0f, 400.0f);
|
|
position = calcCircleFly(&home.pos, &position2, field_0xb8c, field_0xb58, 0x10, 1.0f);
|
|
|
|
if (position.y < 150.0f && position.abs() < 700.0f) {
|
|
setBackAnime(1);
|
|
} else {
|
|
setBackAnime(0);
|
|
}
|
|
|
|
if (position.abs() < 50.0f) {
|
|
mMode = 3;
|
|
bckSet(0xB, 3.0f, 0, 1.0f);
|
|
field_0xb8e[0] = 10;
|
|
speed.y = 0.0f;
|
|
field_0xb9e = 1;
|
|
}
|
|
|
|
chaseAngle = cM_atan2s(speedF, speed.y) - 0x4000;
|
|
break;
|
|
|
|
case 3:
|
|
if (mpMorfSO->checkFrame(5.0f)) {
|
|
mpMorfSO->setPlaySpeed(0.0f);
|
|
}
|
|
|
|
cLib_chaseF(&field_0xb58, 15.0f, 1.0f);
|
|
|
|
position2.set(0.0f, 140.0f, 200.0f);
|
|
position = calcCircleFly(&home.pos, &position2, field_0xb8c, field_0xb58, 4, 1.0f);
|
|
|
|
if (position.abs() < 50.0f) {
|
|
mMode = 4;
|
|
mpMorfSO->setPlaySpeed(1.0f);
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
if (mpMorfSO->checkFrame(17.0f) || mpMorfSO->checkFrame(24.0f)) {
|
|
mSound.startCreatureSound(Z2SE_EN_GE_WING, 0, -1);
|
|
}
|
|
|
|
s16 oldShapeAngleY = shape_angle.y;
|
|
|
|
cLib_chaseF(&field_0xb58, 0.0f, 1.0f);
|
|
|
|
position2.set(0.0f, 0.0f, 0.0f);
|
|
calcCircleFly(&home.pos, &position2, field_0xb8c, field_0xb58, 4, 1.0f);
|
|
shape_angle.y = current.angle.y = oldShapeAngleY;
|
|
|
|
if (cLib_addCalcPos(¤t.pos, home.pos, 0.1f, 15.0f - field_0xb58, 1.0f) < 4.0f) {
|
|
if (mpMorfSO->isStop()) {
|
|
old.pos = home.pos;
|
|
current.pos = old.pos;
|
|
if (mPrevActionMode == ACTION_CAW) {
|
|
setActionMode(ACTION_CAW);
|
|
field_0xb8e[1] = 100;
|
|
return;
|
|
}
|
|
|
|
setActionMode(ACTION_WAIT);
|
|
return;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
cLib_chaseAngleS(&shape_angle.x, chaseAngle, 0x180);
|
|
}
|
|
|
|
void daE_GE_c::executeDown() {
|
|
mDamageCooldownTimer = 10;
|
|
|
|
if (speed.y >= 0.0f) {
|
|
cLib_chaseF(&speed.y, -50.0f, 5.0f);
|
|
} else {
|
|
cLib_chaseF(&speed.y, -50.0f, 3.0f);
|
|
}
|
|
|
|
switch (mMode) {
|
|
case 0:
|
|
#if !DEBUG
|
|
mSphere.OffTgSetBit();
|
|
mSphere2.OffTgSetBit();
|
|
#endif
|
|
fopAcM_OffStatus(this, fopAcStts_UNK_0x20_e);
|
|
field_0xb9e = 0;
|
|
attention_info.flags = 0;
|
|
bckSet(4, 3.0f, 2, 1.0f);
|
|
mMode = 1;
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_DEATH, -1);
|
|
field_0xb8a = 0;
|
|
current.angle.y = (s16)((mAtInfo.mHitDirection.y + 0x8000) + cM_rndFX(4096.0f));
|
|
if (mMoveType != 2) {
|
|
field_0xb8e[0] = 0x96;
|
|
} else {
|
|
field_0xb8e[0] = 0x5A;
|
|
}
|
|
/* fallthrough */
|
|
|
|
case 1:
|
|
if (field_0xb8e[0] == 0) {
|
|
fopAcM_createDisappear(this, ¤t.pos, 10, 0, 0x21);
|
|
fopAcM_delete(this);
|
|
dComIfGs_onSwitch(mSwitch, fopAcM_GetRoomNo(this));
|
|
} else {
|
|
if (mObjAcch.ChkGroundHit()) {
|
|
mSound.startCreatureSound(Z2SE_CM_BODYFALL_S, 0, -1);
|
|
fopAcM_effSmokeSet1(&mSmokeKey, &mSmokeKey2, ¤t.pos, NULL, 1.0f, &tevStr, 1);
|
|
field_0xb8e[0] = 0;
|
|
mMode = 2;
|
|
speed.y = 20.0f;
|
|
speedF = 5.0f;
|
|
shape_angle.x = -0x8000;
|
|
shape_angle.z = 0x0;
|
|
mObjAcch.SetGroundUpY(20.0f);
|
|
}
|
|
shape_angle.z += 0x800;
|
|
cLib_addCalcAngleS(&shape_angle.x, 0x4000, 8, 0x1000, 0x10);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
cLib_addCalcAngleS(&shape_angle.x, -0x8000, 8, 0x1000, 0x10);
|
|
if (mObjAcch.ChkGroundHit()) {
|
|
mSound.startCreatureSound(Z2SE_CM_BODYFALL_S, 0, -1);
|
|
fopAcM_effSmokeSet1(&mSmokeKey, &mSmokeKey2, ¤t.pos, NULL, 1.0f, &tevStr, 1);
|
|
speed.y = 0.0f;
|
|
speedF = 0.0f;
|
|
mMode = 3;
|
|
mpMorfSO->setFrame(16.0f);
|
|
mpMorfSO->setPlaySpeed(0.5f);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (mpMorfSO->checkFrame(23.0f)) {
|
|
field_0xb8e[0] = 0;
|
|
mMode = 4;
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
if (field_0xb8e[0] == 0) {
|
|
fopAcM_createDisappear(this, ¤t.pos, 10, 0, 0x21);
|
|
fopAcM_delete(this);
|
|
dComIfGs_onSwitch(mSwitch, fopAcM_GetRoomNo(this));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::setSurpriseTime(s16 i_surpriseTime) {
|
|
if (getMoveType() == 0 && (mActionMode == ACTION_WAIT || mActionMode == ACTION_CAW)) {
|
|
mSurpriseTime = i_surpriseTime;
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::setSurprise() {
|
|
if (getMoveType() == 0 && (mActionMode == ACTION_WAIT || mActionMode == ACTION_CAW)) {
|
|
setActionMode(ACTION_SURPRISE);
|
|
}
|
|
fpcM_Search(s_ge_surprise, this);
|
|
}
|
|
|
|
void daE_GE_c::executeSurprise() {
|
|
cXyz vec;
|
|
|
|
switch (mMode) {
|
|
case 0:
|
|
field_0xb9e = 0;
|
|
bckSet(8, 3.0f, 0, 1.0f);
|
|
field_0xb8e[0] = (s16)(cM_rndF(100.0f) + 150.0f);
|
|
mMode = 1;
|
|
field_0xb8c = (s16)cM_rndFX(32768.0f);
|
|
vec.set(0.0f, cM_rndFX(300.0f) + 800.0f, cM_rndFX(1500.0f));
|
|
cLib_offsetPos(&field_0xb4c, &home.pos, (s16)cM_rndFX(32768.0f), &vec);
|
|
/* fallthrough */
|
|
|
|
case 1:
|
|
if (bckCheck(8)) {
|
|
mSound.startCreatureSoundLevel(Z2SE_EN_GE_GLIDE, 0, -1);
|
|
if (mpMorfSO->checkFrame(12.0f) || mpMorfSO->checkFrame(19.0f) ||
|
|
mpMorfSO->checkFrame(26.0f))
|
|
{
|
|
mSound.startCreatureSound(Z2SE_EN_GE_WING, 0, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
bckSet(7, 3.0f, 2, 1.0f);
|
|
}
|
|
}
|
|
|
|
vec.set(0.0f, 0.0f, 700.0f);
|
|
calcCircleFly(&field_0xb4c, &vec, field_0xb8c, l_HIO.turning_speed, 6, 1.0f);
|
|
field_0xb8c += 0x258;
|
|
|
|
if (field_0xb8e[0] == 0) {
|
|
if (searchNextAttacker()) {
|
|
break;
|
|
}
|
|
if (daPy_getPlayerActorClass()->current.pos.absXZ(home.pos) > 1000.0f) {
|
|
if (mPrevActionMode == ACTION_CAW) {
|
|
mActionMode = ACTION_CAW;
|
|
}
|
|
setActionMode(ACTION_BACK);
|
|
break;
|
|
}
|
|
field_0xb8e[0] = (s16)(cM_rndF(50.0f) + 70.0f);
|
|
// fallthrough
|
|
}
|
|
default:
|
|
s16 targetAngle = cM_atan2s(speedF, speed.y) - 0x4000;
|
|
|
|
if (targetAngle < -6000) {
|
|
targetAngle = -6000;
|
|
}
|
|
if (targetAngle > 6000) {
|
|
targetAngle = 6000;
|
|
}
|
|
cLib_chaseAngleS(&shape_angle.x, targetAngle, 0x180);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::setCaw() {
|
|
if (getMoveType() == 0 && mActionMode == ACTION_WAIT) {
|
|
setActionMode(ACTION_CAW);
|
|
field_0xb8e[1] = cM_rndFX(30.0f) + 40.0f;
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::executeCaw() {
|
|
fpcM_Search(s_arrow_sub, this);
|
|
|
|
daPy_py_c* player = daPy_getPlayerActorClass();
|
|
// Also not sure if this is in debug since debug doesn't show a ctor
|
|
cXyz diff = player->current.pos - home.pos;
|
|
|
|
if (diff.absXZ() > 2000.0f) {
|
|
setActionMode(ACTION_WAIT);
|
|
} else if (getMoveType() == 0 && diff.absXZ() < 500.0f) {
|
|
setActionMode(ACTION_SURPRISE);
|
|
} else {
|
|
switch (mMode) {
|
|
case 0:
|
|
if (field_0xb8e[1] == 0) {
|
|
bckSet(5, 3.0f, 0, 1.0f);
|
|
mMode = 1;
|
|
if (mSubMode == 0) {
|
|
fpcM_Search(s_ge_caw, this);
|
|
mSubMode = 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (mpMorfSO->checkFrame(6.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_NAKU, -1);
|
|
}
|
|
if (mpMorfSO->isStop()) {
|
|
setActionMode(ACTION_ATTACK);
|
|
field_0xb8e[1] = (s16)(cM_rndF(300.0f) + 700.0f);
|
|
mSubMode = 2;
|
|
} else if (field_0xb8e[0] == 0) {
|
|
mMode = 0;
|
|
field_0xb8e[0] = (s16)(cM_rndFX(50.0f) + 50.0f);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::executeWind() {
|
|
if (daPy_py_c::getThrowBoomerangActor() == NULL && mMode != 2) {
|
|
mMode = 2;
|
|
field_0xb8e[0] = (s16)(cM_rndFX(30.0f) + 60.0f);
|
|
}
|
|
|
|
switch (mMode) {
|
|
case 0: {
|
|
field_0xb9e = 0;
|
|
cXyz boomerangPos(daPy_py_c::getThrowBoomerangActor()->current.pos);
|
|
field_0xb58 = current.pos.absXZ(boomerangPos);
|
|
field_0xb5c = current.pos.y - boomerangPos.y;
|
|
speedF = speed.y = 0.0f;
|
|
mMode = 1;
|
|
bckSet(9, 3.0f, 2, 1.0f);
|
|
field_0xb64 = cM_rndFX(50.0f);
|
|
field_0xb60 = cM_rndFX(100.0f);
|
|
}
|
|
/* fallthrough */
|
|
|
|
case 1: {
|
|
if (mpMorfSO->checkFrame(0.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_FURA, -1);
|
|
}
|
|
|
|
cXyz boomerangPos2(daPy_py_c::getThrowBoomerangActor()->current.pos);
|
|
ANGLE_ADD(field_0xb8c, 0x800);
|
|
current.pos.x = boomerangPos2.x + field_0xb58 * cM_ssin(field_0xb8c);
|
|
current.pos.z = boomerangPos2.z + field_0xb58 * cM_scos(field_0xb8c);
|
|
cLib_chaseF(&field_0xb58, field_0xb60, 2.0f);
|
|
current.pos.y = boomerangPos2.y + field_0xb5c;
|
|
|
|
if (field_0xb5c < 50.0f) {
|
|
cLib_chaseF(&field_0xb5c, field_0xb64, 10.0f);
|
|
} else {
|
|
cLib_chaseF(&field_0xb5c, field_0xb64, 5.0f);
|
|
}
|
|
|
|
field_0xb8a = 0x3000;
|
|
shape_angle.y += field_0xb8a;
|
|
break;
|
|
}
|
|
|
|
case 2:
|
|
cLib_addCalcAngleS2(&field_0xb8a, 0, 4, 0x180);
|
|
shape_angle.y += field_0xb8a;
|
|
if (field_0xb8e[0] == 0) {
|
|
if (getMoveType() != 0) {
|
|
setActionMode(ACTION_FLY);
|
|
mMode = 10;
|
|
break;
|
|
}
|
|
mBackAnimeTimer = 90;
|
|
setActionMode(ACTION_BACK);
|
|
mMode = 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
void daE_GE_c::executeShield() {
|
|
switch (mMode) {
|
|
case 0:
|
|
field_0xb9e = 0;
|
|
speedF = 20.0f;
|
|
speed.y = 0.0f;
|
|
mMode = 1;
|
|
bckSet(9, 3.0f, 2, 1.0f);
|
|
field_0xb8e[0] = 60;
|
|
current.angle.y = fopAcM_searchPlayerAngleY(this) + 0x8000;
|
|
/* fallthrough */
|
|
case 1:
|
|
if (mpMorfSO->checkFrame(0.0f)) {
|
|
mSound.startCreatureVoice(Z2SE_EN_GE_V_FURA, -1);
|
|
}
|
|
|
|
cLib_chaseF(&speedF, 0.0f, 1.5f);
|
|
cLib_chaseF(&speed.y, 0.0f, 1.0f);
|
|
cLib_addCalcAngleS(&shape_angle.y, current.angle.y + 0x8000, 8, 0x400, 0x80);
|
|
|
|
if (field_0xb8e[0] == 0) {
|
|
if (getMoveType() != 0) {
|
|
setActionMode(ACTION_FLY);
|
|
mMode = 10;
|
|
} else {
|
|
mBackAnimeTimer = 90;
|
|
setActionMode(ACTION_BACK);
|
|
mMode = 10;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
daE_GE_c::actionFunc daE_GE_c::l_actionmenu[9] = {
|
|
(&daE_GE_c::executeWait), (&daE_GE_c::executeFly), (&daE_GE_c::executeAttack),
|
|
(&daE_GE_c::executeBack), (&daE_GE_c::executeDown), (&daE_GE_c::executeSurprise),
|
|
(&daE_GE_c::executeCaw), (&daE_GE_c::executeWind), (&daE_GE_c::executeShield),
|
|
};
|
|
|
|
void daE_GE_c::action() {
|
|
mSphere.OffAtSetBit();
|
|
damage_check();
|
|
s16 angleY = shape_angle.y;
|
|
|
|
if (mActionMode < ACTION_MAX) {
|
|
(this->*l_actionmenu[mActionMode])();
|
|
}
|
|
|
|
if (bckCheck(7) && mpMorfSO->checkFrame(0.0f)) {
|
|
mSound.startCreatureSound(Z2SE_EN_GE_WING, 0, -1);
|
|
}
|
|
|
|
if (mActionMode == ACTION_ATTACK) {
|
|
mSound.setLinkSearch(true);
|
|
} else {
|
|
mSound.setLinkSearch(false);
|
|
}
|
|
|
|
if (mActionMode != ACTION_DOWN) {
|
|
f32 actor_speed = speedF;
|
|
if (actor_speed >= 20.0f) {
|
|
actor_speed = 20.0f;
|
|
}
|
|
|
|
s16 targetAngle = (angleY - shape_angle.y) * 7;
|
|
targetAngle = targetAngle * actor_speed / 20.0f;
|
|
|
|
if (targetAngle < -0x2000) {
|
|
targetAngle = -0x2000;
|
|
}
|
|
if (targetAngle > 0x2000) {
|
|
targetAngle = 0x2000;
|
|
}
|
|
cLib_chaseAngleS(&shape_angle.z, targetAngle, 0x400);
|
|
}
|
|
|
|
cXyz speed_vec;
|
|
cXyz mult_vec;
|
|
|
|
mDoMtx_stack_c::YrotS(current.angle.y);
|
|
speed_vec.set(0.0f, 0.0f, speedF);
|
|
mDoMtx_stack_c::multVec(&speed_vec, &mult_vec);
|
|
|
|
speed.x = mult_vec.x;
|
|
speed.z = mult_vec.z;
|
|
|
|
current.pos += speed;
|
|
|
|
cXyz* ccMoveP = mStts.GetCCMoveP();
|
|
if (ccMoveP != NULL) {
|
|
current.pos.x += ccMoveP->x;
|
|
current.pos.y += ccMoveP->y;
|
|
current.pos.z += ccMoveP->z;
|
|
}
|
|
|
|
if (field_0xb9e == 0) {
|
|
mObjAcch.CrrPos(dComIfG_Bgsp());
|
|
}
|
|
|
|
mpMorfSO->play(0, dComIfGp_getReverb(fopAcM_GetRoomNo(this)));
|
|
}
|
|
|
|
void daE_GE_c::mtx_set() {
|
|
mDoMtx_stack_c::transS(current.pos);
|
|
mDoMtx_stack_c::ZXYrotM(shape_angle);
|
|
mpMorfSO->getModel()->setBaseTRMtx(mDoMtx_stack_c::get());
|
|
mpMorfSO->modelCalc();
|
|
}
|
|
|
|
void daE_GE_c::cc_set() {
|
|
MTXCopy(mpMorfSO->getModel()->getAnmMtx(2), mDoMtx_stack_c::get());
|
|
|
|
mDoMtx_stack_c::multVecZero(&eyePos);
|
|
|
|
if (mMoveType == 2) {
|
|
mSphere.SetC(eyePos);
|
|
mSphere.SetR(30.0f);
|
|
dComIfG_Ccsp()->Set(&mSphere);
|
|
mSphere2.SetC(eyePos);
|
|
|
|
if (mActionMode == ACTION_WAIT || mActionMode == ACTION_CAW) {
|
|
mSphere2.SetR(30.0f);
|
|
} else {
|
|
mSphere2.SetR(70.0f);
|
|
}
|
|
dComIfG_Ccsp()->Set(&mSphere2);
|
|
} else {
|
|
mSphere.SetC(eyePos);
|
|
mSphere.SetR(35.0f);
|
|
dComIfG_Ccsp()->Set(&mSphere);
|
|
mSphere2.SetC(eyePos);
|
|
|
|
if (mActionMode == ACTION_WAIT || mActionMode == ACTION_CAW) {
|
|
mSphere2.SetR(35.0f);
|
|
} else {
|
|
mSphere2.SetR(70.0f);
|
|
}
|
|
dComIfG_Ccsp()->Set(&mSphere2);
|
|
}
|
|
}
|
|
|
|
int daE_GE_c::execute() {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (field_0xb8e[i] != 0) {
|
|
field_0xb8e[i]--;
|
|
}
|
|
}
|
|
|
|
if (mDamageCooldownTimer != 0) {
|
|
mDamageCooldownTimer--;
|
|
}
|
|
|
|
if (mAnmChangeTimer != 0) {
|
|
mAnmChangeTimer--;
|
|
}
|
|
|
|
if (mSurpriseTime != 0) {
|
|
mSurpriseTime--;
|
|
if (mSurpriseTime == 0) {
|
|
setSurprise();
|
|
}
|
|
}
|
|
|
|
if (mBackAnimeTimer != 0) {
|
|
mBackAnimeTimer--;
|
|
}
|
|
|
|
action();
|
|
mtx_set();
|
|
cc_set();
|
|
attention_info.position = eyePos;
|
|
attention_info.position.y += 30.0f;
|
|
|
|
cXyz effect_pos(current.pos);
|
|
effect_pos.y += 50.0f;
|
|
cXyz size(1.0f, 1.0f, 1.0f);
|
|
setMidnaBindEffect(this, &mSound, &effect_pos, &size);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int daE_GE_Execute(daE_GE_c* i_this) {
|
|
return i_this->execute();
|
|
}
|
|
|
|
static int daE_GE_IsDelete(daE_GE_c* i_this) {
|
|
return 1;
|
|
}
|
|
|
|
int daE_GE_c::_delete() {
|
|
dComIfG_resDelete(&mPhaseReq, "E_GE");
|
|
|
|
if (mHIOInit) {
|
|
hio_set = FALSE;
|
|
mDoHIO_DELETE_CHILD(l_HIO.id);
|
|
}
|
|
|
|
if (heap != NULL) {
|
|
mSound.deleteObject();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int daE_GE_Delete(daE_GE_c* i_this) {
|
|
return i_this->_delete();
|
|
}
|
|
|
|
int daE_GE_c::CreateHeap() {
|
|
mpMorfSO = JKR_NEW mDoExt_McaMorfSO((J3DModelData*)dComIfG_getObjectRes("E_GE", 0xF), NULL, NULL,
|
|
(J3DAnmTransform*)dComIfG_getObjectRes("E_GE", 0xC), 0, 1.0f, 0,
|
|
-1, &mSound, 0x80000, 0x11000084);
|
|
|
|
if (mpMorfSO == NULL || mpMorfSO->getModel() == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int useHeapInit(fopAc_ac_c* i_this) {
|
|
return static_cast<daE_GE_c*>(i_this)->CreateHeap();
|
|
}
|
|
|
|
int daE_GE_c::create() {
|
|
static dCcD_SrcSph cc_sph_src = {
|
|
{
|
|
{0x0, {{AT_TYPE_CSTATUE_SWING, 0x1, 0xd}, {0xd8fbfdff, 0x3}, 0x75}}, // mObj
|
|
{dCcD_SE_METAL, 0x0, 0x0, 0x0, 0x0}, // mGObjAt
|
|
{dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x22}, // mGObjTg
|
|
{0x0}, // mGObjCo
|
|
}, // mObjInf
|
|
{
|
|
{{0.0f, 0.0f, 0.0f}, 40.0f} // mSph
|
|
} // mSphAttr
|
|
};
|
|
|
|
fopAcM_ct(this, daE_GE_c);
|
|
|
|
mSwitch = fopAcM_GetParam(this) >> 8;
|
|
if (mSwitch != 0xFF && dComIfGs_isSwitch(mSwitch, fopAcM_GetRoomNo(this))) {
|
|
// "E_GE I've been defeated so I won't reset it\n"
|
|
OS_REPORT("E_GE やられ後なので再セットしません\n");
|
|
return cPhs_ERROR_e;
|
|
}
|
|
|
|
mMoveType = fopAcM_GetParam(this);
|
|
if (mMoveType == 0xFF) {
|
|
mMoveType = 0;
|
|
}
|
|
|
|
mGroupNo = fopAcM_GetParam(this) >> 0x10;
|
|
|
|
int phase = dComIfG_resLoad(&mPhaseReq, "E_GE");
|
|
if (phase == cPhs_COMPLEATE_e) {
|
|
OS_REPORT("E_GE PARAM %x\n", fopAcM_GetParam(this));
|
|
|
|
if (!fopAcM_entrySolidHeap(this, useHeapInit, 0x1340)) {
|
|
return cPhs_ERROR_e;
|
|
}
|
|
|
|
if (!hio_set) {
|
|
mHIOInit = true;
|
|
hio_set = TRUE;
|
|
l_HIO.id = mDoHIO_CREATE_CHILD("グェー", &l_HIO);
|
|
}
|
|
|
|
attention_info.flags = fopAc_AttnFlag_BATTLE_e;
|
|
fopAcM_SetMtx(this, mpMorfSO->getModel()->getBaseTRMtx());
|
|
fopAcM_SetMin(this, -200.0f, -200.0f, -200.0f);
|
|
fopAcM_SetMax(this, 200.0f, 200.0f, 200.0f);
|
|
mObjAcch.Set(fopAcM_GetPosition_p(this), fopAcM_GetOldPosition_p(this), this, 1, &mAcchCir,
|
|
fopAcM_GetSpeed_p(this), NULL, NULL);
|
|
mAcchCir.SetWall(0.0f, 50.0f);
|
|
mObjAcch.SetGroundUpY(30.0f);
|
|
health = 10;
|
|
field_0x560 = 10;
|
|
mStts.Init(100, 0, this);
|
|
mSphere.Set(cc_sph_src);
|
|
mSphere.SetStts(&mStts);
|
|
if (mMoveType != 2) {
|
|
mSphere.SetTgType(0xd8fbdddf);
|
|
} else {
|
|
mSphere.SetTgType(0xd8fadddf);
|
|
}
|
|
#if !DEBUG
|
|
mSphere.OnTgNoHitMark();
|
|
#endif
|
|
mSphere2.Set(cc_sph_src);
|
|
mSphere2.SetStts(&mStts);
|
|
mSphere2.SetTgType(0x2020);
|
|
mSphere2.OnTgNoHitMark();
|
|
mSphere2.OffCoSetBit();
|
|
mSphere2.OffAtSetBit();
|
|
mSound.init(¤t.pos, &eyePos, 3, 1);
|
|
mSound.setEnemyName("E_ge");
|
|
mAtInfo.mpSound = &mSound;
|
|
mAtInfo.mPowerType = 1;
|
|
|
|
if (getMoveType() != 0) {
|
|
home.pos.y = old.pos.y = current.pos.y;
|
|
setActionMode(ACTION_FLY);
|
|
} else {
|
|
dBgS_GndChk gndChk;
|
|
cXyz modified_home_pos(home.pos);
|
|
modified_home_pos.y += 100.0f;
|
|
gndChk.SetPos(&modified_home_pos);
|
|
f32 groundCross = dComIfG_Bgsp().GroundCross(&gndChk);
|
|
if (groundCross != -G_CM3D_F_INF && fabsf(current.pos.y - groundCross) < 200.0f) {
|
|
current.pos.y = old.pos.y = home.pos.y = groundCross + 30.0f;
|
|
}
|
|
setActionMode(ACTION_WAIT);
|
|
}
|
|
mtx_set();
|
|
}
|
|
return phase;
|
|
}
|
|
|
|
static int daE_GE_Create(daE_GE_c* i_this) {
|
|
return i_this->create();
|
|
}
|
|
|
|
static actor_method_class l_daE_GE_Method = {
|
|
(process_method_func)daE_GE_Create, (process_method_func)daE_GE_Delete,
|
|
(process_method_func)daE_GE_Execute, (process_method_func)daE_GE_IsDelete,
|
|
(process_method_func)daE_GE_Draw,
|
|
};
|
|
|
|
actor_process_profile_definition g_profile_E_GE = {
|
|
/* Layer ID */ fpcLy_CURRENT_e,
|
|
/* List ID */ 7,
|
|
/* List Prio */ fpcPi_CURRENT_e,
|
|
/* Proc Name */ fpcNm_E_GE_e,
|
|
/* Proc SubMtd */ &g_fpcLf_Method.base,
|
|
/* Size */ sizeof(daE_GE_c),
|
|
/* Size Other */ 0,
|
|
/* Parameters */ 0,
|
|
/* Leaf SubMtd */ &g_fopAc_Method.base,
|
|
/* Draw Prio */ fpcDwPi_E_GE_e,
|
|
/* Actor SubMtd */ &l_daE_GE_Method,
|
|
/* Status */ fopAcStts_UNK_0x40000_e | fopAcStts_UNK_0x10000_e | fopAcStts_CULL_e | fopAcStts_UNK_0x20_e,
|
|
/* Group */ fopAc_ENEMY_e,
|
|
/* Cull Type */ fopAc_CULLBOX_CUSTOM_e,
|
|
};
|