Files
dusklight/src/d/actor/d_a_e_dn.cpp
T
LagoLunatic 877889c510 Clean up code, remove fakematches, add UNUSED, enable warnings (#2992)
* Remove NDEBUG_DEFINED fakematch, clean up getName temps

* Fix ifdef

* Fix bad JSystem pch ifdef breaking decomp.me

* Remove Acch Chk fakematches

* Private Acch fields

* Fix some clangd errors in headers

* Add UNUSED macro for matching debug parameters

* Enable clangd unused-parameter warning

* Remove extern from initializers

Probably added by dol2asm?

* Fix process profile definitions

* Remove leftover dol2asm address comments

* Remove some unnecessary double casts

* Enable some more clangd warnings

* Fix missing usages of fopAcM_ct

* Fix wrong enum usage

* Fix more fakematches
2025-12-23 15:53:10 -08:00

3518 lines
120 KiB
C++

/**
* @file d_a_e_dn.cpp
*
*/
#include "d/dolzel_rel.h" // IWYU pragma: keep
#include "d/actor/d_a_e_dn.h"
#include "d/d_cc_d.h"
#include "d/d_bomb.h"
#include "f_op/f_op_kankyo_mng.h"
#include "d/actor/d_a_player.h"
#include "d/actor/d_a_horse.h"
#include "f_op/f_op_actor_enemy.h"
#include "Z2AudioLib/Z2Instances.h"
class daE_DN_HIO_c : public JORReflexible {
public:
daE_DN_HIO_c();
virtual ~daE_DN_HIO_c() {}
void genMessage(JORMContext*);
/* 0x04 */ s8 no;
/* 0x08 */ f32 model_size; // 基本サイズ
/* 0x0C */ f32 movement_speed; // 移動速度
/* 0x10 */ f32 dash_speed; // 突進速度
/* 0x14 */ f32 battle_init_range; // 戦闘開始範囲
/* 0x18 */ f32 attack_init_range; // 攻撃開始範囲
/* 0x1C */ s16 defense_pause_time; // 防御静止間
/* 0x1E */ s16 soul_disappear_time_weak; // 魂抜間 弱
/* 0x20 */ s16 soul_disappear_time_strong; // 魂抜間 強
/* 0x22 */ u8 field_0x22;
/* 0x23 */ u8 invulnerable; // 不死身
/* 0x24 */ u8 no_learn; // 学習なし
};
enum Joint {
/* 0x00 */ JNT_WORLD_ROOT,
/* 0x01 */ JNT_BACKBONE01,
/* 0x02 */ JNT_BACKBONE02,
/* 0x03 */ JNT_NECK01,
/* 0x04 */ JNT_NECK02,
/* 0x05 */ JNT_FIN,
/* 0x06 */ JNT_HEAD,
/* 0x07 */ JNT_JAW1,
/* 0x08 */ JNT_JAW2,
/* 0x09 */ JNT_TONGUE,
/* 0x0A */ JNT_SHOULDERL,
/* 0x0B */ JNT_ARML1,
/* 0x0C */ JNT_ARML2,
/* 0x0D */ JNT_HANDL,
/* 0x0E */ JNT_FINGERL1,
/* 0x0F */ JNT_FINGERL2,
/* 0x10 */ JNT_SHOULDERR,
/* 0x11 */ JNT_ARMR1,
/* 0x12 */ JNT_ARMR2,
/* 0x13 */ JNT_HANDR1,
/* 0x14 */ JNT_FINGERR1,
/* 0x15 */ JNT_FINGERR2,
/* 0x16 */ JNT_WAIST,
/* 0x17 */ JNT_LEGL1,
/* 0x18 */ JNT_LEGL2,
/* 0x19 */ JNT_LEGL3,
/* 0x1A */ JNT_FOOTL,
/* 0x1B */ JNT_LEGR1,
/* 0x1C */ JNT_LEGR2,
/* 0x1D */ JNT_LEGR3,
/* 0x1E */ JNT_FOOTR,
/* 0x1F */ JNT_TAIL01,
/* 0x20 */ JNT_TAIL02,
/* 0x21 */ JNT_TAIL03,
/* 0x22 */ JNT_TAIL04,
};
enum Action {
/* 0x00 */ ACTION_NORMAL = 0,
/* 0x03 */ ACTION_FIGHT_RUN = 3,
/* 0x04 */ ACTION_ATTACK_0 = 4,
/* 0x05 */ ACTION_ATTACK = 5,
/* 0x06 */ ACTION_TAIL_ATTACK = 6,
/* 0x07 */ ACTION_GUARD = 7,
/* 0x08 */ ACTION_JUMP = 8,
/* 0x09 */ ACTION_STAY = 9,
/* 0x0A */ ACTION_OTOREAC = 10,
/* 0x0B */ ACTION_BOMB_ACTION = 11,
/* 0x0C */ ACTION_DRAWBACK = 12,
/* 0x0D */ ACTION_WOLFBITE = 13,
/* 0x14 */ ACTION_S_DAMAGE = 20,
/* 0x15 */ ACTION_DAMAGE = 21,
/* 0x17 */ ACTION_BACKDROP = 23,
/* 0x18 */ ACTION_WATER = 24,
/* 0x19 */ ACTION_GAKEJUMP = 25,
/* 0x3C */ ACTION_REG = 60,
};
enum Animation {
/* 0x04 */ ANM_ATTACK_TAIL_01 = 4,
/* 0x05 */ ANM_ATTACK_TAIL_02,
/* 0x06 */ ANM_ATTACK_TAIL_03,
/* 0x07 */ ANM_ATTACK_00,
/* 0x08 */ ANM_ATTACK_01,
/* 0x09 */ ANM_BLOWNOFF,
/* 0x0A */ ANM_BRUSH_LEFT_UP,
/* 0x0B */ ANM_BRUSH_RIGHT_UP,
/* 0x0C */ ANM_DAMAGE_W,
/* 0x0D */ ANM_DIE_LEFT,
/* 0x0E */ ANM_DIE_LEFT_UP,
/* 0x0F */ ANM_DIE_RIGHT,
/* 0x10 */ ANM_DIE_RIGHT_UP,
/* 0x11 */ ANM_DIE_W,
/* 0x12 */ ANM_DRAWBACK,
/* 0x13 */ ANM_DROWNED_A,
/* 0x14 */ ANM_DROWNED_B,
/* 0x15 */ ANM_FIND,
/* 0x16 */ ANM_GUARD,
/* 0x17 */ ANM_HANGED,
/* 0x18 */ ANM_HANGED_DAMAGE,
/* 0x19 */ ANM_HANGED_BRUSH,
/* 0x1A */ ANM_HANGED_WAIT,
/* 0x1B */ ANM_JUMP_A,
/* 0x1C */ ANM_JUMP_B,
/* 0x1D */ ANM_JUMP_C,
/* 0x1E */ ANM_RUN,
/* 0x1F */ ANM_WAIT_01,
/* 0x20 */ ANM_WAIT_02,
/* 0x21 */ ANM_WAIT_03,
/* 0x22 */ ANM_WAIT_04,
/* 0x23 */ ANM_WALK,
};
daE_DN_HIO_c::daE_DN_HIO_c() {
no = -1;
model_size = 1.1f;
movement_speed = 7.5f;
dash_speed = 25.0f;
battle_init_range = 300.0f;
attack_init_range = 350.0f;
defense_pause_time = 3;
soul_disappear_time_weak = 40;
soul_disappear_time_strong = 80;
field_0x22 = 1;
invulnerable = 0;
no_learn = 0;
}
#if DEBUG
void daE_DN_HIO_c::genMessage(JORMContext* ctx) {
ctx->genLabel(" リザードマン", 0x80000001, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("基本サイズ", &model_size, 0.0f, 5.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("移動速度", &movement_speed, 0.0f, 20.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("突進速度", &dash_speed, 0.0f, 40.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("戦闘開始範囲", &battle_init_range, 0.0f, 2000.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("攻撃開始範囲", &attack_init_range, 0.0f, 1000.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genCheckBox("不死身", &invulnerable, 1, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genCheckBox("学習なし", &no_learn, 1, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("魂抜間 弱", &soul_disappear_time_weak, 0, 100, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("魂抜間 強", &soul_disappear_time_strong, 0, 100, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
ctx->genSlider("防御静止間", &defense_pause_time, 0, 20, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 0x18);
}
#endif
static void dn_disappear(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz work, pos;
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
work.set(0.0f, 0.0f, 0.0f);
MtxPosition(&work, &pos);
fopAcM_createDisappear(actor, &pos, 13, 0, 21);
fopAcM_delete(actor);
int swBit = (fopAcM_GetParam(actor) & 0xFF000000) >> 24;
if (swBit != 0xFF) {
dComIfGs_onSwitch(swBit, fopAcM_GetRoomNo(actor));
}
}
static void anm_init(e_dn_class* i_this, int i_anm_id, f32 i_morf, u8 i_attr, f32 i_rate) {
i_this->anm_p->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("E_dn", i_anm_id), i_attr, i_morf,
i_rate, 0.0f, -1.0f);
i_this->anm_no = i_anm_id;
}
static int nodeCallBack(J3DJoint* i_joint, int param_2) {
if (param_2 == 0) {
int jointNo = i_joint->getJntNo();
J3DModel* model = j3dSys.getModel();
e_dn_class* i_this = (e_dn_class*)model->getUserArea();
if (i_this != NULL) {
MTXCopy(model->getAnmMtx(jointNo), *calc_mtx);
if (jointNo != JNT_WORLD_ROOT) {
if (jointNo == JNT_WAIST) {
cMtx_YrotM(*calc_mtx, (s16)i_this->field_0x830.y);
cMtx_ZrotM(*calc_mtx, i_this->jnt_waist_z_rot + (-i_this->field_0x762[2].x + i_this->field_0x830.x));
} else if (jointNo == JNT_LEGL1) {
cMtx_YrotM(*calc_mtx, i_this->jnt_legl1_y_rot);
} else if (jointNo == JNT_LEGL2) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x7fc[0]);
} else if (jointNo == JNT_LEGR1) {
cMtx_YrotM(*calc_mtx, i_this->field_0x7fc[1]);
} else if (jointNo == JNT_LEGR2) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x7fc[2]);
} else if (jointNo == JNT_BACKBONE02) {
cMtx_YrotM(*calc_mtx, (i_this->field_0x6fa / 2) + (-i_this->field_0x6f6 + i_this->field_0x762[1].y));
cMtx_ZrotM(*calc_mtx, i_this->field_0x762[1].x + i_this->field_0x7ec[1]);
} else if (jointNo == JNT_NECK01 || jointNo == JNT_NECK02) {
cMtx_YrotM(*calc_mtx, i_this->field_0x762[0].y + (-i_this->field_0x6f6 + i_this->field_0x6fa));
cMtx_ZrotM(*calc_mtx, i_this->field_0x7ec[0] + (-i_this->field_0x6f8 + i_this->field_0x762[0].x));
} else if (jointNo == JNT_ARML1) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x762[3].y + i_this->jnt_arml1_z_rot_offset);
} else if (jointNo == JNT_ARML2) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x762[4].y + i_this->jnt_arml2_z_rot_offset);
} else if (jointNo == JNT_ARMR1) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x762[5].y + i_this->jnt_armr1_z_rot_offset);
} else if (jointNo == JNT_ARMR2) {
cMtx_ZrotM(*calc_mtx, i_this->field_0x762[6].y + i_this->jnt_armr2_z_rot_offset);
} else if (jointNo >= JNT_TAIL01 && jointNo <= JNT_TAIL04) {
cMtx_YrotM(*calc_mtx, i_this->field_0x80e[jointNo - 31].y + i_this->jnt_tail_y_rot_offset);
cMtx_ZrotM(*calc_mtx, (s16)i_this->field_0x80e[jointNo - 31].x);
}
}
if (i_this->death_jnt_rot != 0) {
if ((jointNo & 1) != 0) {
cMtx_YrotM(*calc_mtx, i_this->death_jnt_rot);
} else if ((jointNo & 2) != 0) {
cMtx_XrotM(*calc_mtx, i_this->death_jnt_rot);
} else if ((jointNo & 4) != 0) {
cMtx_ZrotM(*calc_mtx, i_this->death_jnt_rot);
}
}
model->setAnmMtx(jointNo, *calc_mtx);
MTXCopy(*calc_mtx, J3DSys::mCurrentMtx);
if (jointNo == TREG_S(0)) {
MTXCopy(model->getAnmMtx(jointNo), *calc_mtx);
cMtx_YrotM(*calc_mtx, TREG_S(1));
cMtx_XrotM(*calc_mtx, TREG_S(2));
cMtx_ZrotM(*calc_mtx, TREG_S(3));
model->setAnmMtx(jointNo, *calc_mtx);
MTXCopy(*calc_mtx, J3DSys::mCurrentMtx);
}
if (jointNo == TREG_S(4)) {
MTXCopy(model->getAnmMtx(jointNo), *calc_mtx);
cMtx_YrotM(*calc_mtx, TREG_S(5));
cMtx_XrotM(*calc_mtx, TREG_S(6));
cMtx_ZrotM(*calc_mtx, TREG_S(7));
model->setAnmMtx(jointNo, *calc_mtx);
MTXCopy(*calc_mtx, J3DSys::mCurrentMtx);
}
}
}
return 1;
}
static int daE_DN_Draw(e_dn_class* i_this) {
if (i_this->status != 0) {
return 1;
}
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
J3DModel* model = i_this->anm_p->getModel();
g_env_light.settingTevStruct(0, &actor->current.pos, &actor->tevStr);
g_env_light.setLightTevColorType_MAJI(model, &actor->tevStr);
if (i_this->death_flag != 0) {
J3DModelData* modelData = model->getModelData();
for (u16 i = 0; i < modelData->getMaterialNum(); i++) {
J3DMaterial* matNode_p = modelData->getMaterialNodePointer(i);
matNode_p->getTevColor(0)->r = i_this->color;
matNode_p->getTevColor(0)->g = i_this->color;
matNode_p->getTevColor(0)->b = i_this->color;
}
}
i_this->anm_p->entryDL();
if (i_this->death_flag != 0) {
J3DModelData* modelData = model->getModelData();
for (u16 i = 0; i < modelData->getMaterialNum(); i++) {
J3DMaterial* matNode_p = modelData->getMaterialNodePointer(i);
matNode_p->getTevColor(0)->r = 0;
matNode_p->getTevColor(0)->g = 0;
matNode_p->getTevColor(0)->b = 0;
}
}
g_env_light.setLightTevColorType_MAJI(i_this->knife_model, &actor->tevStr);
mDoExt_modelUpdateDL(i_this->knife_model);
if (i_this->skull_model != NULL) {
g_env_light.setLightTevColorType_MAJI(i_this->skull_model, &actor->tevStr);
mDoExt_modelUpdateDL(i_this->skull_model);
}
g_env_light.setLightTevColorType_MAJI(i_this->tate_model, &actor->tevStr);
mDoExt_modelUpdateDL(i_this->tate_model);
cXyz shadow_pos;
shadow_pos.set(actor->current.pos.x, actor->current.pos.y + 50.0f + BREG_F(18), actor->current.pos.z);
i_this->shadow_key = dComIfGd_setShadow(i_this->shadow_key, 1, model, &shadow_pos, BREG_F(19) + 950.0f, 0.0f,
actor->current.pos.y, i_this->objacch.GetGroundH(),
i_this->objacch.m_gnd, &i_this->actor.tevStr, 0, 1.0f,
dDlst_shadowControl_c::getSimpleTex());
dComIfGd_addRealShadow(i_this->shadow_key, i_this->knife_model);
if (i_this->skull_model != NULL) {
dComIfGd_addRealShadow(i_this->shadow_key, i_this->skull_model);
}
dComIfGd_addRealShadow(i_this->shadow_key, i_this->tate_model);
return 1;
}
static BOOL other_bg_check(e_dn_class* i_this, fopAc_ac_c* i_actor) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBgS_LinChk lin_chk;
cXyz unused, start, end;
end = i_actor->current.pos;
end.y += 100.0f;
start = actor->current.pos;
start.y = actor->eyePos.y;
lin_chk.Set(&start, &end, actor);
if (dComIfG_Bgsp().LineCross(&lin_chk)) {
return TRUE;
}
return FALSE;
}
static BOOL other_bg_check2(e_dn_class* i_this, cXyz* i_pos) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBgS_LinChk lin_chk;
cXyz unused, start, end;
end = *i_pos;
end.y += 100.0f;
start = actor->current.pos;
start.y = actor->eyePos.y;
lin_chk.Set(&start, &end, actor);
if (dComIfG_Bgsp().LineCross(&lin_chk)) {
return TRUE;
}
return FALSE;
}
u8 hio_set;
daE_DN_HIO_c l_HIO;
fopAc_ac_c* target_info[10];
int target_info_count;
static void* s_b_sub(void* i_actor, void* i_data) {
if (fopAcM_IsActor(i_actor) && dBomb_c::checkBombActor((fopAc_ac_c*)i_actor) && !((dBomb_c*)i_actor)->checkStateExplode() && target_info_count < 10) {
target_info[target_info_count] = (fopAc_ac_c*)i_actor;
target_info_count++;
}
return NULL;
}
static dBomb_c* search_bomb(e_dn_class* i_this, int param_2) {
if ((i_this->learn & 0x10000000) == 0) {
return NULL;
}
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBomb_c* bomb;
target_info_count = 0;
for (int i = 0; i < 10; i++) {
target_info[i] = NULL;
}
fpcM_Search(s_b_sub, i_this);
f32 threshold = 50.0f;
if (target_info_count != 0) {
cXyz work, bomb_dist, sp5c;
for (int i = 0; i < target_info_count;) {
bomb = (dBomb_c*)target_info[i];
work.x = bomb->current.pos.x - actor->eyePos.x;
work.y = 50.0f + bomb->current.pos.y - actor->eyePos.y;
work.z = bomb->current.pos.z - actor->eyePos.z;
bomb_dist.x = bomb->current.pos.x - actor->current.pos.x;
bomb_dist.y = bomb->current.pos.y - actor->current.pos.y;
bomb_dist.z = bomb->current.pos.z - actor->current.pos.z;
if (work.abs() < threshold && !(bomb_dist.abs() > i_this->pl_dir + 30.0f) && (!other_bg_check(i_this, bomb) || !param_2)) {
if (param_2) {
f32 absVal = fabsf(50.0f + bomb->current.pos.y - actor->eyePos.y);
if (absVal <= 300.0f) {
s16 angle = actor->shape_angle.y - cM_atan2s(work.x, work.z);
if (angle < 0) {
angle = -1 * angle;
}
if ((u16)angle < 20000) { // ~110°
return bomb;
}
cMtx_YrotS(*calc_mtx, -actor->shape_angle.y);
MtxPosition(&work, &sp5c);
if (fabsf(sp5c.x) < 500.0f && fabsf(sp5c.y) < 300.0f && sp5c.z > -125.0f && sp5c.z < 500.0f) {
return bomb;
}
}
} else {
return bomb;
}
}
i++;
if (i == target_info_count) {
i = 0;
threshold += 50.0f;
if (threshold > 1500.0f) {
return NULL;
}
}
}
} else {
return NULL;
}
return NULL;
}
static dBomb_c* bomb_view_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
return search_bomb(i_this, TRUE);
}
static dBomb_c* bomb_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
return search_bomb(i_this, FALSE);
}
static BOOL player_way_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
fopAc_ac_c* player = dComIfGp_getPlayer(0);
s16 way = actor->shape_angle.y - player->shape_angle.y;
if (way < 0) {
way = way * -1;
}
if ((u32)((s16)way & 0xFFFF) < 0x6000) {
return FALSE;
}
return TRUE;
}
static int pl_check(e_dn_class* i_this, f32 search_area, s16 search_angle) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
if (i_this->pl_dir < search_area) {
s16 angle = actor->shape_angle.y - i_this->search_angle_y;
if (angle < search_angle && angle > (s16)-search_angle && !other_bg_check(i_this, player)) {
return 1;
}
}
for (int i = 0; i <= 2; i++) {
if (i_this->cc_sph[i].ChkCoHit() != 0) {
if (player == dCc_GetAc(i_this->cc_sph[i].GetCoHitObj()->GetAc())) {
return 2;
}
}
}
return 0;
}
static BOOL move_gake_check(e_dn_class* i_this, f32 param_2, s8 param_3) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBgS_GndChk gnd_chk;
cXyz work, pos;
cMtx_YrotS(*calc_mtx, actor->shape_angle.y);
work.x = 0.0f;
work.y = 100.0f;
if (param_3 != 0) {
work.z = -param_2;
} else {
work.z = param_2;
}
MtxPosition(&work, &pos);
pos += actor->current.pos;
gnd_chk.SetPos(&pos);
if (actor->current.pos.y - dComIfG_Bgsp().GroundCross(&gnd_chk) > 300.0f) {
return TRUE;
}
return FALSE;
}
static BOOL jump_pos_check(e_dn_class* i_this, cXyz* i_pos) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBgS_GndChk gnd_chk;
cXyz work, new_pos;
f32 z_offset = KREG_F(16) + 300.0f;
cMtx_YrotS(*calc_mtx, i_this->search_angle_y);
work.x = 0.0f;
work.y = 200.0f;
int i = 0;
while (i < KREG_S(7) + 10) {
work.z = z_offset;
MtxPosition(&work, &new_pos);
new_pos += actor->current.pos;
gnd_chk.SetPos(&new_pos);
new_pos.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if ((actor->current.pos.y - new_pos.y) < 200.0f) {
*i_pos = new_pos;
work.z += KREG_F(18) + 200.0f;
MtxPosition(&work, &new_pos);
new_pos += actor->current.pos;
gnd_chk.SetPos(&new_pos);
new_pos.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if ((actor->current.pos.y - new_pos.y) < 200.0f) {
*i_pos = new_pos;
}
return TRUE;
}
z_offset += 50.0f;
i++;
}
return FALSE;
}
static void e_dn_stay(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
i_this->field_0x6f4 = 5;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_WAIT_01, 10.0f, J3DFrameCtrl::EMode_LOOP, cM_rndF(0.1f) + 0.9f);
i_this->mode = 1;
// fallthrough
case 1:
if (fopAcM_otoCheck(actor, 2000.0f) || daPy_getPlayerActorClass()->checkWolfBark()) {
SND_INFLUENCE* sound = dKy_Sound_get();
cXyz posDelta = sound->position - actor->current.pos;
s16 angle = cM_atan2s(posDelta.y, JMAFastSqrt(posDelta.x * posDelta.x + posDelta.z * posDelta.z));
if (angle > 0x1000) { // 22.5°
i_this->mode = 5;
} else {
i_this->mode = 2;
}
i_this->timer[0] = cM_rndF(10.0f) + 10.0f;
i_this->find_pos = sound->position;
}
break;
case 2:
if (i_this->timer[0] == 0) {
anm_init(i_this, ANM_FIND, 3.0f, J3DFrameCtrl::EMode_NONE, 1.5f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_FIND, -1);
i_this->mode = 3;
}
break;
case 3:
if (i_this->anm_p->isStop()) {
if (other_bg_check2(i_this, &i_this->find_pos)) {
i_this->timer[0] = cM_rndF(10.0f) + 20.0f;
i_this->mode = 4;
} else {
i_this->action = ACTION_OTOREAC;
i_this->mode = 0;
}
}
break;
case 4:
if (i_this->timer[0] == 0) {
i_this->mode = 10;
i_this->timer[0] = cM_rndF(10.0f) + 30.0f;
anm_init(i_this, ANM_WAIT_03, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.5f);
}
break;
case 5:
if (i_this->timer[0] == 0) {
anm_init(i_this, ANM_FIND, 3.0f, J3DFrameCtrl::EMode_NONE, 1.5f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_FIND, -1);
i_this->mode = 6;
}
break;
case 6:
if (i_this->anm_p->isStop()) {
i_this->timer[0] = cM_rndF(10.0f) + 20.0f;
i_this->mode = 7;
}
break;
case 7:
if (i_this->timer[0] == 0) {
i_this->mode = 10;
i_this->timer[0] = cM_rndF(40.0f) + 50.0f;
anm_init(i_this, ANM_WAIT_04, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.3f);
i_this->anm_p->setFrame(cM_rndF(75.0f));
}
break;
case 8:
if (i_this->anm_p->isStop()) {
i_this->mode = 0;
}
break;
case 10:
if (i_this->timer[0] == 0) {
i_this->mode = 0;
}
}
if ((i_this->frame_counter & 15) == 0) { // Every 16 frames
if (pl_check(i_this, i_this->pl_range, 0x4000) != 0) { // 90°
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = -10;
i_this->timer[0] = 60;
} else if (bomb_view_check(i_this) != NULL) {
i_this->action = ACTION_BOMB_ACTION;
i_this->mode = 0;
}
}
}
static void e_dn_otoreac(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz work, unused;
f32 dash_speed = 0.0f;
i_this->field_0x6f4 = 2;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_WAIT_01, 10.0f, J3DFrameCtrl::EMode_LOOP, cM_rndF(0.2f) + 1.5f);
i_this->timer[0] = cM_rndF(10.0f) + 20.0f;
i_this->mode = 1;
// fallthrough
case 1:
if (i_this->timer[0] == 0) {
anm_init(i_this, ANM_RUN, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndFX(0.05f) + 1.0f);
i_this->mode = 2;
}
break;
case 2:
dash_speed = l_HIO.dash_speed;
if ((i_this->frame_counter & 3) == 0) { // Every 4 frames
if ((i_this->frame_counter & 4) != 0) { // Every 5 frames
i_this->set_smoke_flag = 1;
} else {
i_this->set_smoke_flag = 2;
}
}
work = i_this->find_pos - actor->current.pos;
cLib_addCalcAngleS2(&actor->current.angle.y, cM_atan2s(work.x, work.z), 2, 0xC00);
if (work.abs() < 250.0f || i_this->objacch.ChkWallHit() != 0) {
i_this->action = ACTION_NORMAL;
i_this->mode = 0;
i_this->timer[0] = cM_rndF(50.0f) + 50.0f;
anm_init(i_this, ANM_WAIT_03, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
break;
}
cLib_addCalc2(&actor->speedF, dash_speed, 1.0f, 5.0f);
if ((i_this->frame_counter & 15) == 0) { // Every 16 frames
if (pl_check(i_this, i_this->pl_range, 0x4000) != 0) { // 90°
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = -10;
i_this->timer[0] = 60;
} else if (bomb_view_check(i_this) != NULL) {
i_this->action = ACTION_BOMB_ACTION;
i_this->mode = 0;
}
}
}
static void e_dn_bomb_action(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
s16 angle;
cXyz work, bomb_pos_target;
dBomb_c* bomb = bomb_check(i_this);
if (bomb == NULL) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
return;
}
work.x = bomb->current.pos.x - actor->current.pos.x;
work.z = bomb->current.pos.z - actor->current.pos.z;
s16 target_angle_y = cM_atan2s(work.x, work.z);
f32 dash_speed = 0.0f;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_FIND, 3.0f, J3DFrameCtrl::EMode_NONE, 1.5f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_FIND_BOMB, -1);
i_this->mode = 1;
break;
case 1:
if (i_this->anm_p->isStop()) {
i_this->mode = 2;
}
break;
case 2:
i_this->mode = 3;
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->timer[1] = cM_rndF(10.0f) + 10.0f;
// fallthrough
case 3:
if (i_this->timer[1] == 0 && bomb->speedF < 0.1f) {
i_this->mode = 4;
anm_init(i_this, ANM_RUN, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndFX(0.05f) + 1.0f);
}
break;
case 4:
if (i_this->arg1 == 1 && bomb->speedF < 0.1f && !bomb->checkStateCarry() && JMAFastSqrt(work.x * work.x + work.z * work.z) < 250.0f) {
angle = i_this->search_angle_y - actor->shape_angle.y;
if (angle < 0x4000 && angle > -0x4000) { // ±90°
i_this->mode = 10;
break;
}
}
target_angle_y += 0x8000; // 180°
dash_speed = l_HIO.dash_speed;
if (JMAFastSqrt(work.x * work.x + work.z * work.z) > 600.0f) {
i_this->mode = 5;
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
break;
case 5:
i_this->sound.startCreatureSoundLevel(Z2SE_EN_DN_V_LOOK_BOMB, 0, -1);
target_angle_y = i_this->search_angle_y;
if (JMAFastSqrt(work.x * work.x + work.z * work.z) < 500.0f) {
i_this->mode = 2;
}
break;
case 10:
i_this->field_0x6f2 = 0;
dash_speed = l_HIO.dash_speed;
if (JMAFastSqrt(work.x * work.x + work.z * work.z) < 100.0f) {
i_this->timer[0] = 20;
i_this->mode = 11;
anm_init(i_this, ANM_RUN, 5.0f, J3DFrameCtrl::EMode_NONE, cM_rndFX(0.05f) + 1.0f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_KICK_BOMB, -1);
}
if (bomb->speedF > 0.1f) {
i_this->mode = 2;
}
break;
case 11:
i_this->field_0x6f2 = 0;
target_angle_y = i_this->search_angle_y;
if (i_this->timer[0] >= 10) {
cMtx_YrotS(*calc_mtx, target_angle_y);
work.x = TREG_F(15) + -30.0f;
work.y = 0.0f;
work.z = TREG_F(16) + 60.0f;
MtxPosition(&work, &bomb_pos_target);
bomb_pos_target += actor->current.pos;
cLib_addCalc2(&bomb->current.pos.x, bomb_pos_target.x, 1.0f, 15.0f);
cLib_addCalc2(&bomb->current.pos.z, bomb_pos_target.z, 1.0f, 15.0f);
if (i_this->timer[0] == 10) {
bomb->speedF = 30.0f;
bomb->speed.y = 30.0f;
bomb->current.angle.y = actor->shape_angle.y;
}
}
if (i_this->timer[0] == 0) {
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->mode = 5;
}
}
cLib_addCalc2(&actor->speedF, dash_speed, 1.0f, 5.0f);
cLib_addCalcAngleS2(&actor->current.angle.y, target_angle_y, 4, 0x1000);
i_this->field_0x6f4 = 2;
i_this->find_pos = bomb->current.pos;
}
static void e_dn_normal(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp44, sp50;
f32 movement_speed = 0.0f;
s16 search_angle, angle, angle_delta;
search_angle = 0x4000; // 90°
switch (i_this->mode) {
case 0:
case 1:
case 2:
if (i_this->timer[0] == 0) {
if (fopAcM_wayBgCheck(actor, 200.0f, 50.0f) || move_gake_check(i_this, 200.0f, 0)) {
angle = cM_rndFX(10000.0f) + 32768.0f;
i_this->timer[1] = 40;
} else {
sp50.x = actor->home.pos.x + cM_rndFX(600.0f);
sp50.y = actor->home.pos.y;
sp50.z = actor->home.pos.z + cM_rndFX(600.0f);
sp44 = sp50 - actor->current.pos;
angle = cM_atan2s(sp44.x, sp44.z) - actor->current.angle.y;
if (angle > 0x3000) { // 67.5°
angle = 0x3000;
} else if (angle < -0x3000) {
angle = -0x3000;
}
}
i_this->cur_angle_y_target = actor->current.angle.y + angle;
anm_init(i_this, ANM_WALK, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->mode = 3;
i_this->timer[0] = cM_rndF(100.0f) + 100.0f;
} else {
search_angle = 0x7000; // 157.5°
}
break;
case 3:
movement_speed = l_HIO.movement_speed;
angle = actor->current.angle.y;
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->cur_angle_y_target, 2, 0x400);
/* If the actor is facing roughly 22.5° from the target y, stop moving */
angle_delta = actor->current.angle.y - i_this->cur_angle_y_target;
if (angle_delta > 0x1000 || angle_delta < -0x1000) {
movement_speed = 0.0f;
}
/* Calculate how much the actor turned */
angle -= actor->current.angle.y;
/* Scale turn strength */
angle *= (s16)(YREG_S(5) + 2);
/* Ensure the targeted angle is no more than ±22.5° */
s16 max_turn = YREG_S(6) + 0x1000;
if (angle > max_turn) {
angle = max_turn;
} else if (angle < (s16)-max_turn) {
angle = -max_turn;
}
cLib_addCalcAngleS2(&i_this->jnt_tail_y_rot_offset, angle, 2, 0x400);
if (i_this->timer[0] == 0 ||
(i_this->timer[1] == 0 && (fopAcM_wayBgCheck(actor, 200.0f, 50.0f) || move_gake_check(i_this, 200.0f, 0)))) {
i_this->mode = 2;
i_this->timer[0] = cM_rndF(100.0f) + 50.0f;
anm_init(i_this, ANM_WAIT_03, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
break;
}
cLib_addCalc2(&actor->speedF, movement_speed, 1.0f, 3.0f);
BOOL oto_check = fopAcM_otoCheck(actor, 2000.0f) | daPy_getPlayerActorClass()->checkWolfBark();
/* Run the following checks every 16 frames or immediately if the above sound check is true */
if ((i_this->frame_counter & 15) == 0 || oto_check) {
if (oto_check || pl_check(i_this, i_this->pl_range, search_angle) != 0) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = -10;
i_this->timer[0] = 60;
}
if (bomb_view_check(i_this) != NULL) {
i_this->action = ACTION_BOMB_ACTION;
i_this->mode = 0;
}
}
}
static void e_dn_drawback(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
fopAc_ac_c* player = dComIfGp_getPlayer(0);
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_DRAWBACK, 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
actor->speedF = KREG_F(4) + -5.0f;
i_this->invulnerability_timer = 10;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DRAWBACK, -1);
i_this->cur_angle_y_target = player->shape_angle.y + 0x8000; // Target current angle towards player
break;
case 1:
i_this->actor.onHeadLockFlg();
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->cur_angle_y_target, 4, 0x400);
cLib_addCalc0(&actor->speedF, 1.0f, KREG_F(5) + 0.1f);
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_AWAKE, -1);
}
break;
}
if (move_gake_check(i_this, KREG_F(9) + 50.0f, 1)) {
i_this->action = ACTION_BACKDROP;
i_this->mode = 0;
}
}
static void e_dn_wolfbite(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
i_this->invulnerability_timer = 10;
cLib_addCalc0(&actor->speedF, 1.0f, 2.0f);
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_HANGED, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DRAWBACK, -1);
actor->health -= (s16)10;
break;
case 1:
if (i_this->anm_p->isStop()) {
anm_init(i_this, ANM_HANGED_WAIT, 3.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->mode = 2;
}
break;
case 2:
if (i_this->anm_no == ANM_HANGED_DAMAGE) {
if (i_this->anm_p->isStop()) {
anm_init(i_this, ANM_HANGED_WAIT, 3.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
}
if (actor->health <= 0 || actor->checkWolfBiteDamage()) {
actor->offWolfBiteDamage();
anm_init(i_this, ANM_HANGED_DAMAGE, 2.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
actor->health -= (s16)10;
if (actor->health <= 0) {
player->offWolfEnemyHangBite();
i_this->field_0x750 = (actor->shape_angle.y - 0x8000) - player->shape_angle.y;
i_this->field_0x74c = 150.0f;
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
i_this->field_0x724.y = player->shape_angle.y + 0x8000;
actor->speed.y = 0.0f;
i_this->field_0x704 = -1.0f;
i_this->unk_timer_4 = DREG_S(2) + 50;
i_this->sound.startCollisionSE(Z2SE_HIT_WOLFBITE, 32);
i_this->field_0x710 = 1;
i_this->invulnerability_timer = 1000;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DEATH, -1);
return;
}
i_this->sound.startCollisionSE(Z2SE_HIT_WOLFBITE, 30);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DAMAGE, -1);
}
if (!player->checkWolfEnemyHangBiteOwn(actor)) {
anm_init(i_this, ANM_HANGED_BRUSH, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 3;
}
break;
case 3:
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_AWAKE, -1);
}
}
}
static int way_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
s16 sVar1 = actor->shape_angle.y - i_this->search_angle_y;
if (sVar1 <= 0x4000 && sVar1 >= -0x4000) {
return 0;
}
if (sVar1 < 0) {
return 1;
}
return 2;
}
int learn_check;
static void* shot_s_sub(void* i_actor, void* i_data) {
e_dn_class* i_this = (e_dn_class*)i_data;
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
if ((fopAcM_IsActor(i_actor) && (learn_check & 0x80000000) != 0 && fopAcM_GetName(i_actor) == PROC_ARROW && (fopAcM_GetParam(i_actor) == 1 ||
fopAcM_GetParam(i_actor) == 2))) {
cXyz sp28(actor->current.pos - ((fopAc_ac_c*)i_actor)->current.pos);
if (sp28.abs() < 1000.0f) {
return i_actor;
}
}
return NULL;
}
static void e_dn_fight_run(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp4c, sp58;
f32 fVar1 = 0.0f;
int frame = i_this->anm_p->getFrame();
BOOL wayCheck;
s8 sVar4 = 1;
if (pl_check(i_this, i_this->pl_range + 50.0f, 0x7FFF) == 0 && i_this->timer[0] == 0) {
if (i_this->unk_timer_1 == 0) {
sVar4 = 0;
}
} else {
i_this->unk_timer_1 = 40;
}
switch (i_this->mode) {
case -10:
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->timer[1] = cM_rndF(10.0f) + 15.0f;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_FIND, -1);
i_this->mode = -9;
break;
case -9:
cLib_addCalc0(&actor->speedF, 1.0f, 5.0f);
if (i_this->timer[1] == 0) {
i_this->mode = 0;
}
break;
case 0:
anm_init(i_this, ANM_RUN, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndFX(0.05f) + 1.0f);
i_this->mode = 1;
i_this->unk_counter_1 = 0;
// fallthrough
case 1:
fVar1 = l_HIO.dash_speed;
if ((i_this->frame_counter & 3) == 0) { // Every 4 frames
if ((i_this->frame_counter & 4) != 0) { // Every 5 frames
i_this->set_smoke_flag = 1;
} else {
i_this->set_smoke_flag = 2;
}
}
if (i_this->objacch.ChkWallHit() != 0 && !fopAcM_wayBgCheck(actor, 200.0f, 120.0f)) {
i_this->unk_counter_1++;
} else if (i_this->pl_dir < l_HIO.battle_init_range) {
anm_init(i_this, ANM_WAIT_02, 5.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->mode = 2;
i_this->timer[2] = JREG_F(1) + (cM_rndF(30.0f) + 30.0f);
}
if (i_this->unk_counter_1 > 20) {
i_this->action = ACTION_JUMP;
i_this->mode = 0;
return;
}
if (move_gake_check(i_this, KREG_F(6) + 50.0f, 0)) {
i_this->action = ACTION_GAKEJUMP;
i_this->mode = 0;
i_this->invulnerability_timer = 100;
actor->speedF = 0.0f;
return;
}
break;
case 2:
i_this->snap_angle_y_flag = 1;
if (frame == 7 || frame == 21) {
actor->speed.y = XREG_F(4) + 10.0f;
if (i_this->pl_dir > (l_HIO.battle_init_range + 250.0f)) {
i_this->mode = 0;
actor->current.angle.y = actor->shape_angle.y;
break;
}
if (i_this->pl_dir > (l_HIO.battle_init_range + 100.0f)) {
actor->current.angle.y = i_this->search_angle_y;
} else if (i_this->pl_dir < (l_HIO.battle_init_range - 100.0f)) {
actor->current.angle.y = -i_this->search_angle_y;
} else {
actor->current.angle.y = cM_rndFX(32763.0f);
}
actor->speedF = cM_rndF(XREG_F(5) + 5.0f) + 5.0f;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_BREATH, -1);
}
if (frame == 13 || frame == 27) {
actor->speedF = 0.0f;
i_this->set_smoke_flag = 3;
if (frame == 13) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_L, 0, -1);
} else {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_R, 0, -1);
}
}
actor->gravity = XREG_F(6) + -5.0f;
break;
}
s16 sVar1;
if (i_this->mode >= 0) {
if (i_this->snap_angle_y_flag == 0) {
sVar1 = actor->current.angle.y;
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->search_angle_y, 2, 0x800);
sVar1 -= actor->current.angle.y;
s16 sVar2 = actor->current.angle.y - i_this->search_angle_y;
if (sVar2 > 0x800 || sVar2 < -0x800) {
fVar1 = 0.0f;
}
cLib_addCalc2(&actor->speedF, fVar1, 1.0f, 5.0f);
} else {
sVar1 = actor->shape_angle.y;
cLib_addCalcAngleS2(&actor->shape_angle.y, i_this->search_angle_y, 4, 0x800);
sVar1 -= actor->shape_angle.y;
}
sVar1 *= (s16)(YREG_S(5) + 2);
s16 sVar4 = YREG_S(6) + 0x1000;
if (sVar1 > sVar4) {
sVar1 = sVar4;
} else if (sVar1 < (s16)-sVar4) {
sVar1 = -sVar4;
}
cLib_addCalcAngleS2(&i_this->jnt_tail_y_rot_offset, sVar1, 2, 0x400);
}
u8 def = 0;
learn_check = i_this->learn;
if (fpcM_Search(shot_s_sub, i_this) != NULL || ((i_this->learn & 0x1000) != 0 && daPy_getPlayerActorClass()->checkHookshotShootReturnMode())) {
def = 1;
OS_REPORT(" DEF ON !!\n");
}
if (sVar4 == 0) {
if (i_this->unk_timer_1 == 0) {
i_this->action = ACTION_NORMAL;
i_this->mode = 0;
i_this->timer[0] = cM_rndF(50.0f) + 50.0f;
anm_init(i_this, ANM_WAIT_03, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
if (i_this->snap_angle_y_flag != 0) {
actor->current.angle.y = actor->shape_angle.y;
}
return;
}
} else if (
dComIfGp_checkPlayerStatus1(0, 0x2000000) != 0 ||
(((i_this->search_angle_x < 0x1000 && i_this->search_angle_x > -0x1000) || def != 0) && player_way_check(i_this))
) {
if (
(def != 0 || (i_this->pl_dir < l_HIO.battle_init_range && (i_this->learn & cc_pl_cut_bit_get()) != 0 &&
((daPy_getPlayerActorClass()->getCutAtFlg() != 0 || daPy_getPlayerActorClass()->getCutType() == daPy_py_c::CUT_TYPE_JUMP) ||
(i_this->learn & 0x400) != 0))) && i_this->field_0x74c < 1.0f
) {
i_this->action = ACTION_GUARD;
if (cc_pl_cut_bit_get() == 0x100) {
i_this->mode = 0;
} else {
i_this->mode = 5;
}
i_this->field_0x708 = TREG_F(10) + 30.0f;
i_this->field_0x70c = actor->shape_angle.y;
i_this->timer[0] = 0;
i_this->invulnerability_timer = 15;
} else if (i_this->pl_dir < l_HIO.attack_init_range) {
if (i_this->timer[2] == 0) {
i_this->timer[2] = JREG_F(1) + (cM_rndF(30.0f) + 30.0f);
f32 fVar1 = 1.0f;
if (cM_rndF(1.0f) < fVar1) {
wayCheck = way_check(i_this);
if (!wayCheck && cM_rndF(1.0f) < 0.75f) {
if (i_this->pl_dir < (l_HIO.attack_init_range - 100.0f) + TREG_F(7)) {
i_this->action = ACTION_ATTACK_0;
} else {
i_this->action = ACTION_ATTACK;
}
i_this->mode = 0;
} else {
i_this->action = ACTION_TAIL_ATTACK;
i_this->mode = 0;
}
}
}
}
}
i_this->field_0x6f4 = 1;
if ((i_this->frame_counter & 15) == 0 && bomb_view_check(i_this) != NULL) { // Every 16 frames
i_this->action = ACTION_BOMB_ACTION;
i_this->mode = 0;
}
if (
i_this->arg1 == 1 && move_gake_check(i_this, KREG_F(8) + 150.0f, 1) &&
(i_this->frame_counter & 15) == 0 && cM_rndF(1.0f) < 0.5f // Every 16 frames
) {
i_this->field_0x700 = cM_rndF(10.0f) + 10.0f;
i_this->field_0x701 = cM_rndF(1.9f);
}
if (move_gake_check(i_this, KREG_F(9) + 50.0f, 1)) {
if (i_this->arg1 == 1) {
if (cM_rndF(1.0f) < 0.5f) {
i_this->action = ACTION_TAIL_ATTACK;
i_this->mode = 0;
} else {
i_this->action = ACTION_GAKEJUMP;
i_this->mode = 0;
i_this->field_0x5c8 = actor->current.pos;
i_this->field_0x5bc = actor->current.pos;
i_this->invulnerability_timer = 100;
}
actor->speedF = 0.0f;
} else {
i_this->action = ACTION_BACKDROP;
i_this->mode = 0;
}
}
if (i_this->action != 3 && i_this->snap_angle_y_flag != 0) {
actor->current.angle.y = actor->shape_angle.y;
}
}
static void e_dn_jump(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
i_this->field_0x6f4 = 1;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_JUMP_A, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
break;
case 1:
if (!i_this->anm_p->isStop()) {
break;
}
actor->speed.y = KREG_F(13) + 50.0f;
i_this->mode = 2;
i_this->set_smoke_flag = 3;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_JUMP, -1);
// fallthrough
case 2:
actor->speedF =KREG_F(13) + 30.0f;
if (!(actor->speed.y <= 0.0f)) {
break;
}
anm_init(i_this, ANM_JUMP_B, 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 3;
break;
case 3:
if (!i_this->objacch.ChkGroundHit()) {
break;
}
anm_init(i_this, ANM_JUMP_C, 1.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 4;
i_this->set_smoke_flag = 3;
i_this->timer[0] = 3;
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_R, 0, -1);
break;
case 4:
if (i_this->timer[0] == 1) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_L, 0, -1);
}
cLib_addCalc0(&actor->speedF, 1.0f, 10.0f);
if (!i_this->anm_p->isStop()) {
break;
}
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
static void e_dn_gakejump(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp24, sp30;
i_this->field_0x6f4 = 1;
switch (i_this->mode) {
case 0:
if (jump_pos_check(i_this, &i_this->field_0x5bc)) {
anm_init(i_this, ANM_JUMP_A, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 2;
actor->current.angle.y = i_this->search_angle_y;
break;
}
if (i_this->anm_no != ANM_WAIT_01) {
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndF(0.1f) + 0.9f);
i_this->timer[0] = cM_rndF(15.0f) + 35.0f;
i_this->mode = 1;
}
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->search_angle_y, 4, 0x800);
break;
case 1:
i_this->field_0x6f4 = 2;
cMtx_YrotS(*calc_mtx, actor->shape_angle.y);
sp24.x = 0.0f;
sp24.y = 0.0f;
sp24.z = 100.0f;
MtxPosition(&sp24, &i_this->find_pos);
i_this->find_pos += actor->current.pos;
if (i_this->timer[0] != 0) {
break;
}
i_this->mode = 0;
break;
case 2:
if (!i_this->anm_p->isStop()) {
break;
}
if (jump_pos_check(i_this, &i_this->field_0x5bc)) {
i_this->mode = 3;
i_this->set_smoke_flag = 3;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_JUMP, -1);
i_this->timer[0] = 20;
i_this->timer[1] = 60;
i_this->field_0x5c8 = actor->current.pos;
} else {
anm_init(i_this, ANM_WAIT_01, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndF(0.1f) + 0.9f);
i_this->timer[0] = cM_rndF(15.0f) + 35.0f;
i_this->mode = 1;
break;
}
// fallthrough
case 3:
i_this->field_0x5d8 = 1;
sp24 = i_this->field_0x5bc - actor->current.pos;
i_this->cur_angle_y_target = cM_atan2s(sp24.x, sp24.z);
i_this->field_0x5d6 = -cM_atan2s(sp24.y, JMAFastSqrt(sp24.x * sp24.x + sp24.z * sp24.z));
actor->speedF = KREG_F(13) + 50.0f;
if (i_this->timer[0] == 1) {
anm_init(i_this, ANM_JUMP_B, 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
}
if (sp24.abs() < (actor->speedF * 1.1f)) {
actor->current.pos = i_this->field_0x5bc;
anm_init(i_this, ANM_JUMP_C, 1.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 4;
i_this->set_smoke_flag = 3;
i_this->timer[0] = 3;
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_R, 0, -1);
actor->speedF = 0.0f;
i_this->invulnerability_timer = 0;
}
if (!(i_this->timer[1] == 0 || i_this->objacch.ChkWallHit() != 0)) {
break;
}
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
break;
case 4:
if (i_this->timer[0] == 1) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_L, 0, -1);
}
if (!i_this->anm_p->isStop()) {
break;
}
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
static fopAc_ac_c* at_hit_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
fopAc_ac_c* player = dComIfGp_getPlayer(0);
if (i_this->mode >= 10) {
return NULL;
}
if (i_this->at_sph.ChkAtHit() != 0) {
return dCc_GetAc(i_this->at_sph.GetAtHitObj()->GetAc());
}
return NULL;
}
static void e_dn_attack_0(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp2c, sp38;
int frame = i_this->anm_p->getFrame();
i_this->field_0x6f4 = 1;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_ATTACK_TAIL_01, TREG_F(14) + 6.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_KNIFE, -1);
i_this->mode = 1;
// fallthrough
case 1:
if (frame >= 22 && frame <= 28) {
i_this->at_chk_flag = 1;
i_this->tail_at_sph_flag = 0;
}
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
cLib_addCalc0(&actor->speedF, 1.0f, 5.0f);
if (i_this->at_chk_flag != 0) {
fopAc_ac_c* actor_p = at_hit_check(i_this);
if (actor_p != NULL && fopAcM_GetName(actor_p) == PROC_ALINK && daPy_getPlayerActorClass()->checkPlayerGuard()) {
dComIfGp_getVibration().StartShock(3, 31, cXyz(0.0f, 1.0f, 0.0f));
}
}
}
static void e_dn_attack(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp34, sp40;
int frame = i_this->anm_p->getFrame();
i_this->field_0x6f4 = 1;
s16 sVar1, sVar2;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_ATTACK_TAIL_02, TREG_F(14) + 6.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_KNIFE2_A, -1);
i_this->mode = 1;
// fallthrough
case 1:
if (frame < 10 || (frame >= 25 && frame <= 30)) {
sVar1 = actor->current.angle.y;
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->search_angle_y, 2, 0x800);
sVar1 -= actor->current.angle.y;
sVar1 *= (s16)(YREG_S(5) + 2);
s16 sVar3 = YREG_S(6) + 0x1000;
if (sVar1 > sVar3) {
sVar1 = sVar3;
} else if (sVar1 < (s16)-sVar3) {
sVar1 = -sVar3;
}
cLib_addCalcAngleS2(&i_this->jnt_tail_y_rot_offset, sVar1, 2, 0x400);
}
if (frame >= 13 && frame <= 18) {
i_this->at_chk_flag = 1;
i_this->tail_at_sph_flag = 0;
}
if (frame >= 25 && frame <= 30) {
i_this->at_chk_flag = 1;
i_this->tail_at_sph_flag = 1;
cMtx_YrotS(*calc_mtx, actor->current.angle.y);
sp34.x = 0.0f;
sp34.y = 0.0f;
sp34.z = BREG_F(17) + 25.0f;
MtxPosition(&sp34, &sp40);
actor->current.pos += sp40;
}
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
cLib_addCalc0(&actor->speedF, 1.0f, 5.0f);
if (i_this->at_chk_flag != 0) {
fopAc_ac_c* actor_p = at_hit_check(i_this);
if (actor_p != NULL && fopAcM_GetName(actor_p) == PROC_ALINK && daPy_getPlayerActorClass()->checkPlayerGuard()) {
i_this->anm_p->setPlaySpeed(0.0f);
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
}
static void tail_eff_set(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
J3DModel* model = i_this->anm_p->getModel();
i_this->dn_tail_blur_a_prtcl = dComIfGp_particle_set(i_this->dn_tail_blur_a_prtcl, dPa_RM(ID_ZI_S_DNTAILBLUR_A), &actor->current.pos, NULL, NULL);
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(i_this->dn_tail_blur_a_prtcl);
if (emitter != NULL) {
MTXCopy(model->getAnmMtx(JNT_WORLD_ROOT), *calc_mtx);
emitter->setGlobalRTMatrix(*calc_mtx);
}
i_this->dn_tail_blur_b_prtcl = dComIfGp_particle_set(i_this->dn_tail_blur_b_prtcl, dPa_RM(ID_ZI_S_DNTAILBLUR_B), &actor->current.pos, NULL, NULL);
emitter = dComIfGp_particle_getEmitter(i_this->dn_tail_blur_b_prtcl);
if (emitter != NULL) {
MTXCopy(model->getAnmMtx(JNT_WORLD_ROOT), *calc_mtx);
emitter->setGlobalRTMatrix(*calc_mtx);
}
}
static void e_dn_tail_attack(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp30, sp3c;
int frame = i_this->anm_p->getFrame();
i_this->field_0x6f4 = 1;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_ATTACK_01, TREG_F(14) + 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
break;
case 1:
if (frame >= 19) {
tail_eff_set(i_this);
}
if (frame >= 33 && frame <= 41) {
i_this->at_chk_flag = 1;
i_this->tail_at_sph_flag = 2;
cMtx_YrotS(*calc_mtx, i_this->search_angle_y);
sp30.x = 0.0f;
sp30.y = 0.0f;
sp30.z = BREG_F(18) + 30.0f;
MtxPosition(&sp30, &sp3c);
actor->current.pos += sp3c;
}
if (frame == 40) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_R, 0, -1);
} else if (frame == 43) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_L, 0, -1);
}
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
actor->current.angle.y += i_this->angle_y_offset;
actor->shape_angle.y += i_this->angle_y_offset;
cLib_addCalcAngleS2(&i_this->angle_y_offset, 0, 1, 300);
cLib_addCalc0(&actor->speedF, 1.0f, 3.0f);
}
static void e_dn_guard(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
i_this->guard_flag = 1;
i_this->field_0x6f4 = 1;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_WAIT_02, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
actor->speed.y = KREG_F(0) + 20.0f;
actor->speedF = KREG_F(1) + -8.0f;
i_this->set_smoke_flag = 3;
break;
case 1:
i_this->invulnerability_timer = 5;
if (i_this->anm_p->getFrame() >= 5.0f) {
i_this->mode = 5;
i_this->timer[0] = KREG_S(1) + 20;
}
break;
case 5:
anm_init(i_this, ANM_GUARD, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_GUARD, -1);
i_this->mode = 6;
// fallthrough
case 6:
i_this->invulnerability_timer = 5;
if (i_this->objacch.ChkGroundHit()) {
cLib_addCalc0(&actor->speedF, 1.0f, 10.0f);
}
if (i_this->anm_p->getFrame() >= 8.0f) {
i_this->anm_p->setPlaySpeed(0.0f);
i_this->mode = 7;
actor->speedF = 0.0f;
}
break;
case 7:
i_this->invulnerability_timer = 5;
if (cc_pl_cut_bit_get() == 0x80 || cc_pl_cut_bit_get() == 0x800) {
i_this->timer[0] = KREG_S(0) + 20;
}
if (i_this->timer[0] == 0) {
i_this->mode = 8;
i_this->anm_p->setPlaySpeed(1.0f);
}
break;
case 8:
if (i_this->anm_p->isStop()) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
}
}
}
static void e_dn_s_damage(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
switch (i_this->mode) {
case 0:
i_this->mode = 1;
i_this->timer[0] = 20;
anm_init(i_this, ANM_WAIT_01, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
break;
case 1:
if (i_this->timer[0] == 0) {
i_this->action = ACTION_FIGHT_RUN;
i_this->mode = 0;
i_this->timer[0] = 40;
}
}
cLib_addCalc0(&actor->speedF, 1.0f, 3.0f);
}
static BOOL kado_check(e_dn_class* i_this) {
static int kado_bit[2] = {
1, 2,
};
static f32 kado_check_x[2] = {
80.0f, -80.0f,
};
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
dBgS_LinChk lin_chk;
cXyz work, start, end;
BOOL kado = FALSE;
cMtx_YrotS(*calc_mtx, i_this->field_0x724.y);
for (int i = 0; i < 2; i++) {
start = actor->current.pos;
start.y += JREG_F(0) + 100.0f;
work.x = JREG_F(1);
work.y = JREG_F(2);
work.z = JREG_F(3) + 70.0f;
MtxPosition(&work, &end);
start += end;
work.y = JREG_F(4) + 50.0f;
work.z = JREG_F(5) + -150.0f;
work.x = (JREG_F(6) + 1.0f) * kado_check_x[i];
MtxPosition(&work, &end);
end += start;
lin_chk.Set(&start, &end, actor);
if (dComIfG_Bgsp().LineCross(&lin_chk)) {
kado |= kado_bit[i];
}
}
if (kado == 3) {
kado = FALSE;
}
return kado;
}
static BOOL body_gake(e_dn_class* i_this) {
J3DModel* model = i_this->anm_p->getModel();
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz work, body_pos;
MTXCopy(model->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
work.set(BREG_F(10), BREG_F(11), BREG_F(12));
MtxPosition(&work, &body_pos);
dBgS_ObjGndChk gnd_chk;
body_pos.y += 100.0f;
gnd_chk.SetPos(&body_pos);
body_pos.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if ((actor->current.pos.y - body_pos.y) > 300.0f) {
return TRUE;
}
return FALSE;
}
static void e_dn_damage(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp34, sp40;
if (actor->health <= 0) {
fopAcM_OffStatus(actor, 0);
actor->attention_info.flags = 0;
}
if (daPy_py_c::checkNowWolf() != 0) {
if (i_this->field_0x6f3 == 0 && actor->checkWolfDownStartFlg()) {
if (i_this->timer[0] > 40) {
i_this->timer[0] = 90;
OS_REPORT(" DN WOLFHIT LONG \n");
} else if (i_this->timer[0] > 20) {
i_this->timer[0] = 70;
OS_REPORT(" DN WOLFHIT MID \n");
} else {
i_this->timer[0] = 50;
OS_REPORT(" DN WOLFHIT SHORT \n");
}
i_this->mode = 30;
i_this->field_0x6f3 = 1;
if (i_this->arg1 == 1) {
i_this->timer[1] = l_HIO.soul_disappear_time_strong + 1;
} else {
i_this->timer[1] = l_HIO.soul_disappear_time_weak + 1;
}
}
} else if (actor != NULL && actor->checkCutDownHitFlg()) {
actor->offCutDownHitFlg();
i_this->mode = 3;
actor->health = 0;
i_this->timer[0] = 100;
i_this->timer[1] = 46;
actor->offDownFlg();
actor->health = 0;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DEATH, -1);
i_this->death_flag = 1;
daPy_getPlayerActorClass()->onEnemyDead();
i_this->death_jnt_rot_counter = TREG_S(7) + 15;
}
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_BLOWNOFF, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
i_this->mode = 1;
actor->speedF = 0.0f;
i_this->field_0x7e8 = BREG_F(10) + 8000.0f;
if (actor->health <= 0) {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DEATH, -1);
i_this->death_flag = 1;
daPy_getPlayerActorClass()->onEnemyDead();
} else {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DAMAGE2, -1);
}
i_this->timer[0] = 0;
break;
case 1:
if (i_this->objacch.ChkWallHit() != 0 && i_this->timer[0] == 0) {
int kado_kabe = kado_check(i_this);
if (kado_kabe != 0) {
OS_REPORT(" ..KADO KABE ..%x\n", kado_kabe);
if (kado_kabe == 2) {
i_this->field_0x70e = 0xC00;
i_this->field_0x724.y += TREG_S(8) + -7000;
} else {
i_this->field_0x70e = -0xC00;
i_this->field_0x724.y += -(TREG_S(8) - 7000);
}
i_this->field_0x7e8 = BREG_F(10) + 8000.0f;
i_this->field_0x754 = BREG_F(4) + 100.0f;
i_this->field_0x75c = BREG_F(5) + 100.0f;
i_this->unk_timer_4 = DREG_S(1) + 40;
i_this->timer[0] = 60;
} else {
i_this->mode = 10;
actor->speed.y = 0.0f;
i_this->field_0x704 *= 0.2f;
i_this->field_0x724.y += 0x8000;
i_this->field_0x7e8 = BREG_F(10) + 8000.0f;
i_this->unk_timer_5 = BREG_S(7) + 5;
i_this->field_0x754 = BREG_F(4) + 100.0f;
i_this->field_0x75c = BREG_F(5) + 100.0f;
i_this->unk_timer_4 = DREG_S(1) + 40;
i_this->field_0x70e = 0;
}
break;
}
cLib_addCalcAngleS2(&i_this->field_0x724.x, -0x4000, 1, BREG_S(4) + 0x300);
actor->current.angle.y += i_this->field_0x70e;
actor->shape_angle.y = actor->current.angle.y;
if (i_this->field_0x724.x <= -0x3000 && i_this->objacch.ChkGroundHit()) {
i_this->mode = 2;
i_this->unk_timer_3 = 10;
i_this->sound.startCreatureSound(Z2SE_CM_BODYFALL_M, 0, -1);
if (i_this->left_right_flag == 0) {
anm_init(i_this, ANM_DIE_LEFT, 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
} else {
anm_init(i_this, ANM_DIE_RIGHT, 5.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
}
if (i_this->field_0x710 != 0) {
i_this->field_0x704 = 0.0f;
i_this->field_0x7e8 = BREG_F(12) + 2000.0f;
} else {
if (i_this->left_right_flag == 0) {
i_this->field_0x754 = -100.0f - BREG_F(6);
i_this->field_0x75c = -100.0f - BREG_F(7);
} else {
i_this->field_0x754 = BREG_F(4) + 100.0f;
i_this->field_0x75c = BREG_F(5) + 100.0f;
}
i_this->field_0x758 = -0x5000;
i_this->field_0x760 = -0x4000;
i_this->unk_timer_4 = DREG_S(1) + 40;
i_this->field_0x704 *= 0.5f;
actor->speed.y = TREG_F(6) + 20.0f;
i_this->field_0x70e /= 2;
actor->current.angle.y = i_this->field_0x724.y;
i_this->field_0x7e8 = BREG_F(12) + 8000.0f;
J3DModel* model = i_this->anm_p->getModel();
MTXCopy(model->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
sp34.set(0.0f, 0.0f, 0.0f);
MtxPosition(&sp34, &sp40);
fopAcM_effSmokeSet1(&i_this->field_0x10dc, &i_this->field_0x10e0, &sp40, NULL, 1.8f, &actor->tevStr, 1);
}
}
break;
case 2:
actor->current.angle.y += i_this->field_0x70e;
actor->shape_angle.y = actor->current.angle.y;
cLib_addCalcAngleS2(&i_this->field_0x724.x, -0x4000, 1, BREG_S(4) + 0x300);
if (i_this->objacch.ChkGroundHit()) {
if (actor->health > 0 && !daPy_py_c::checkNowWolf()) {
actor->onDownFlg();
}
dKy_Sound_set(actor->current.pos, 100, fopAcM_GetID(&i_this->actor), 5);
i_this->unk_timer_3 = 10;
if (i_this->left_right_flag == 0) {
anm_init(i_this, ANM_DIE_LEFT, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
} else {
anm_init(i_this, ANM_DIE_RIGHT, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
}
i_this->field_0x704 = 0.0f;
i_this->field_0x724.x = -0x4000;
for (int i = 0; i < 4; i++) {
i_this->field_0x802[i] = cM_rndF(10.0f);
}
actor->current.angle.y = i_this->field_0x724.y;
if (daPy_py_c::checkNowWolf() != 0) {
i_this->timer[0] = 80;
i_this->timer[1] = 55;
} else {
i_this->timer[0] = cM_rndF(10.0f) + 60.0f;
i_this->timer[1] = 35;
}
i_this->mode = 3;
i_this->field_0x7e8 = BREG_F(13) + 1500.0f;
J3DModel* model = i_this->anm_p->getModel();
MTXCopy(model->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
sp34.set(0.0f, 0.0f, 0.0f);
MtxPosition(&sp34, &sp40);
fopAcM_effSmokeSet1(&i_this->field_0x10dc, &i_this->field_0x10e0, &sp40, NULL, 1.0f, &actor->tevStr, 1);
}
break;
case 3:
if (body_gake(i_this)) {
i_this->field_0x704 = VREG_F(8) + -20.0f;
i_this->field_0x724.x -= (s16)(VREG_S(7) + 0x300);
}
if (actor->health <= 0 && i_this->timer[1] == 0) {
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
sp34.set(0.0f, 0.0f, 0.0f);
MtxPosition(&sp34, &sp40);
s8 unused = 0;
dn_disappear(i_this);
fopAcM_delete(actor);
return;
}
if (daPy_getPlayerActorClass()->getCutType() != daPy_py_c::CUT_TYPE_DOWN && i_this->timer[0] == 0) {
i_this->mode = 20;
if (i_this->left_right_flag == 0) {
anm_init(i_this, ANM_DIE_LEFT_UP, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
} else {
anm_init(i_this, ANM_DIE_RIGHT_UP, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
}
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_UP, -1);
if (actor != NULL) {
actor->offDownFlg();
}
}
break;
case 10:
if (i_this->unk_timer_5 != 0) {
cLib_addCalcAngleS2(&i_this->field_0x724.x, 0, 1, BREG_S(4) + 0x300);
} else {
cLib_addCalcAngleS2(&i_this->field_0x724.x, -0x4000, 1, BREG_S(5) + 0x800);
if (i_this->objacch.ChkGroundHit()) {
i_this->mode = 2;
if (i_this->left_right_flag == 0) {
i_this->field_0x754 = -100.0f - BREG_F(6);
i_this->field_0x75c = -100.0f - BREG_F(7);
} else {
i_this->field_0x754 = BREG_F(4) + 100.0f;
i_this->field_0x75c = BREG_F(5) + 100.0f;
}
i_this->field_0x758 = -0x5000;
i_this->field_0x760 = -0x4000;
i_this->field_0x704 *= 0.5f;
actor->speed.y = TREG_F(6) + 20.0f;
actor->current.angle.y = i_this->field_0x724.y;
i_this->field_0x7e8 = BREG_F(12) + 8000.0f;
}
}
break;
case 20:
if (i_this->anm_p->getFrame() >= 35.0f) {
i_this->field_0x730.x = i_this->field_0x730.z = 0;
}
if (i_this->anm_p->isStop()) {
i_this->field_0x724.x = i_this->field_0x724.y = 0;
anm_init(i_this, ANM_WAIT_01, 0.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
i_this->timer[0] = 5;
i_this->mode = 21;
if (actor != NULL) {
actor->offDownFlg();
}
}
break;
case 21:
case 22:
i_this->invulnerability_timer = 0;
if (i_this->timer[0] == 0) {
i_this->action = ACTION_NORMAL;
i_this->mode = 0;
i_this->timer[0] = cM_rndF(50.0f) + 50.0f;
anm_init(i_this, ANM_WAIT_03, 10.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
break;
case 30:
if (!actor->checkWolfDownPullFlg()) {
i_this->timer[1] = 0;
}
if (i_this->timer[0] == 0) {
i_this->mode = 31;
if (i_this->left_right_flag == 0) {
anm_init(i_this, ANM_BRUSH_LEFT_UP, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
} else {
anm_init(i_this, ANM_BRUSH_RIGHT_UP, 3.0f, J3DFrameCtrl::EMode_NONE, 1.0f);
}
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_UP, -1);
i_this->timer[0] = 10;
} else if (i_this->timer[1] == 1) {
actor->onWolfDownPullEndFlg();
actor->offCutDownHitFlg();
actor->health = 0;
i_this->timer[0] = 1000;
i_this->timer[1] = 35;
i_this->mode = 3;
}
break;
case 31:
if (i_this->timer[0] == 0) {
actor->offDownFlg();
i_this->mode = 20;
i_this->field_0x6f3 = 0;
}
}
if (actor != NULL && actor->checkDownFlg()) {
i_this->field_0x6f2 = 0;
}
if (i_this->death_jnt_rot_counter != 0) {
i_this->death_jnt_rot_counter--;
i_this->death_jnt_rot = i_this->death_jnt_rot_counter * cM_ssin(i_this->death_jnt_rot_counter * (TREG_S(9) + 0x3800)) * (TREG_F(5) + 100.0f);
}
}
static void e_dn_backdrop(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
f32 zero = 0.0f;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_DRAWBACK, 3.0f, J3DFrameCtrl::EMode_NONE, 0.5f);
i_this->mode = 1;
i_this->field_0x724.y = (s16)actor->shape_angle.y;
i_this->field_0x724.x = 0;
actor->speedF = -3.0f;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DEATH, -1);
// fallthrough
case 1:
if (i_this->field_0x724.x < -0x4000) {
actor->speedF = -6.0f;
}
if (actor->speed.y < -20.0f) {
i_this->mode = 2;
actor->speedF = 0.0f;
}
// fallthrough
case 2:
// Target: -157.5 degrees, Step: (field_0x724.x - (-157.5 degrees)) / 2, Max Step: 11.25 degrees
cLib_addCalcAngleS2(&i_this->field_0x724.x, -0x7000, 2, 0x800);
if (i_this->mode == 2 && actor->current.pos.y <= (KREG_F(17) + (i_this->objacch.GetGroundH() + 100.0f))) {
actor->current.pos.y = KREG_F(17) + (i_this->objacch.GetGroundH() + 100.0f);
i_this->field_0x724.x = -0x4000;
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
i_this->field_0x704 = 0.0f;
actor->health = 0;
}
}
}
static void e_dn_water(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp20, sp2c;
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
sp20.set(0.0f, 0.0f, 0.0f);
MtxPosition(&sp20, &sp2c);
i_this->invulnerability_timer = 10;
switch (i_this->mode) {
case 0:
case 1: {
actor->speed.y = 0.0f;
if (i_this->left_right_flag == 0) {
anm_init(i_this, ANM_DROWNED_A, 3.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
} else {
anm_init(i_this, ANM_DROWNED_B, 3.0f, J3DFrameCtrl::EMode_LOOP, 1.0f);
}
i_this->timer[0] = 60;
i_this->field_0x708 = i_this->field_0x704 = actor->speedF = 0.0f;
cXyz pos = actor->current.pos;
pos.y = i_this->field_0xa5c;
if (i_this->mode == 0) {
fopKyM_createWpillar(&pos, 1.5f, 0);
} else {
fopKyM_createMpillar(&pos, 1.0f);
}
i_this->mode = 10;
break;
}
case 10:
actor->speed.y = 0.0f;
cLib_addCalc2(&actor->current.pos.y, i_this->field_0xa5c, 0.5f, 5.0f);
cLib_addCalcAngleS2(&i_this->field_0x724.x, -0x4000, 4, BREG_S(4) + 0x400);
if (i_this->timer[0] == 0) {
dn_disappear(i_this);
}
break;
}
}
static void e_dn_reg(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz sp34, sp40;
f32 dash_speed = 0.0f;
int frame = i_this->anm_p->getFrame();
i_this->field_0x6f2 = 0;
i_this->invulnerability_timer = 10;
switch (i_this->mode) {
case 0:
anm_init(i_this, ANM_RUN, 5.0f, J3DFrameCtrl::EMode_LOOP, cM_rndFX(0.05f) + 1.0f);
i_this->mode = 1;
if ((i_this->arg0 & 1) != 0) {
actor->current.pos.set(-8613.0f, 2000.0f, 8017.0f);
actor->current.angle.set(0, 0x19A0, 0);
} else {
actor->current.pos.set(-8044.0f, 2000.0f, 8616.0f);
actor->current.angle.set(0, -0x629E, 0);
}
actor->old.pos = actor->current.pos;
i_this->cur_angle_y_target = actor->current.angle.y;
i_this->timer[0] = nREG_S(0) + 14;
// fallthrough
case 1:
dash_speed = l_HIO.dash_speed;
if ((i_this->frame_counter & 3) == 0) { // Every 4 frames
if ((i_this->frame_counter & 4) != 0) { // Every 5 frames
i_this->set_smoke_flag = 1;
} else {
i_this->set_smoke_flag = 2;
}
}
if (i_this->timer[0] == 0) {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
cMtx_YrotS(*calc_mtx, (s16)player->shape_angle.y);
if ((i_this->arg0 & 1) != 0) {
sp34.x = 100.0f;
} else {
sp34.x = -100.0f;
}
sp34.y = 0.0f;
sp34.z = 0.0f;
MtxPosition(&sp34, &sp40);
sp40 += player->current.pos;
sp34 = sp40 - actor->current.pos;
i_this->cur_angle_y_target = cM_atan2s(sp34.x, sp34.z);
}
break;
case 2:
if ((i_this->arg0 & 1) != 0) {
i_this->field_0x750 = actor->shape_angle.y - (0x4000 << 2) + 0x4000;
i_this->field_0x724.y = actor->shape_angle.y + 0x4000;
i_this->field_0x70e = (cM_rndFX(800.0f) + 3000.0f);
} else {
i_this->field_0x750 = actor->shape_angle.y - 0x4000;
i_this->field_0x724.y = actor->shape_angle.y - 0x4000;
i_this->field_0x70e = -(cM_rndFX(800.0f) + 3000.0f);
}
i_this->field_0x74c = 150.0f;
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
actor->speed.y = TREG_F(13) + 40.0f + cM_rndF(10.0f);
i_this->field_0x704 = TREG_F(18) + -30.0f;
i_this->unk_timer_4 = DREG_S(2) + 50;
actor->health = 0;
break;
}
cLib_addCalcAngleS2(&actor->current.angle.y, i_this->cur_angle_y_target, 2, 0x800);
s16 sVar1 = actor->current.angle.y - i_this->cur_angle_y_target;
if (sVar1 > 0x800 || sVar1 < -0x800) {
dash_speed = 0.0f;
}
actor->speedF = dash_speed;
i_this->field_0x6f4 = 1;
}
static void wolfkick_damage(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
fopAc_ac_c* player = dComIfGp_getPlayer(0);
i_this->field_0x750 = (actor->shape_angle.y - 0x8000) - i_this->at_info.mHitDirection.y;
i_this->field_0x74c = 150.0f;
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
i_this->field_0x724.y = player->shape_angle.y + 0x8000;
actor->speed.y = 0.0f;
i_this->field_0x704 = -1.0f;
i_this->unk_timer_4 = DREG_S(2) + 50;
i_this->sound.startCollisionSE(Z2SE_HIT_WOOD_WEAPON, 31);
i_this->field_0x710 = 1;
}
static void big_damage(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
i_this->field_0x750 = (actor->shape_angle.y - 0x8000) - i_this->at_info.mHitDirection.y;
i_this->field_0x74c = 150.0f;
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
i_this->field_0x724.y = i_this->at_info.mHitDirection.y;
actor->speed.y = TREG_F(13) + 25.0f + cM_rndF(10.0f);
i_this->field_0x704 = TREG_F(18) + -20.0f;
i_this->unk_timer_4 = DREG_S(2) + 50;
if ((i_this->at_info.mHitBit & 0x80) != 0) {
OS_REPORT("SPIN CUT HIT !!\n");
i_this->field_0x70e = cM_rndFX(800.0f) + 3000.0f;
} else if ((i_this->at_info.mHitBit & 0x800) != 0) {
OS_REPORT("SPIN CUT L HIT !!\n");
i_this->field_0x70e = -(cM_rndFX(800.0f) + 3000.0f);
} else {
i_this->field_0x70e = cM_rndFX(700.0f);
}
i_this->field_0x710 = 0;
}
static void small_damage(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
i_this->action = ACTION_S_DAMAGE;
i_this->mode = 0;
i_this->unk_timer_4 = DREG_S(6) + 50;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DAMAGE, -1);
if (i_this->snap_angle_y_flag != 0) {
actor->current.angle.y = actor->shape_angle.y;
}
i_this->field_0x750 = (actor->shape_angle.y - 0x8000) - i_this->at_info.mHitDirection.y;
i_this->field_0x74c = 150.0f;
i_this->field_0x708 = TREG_F(0) + 25.0f;
i_this->field_0x70c = i_this->at_info.mHitDirection.y;
}
static void damage_check(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
if (l_HIO.no_learn != 0) {
i_this->learn = 0;
}
i_this->stts.Move();
if (i_this->invulnerability_timer == 0) {
fopEn_enemy_c* enemy = (fopEn_enemy_c*)actor;
dCcU_AtInfo atInfo;
if (l_HIO.invulnerable != 0) {
actor->health = 100;
}
for (int i = 0; i <= 2; i++) {
if (i_this->cc_sph[i].ChkTgHit() != 0) {
i_this->at_info.mpCollider = i_this->cc_sph[i].GetTgHitObj();
if (player->getCutType() != daPy_py_c::CUT_TYPE_WOLF_B_LEFT && player->getCutType() != daPy_py_c::CUT_TYPE_WOLF_B_RIGHT &&
i_this->at_info.mpCollider->ChkAtType(AT_TYPE_WOLF_ATTACK)) {
if (player->onWolfEnemyHangBite(enemy)) {
OS_REPORT("DN PL BITE HANG \n");
i_this->action = ACTION_WOLFBITE;
i_this->mode = 0;
i_this->invulnerability_timer = 1000;
i_this->sound.startCollisionSE(Z2SE_HIT_WOLFBITE, 31);
}
return;
}
i_this->unk_timer_6 = 3;
if (i_this->at_info.mpCollider->ChkAtType(AT_TYPE_10000000)) {
wolfkick_damage(i_this);
i_this->invulnerability_timer = 1000;
} else {
at_power_check(&i_this->at_info);
s16 sVar1 = actor->health;
cc_at_check(actor, &i_this->at_info);
if (daPy_getPlayerActorClass()->getCutType() == daPy_py_c::CUT_TYPE_HEAD_JUMP) {
i_this->at_info.mHitStatus = 0;
}
if (i_this->at_info.mpCollider->ChkAtType(AT_TYPE_UNK)) {
i_this->invulnerability_timer = 20;
} else {
i_this->invulnerability_timer = 10;
}
if (i_this->at_info.mAttackPower <= 1) {
i_this->invulnerability_timer = 10;
}
i_this->learn |= i_this->at_info.mHitBit;
if (i_this->at_info.mHitType == 16 || i_this->at_info.mpCollider->ChkAtType(AT_TYPE_HOOKSHOT)) {
actor->health = sVar1;
i_this->action = ACTION_DRAWBACK;
i_this->mode = 0;
if (i_this->snap_angle_y_flag != 0) {
actor->current.angle.y = actor->shape_angle.y;
}
i_this->field_0x750 = (actor->shape_angle.y - 0x8000) - i_this->at_info.mHitDirection.y;
i_this->field_0x74c = KREG_F(9) + 100.0f;
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DAMAGE, -1);
break;
}
if (daPy_getPlayerActorClass()->checkHorseRide() != 0 && dComIfGp_getHorseActor()->speedF >= 20.0f && i_this->at_info.mHitType == 1) {
i_this->at_info.mAttackPower = 20;
if (cM_rndF(1.0f) < 0.5f) {
i_this->at_info.mHitBit |= 0x80;
} else {
i_this->at_info.mHitBit |= 0x800;
}
}
if (actor->health <= 0 || i_this->at_info.mHitStatus != 0) {
if (player->getCutType() == daPy_py_c::CUT_TYPE_JUMP && player->checkCutJumpCancelTurn()) {
small_damage(i_this);
i_this->invulnerability_timer = 3;
} else {
big_damage(i_this);
i_this->invulnerability_timer = 1000;
}
} else {
small_damage(i_this);
}
actor->speedF = 0.0f;
}
break;
}
}
for (int i = 0; i <= 2; i++) {
if (actor->health <= 1) {
i_this->cc_sph[i].SetTgHitMark((CcG_Tg_HitMark)3);
}
}
}
}
static void action(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
cXyz work, sp24c;
i_this->field_0x6f4 = 0;
i_this->pl_dir = fopAcM_searchPlayerDistanceXZ(actor);
i_this->search_angle_y = fopAcM_searchPlayerAngleY(actor);
i_this->search_angle_x = fopAcM_searchPlayerAngleX(actor);
damage_check(i_this);
i_this->snap_angle_y_flag = 0;
s8 pl_search = 0;
s8 bVar2 = 1;
actor->offHeadLockFlg();
if (fopAcM_otherBgCheck(player, actor)) {
fopAcM_OffStatus(actor, 0);
actor->attention_info.flags = 0;
} else {
fopAcM_OnStatus(actor, 0);
actor->attention_info.flags = fopAc_AttnFlag_BATTLE_e;
}
switch (i_this->action) {
case ACTION_NORMAL:
e_dn_normal(i_this);
break;
case ACTION_FIGHT_RUN:
e_dn_fight_run(i_this);
pl_search = 1;
break;
case ACTION_ATTACK_0:
e_dn_attack_0(i_this);
pl_search = 1;
break;
case ACTION_ATTACK:
e_dn_attack(i_this);
pl_search = 1;
break;
case ACTION_TAIL_ATTACK:
e_dn_tail_attack(i_this);
pl_search = 1;
break;
case ACTION_GUARD:
e_dn_guard(i_this);
pl_search = 1;
break;
case ACTION_JUMP:
e_dn_jump(i_this);
pl_search = 1;
break;
case ACTION_STAY:
e_dn_stay(i_this);
break;
case ACTION_OTOREAC:
e_dn_otoreac(i_this);
break;
case ACTION_DRAWBACK:
e_dn_drawback(i_this);
pl_search = 1;
break;
case ACTION_WOLFBITE:
e_dn_wolfbite(i_this);
break;
case ACTION_BOMB_ACTION:
e_dn_bomb_action(i_this);
break;
case ACTION_S_DAMAGE:
e_dn_s_damage(i_this);
break;
case ACTION_DAMAGE:
e_dn_damage(i_this);
break;
case ACTION_BACKDROP:
e_dn_backdrop(i_this);
break;
case ACTION_WATER:
e_dn_water(i_this);
bVar2 = 0;
break;
case ACTION_GAKEJUMP:
e_dn_gakejump(i_this);
pl_search = 1;
break;
case ACTION_REG:
e_dn_reg(i_this);
break;
}
if (bVar2) {
dBgS_ObjGndChk obj_gnd_chk;
dBgS_ObjGndChk_Spl spl_chk;
work = actor->current.pos;
work.y += 150.0f;
spl_chk.SetPos(&work);
obj_gnd_chk.SetPos(&work);
i_this->field_0xa5c = dComIfG_Bgsp().GroundCross(&spl_chk);
f32 fVar1 = i_this->field_0xa5c - dComIfG_Bgsp().GroundCross(&obj_gnd_chk);
if (actor->current.pos.y < i_this->field_0xa5c && fVar1 > 100.0f) {
OS_REPORT("DN YOGAN \n");
i_this->action = ACTION_WATER;
if (dComIfG_Bgsp().GetPolyAtt0(spl_chk) == 6) {
i_this->mode = 1;
} else {
i_this->mode = 0;
}
actor->current.pos.y = i_this->field_0xa5c;
}
}
if (pl_search) {
i_this->sound.setLinkSearch(true);
} else {
i_this->sound.setLinkSearch(false);
}
if (i_this->snap_angle_y_flag == 0) {
cLib_addCalcAngleS2(&actor->shape_angle.y, actor->current.angle.y, 2, 0x2000);
}
cLib_addCalcAngleS2(&actor->shape_angle.x, actor->current.angle.x, 2, 0x2000);
cLib_addCalcAngleS2(&actor->shape_angle.z, actor->current.angle.z, 2, 0x2000);
if (i_this->field_0x5d8 != 0) {
cMtx_YrotS(*calc_mtx, i_this->cur_angle_y_target);
cMtx_XrotM(*calc_mtx, i_this->field_0x5d6);
work.x = 0.0f;
work.y = 0.0f;
work.z = actor->speedF;
MtxPosition(&work, &sp24c);
actor->current.pos += sp24c;
work = i_this->field_0x5bc - i_this->field_0x5c8;
f32 fVar1 = work.abs();
work = i_this->field_0x5bc - actor->current.pos;
f32 fVar2 = work.abs();
f32 fVar3 = fVar1 * (NREG_F(19) + 0.3f);
if (fVar3 > NREG_F(18) + 250.0f) {
fVar3 = NREG_F(18) + 250.0f;
}
i_this->cur_pos_y_offset = fVar3 * cM_ssin((fVar2 / fVar1) * 32768.0f);
i_this->field_0x5d8 = 0;
} else {
cLib_addCalc0(&i_this->cur_pos_y_offset, 1.0f, 30.0f);
if (i_this->field_0x704) {
cMtx_YrotS(*calc_mtx, i_this->field_0x724.y);
if (i_this->unk_timer_5 == 0) {
work.z = i_this->field_0x704;
} else {
work.z = 0.0f;
actor->speed.y = 0.0f;
}
actor->gravity = -4.0f;
} else {
cMtx_YrotS(*calc_mtx, actor->current.angle.y);
work.z = actor->speedF;
}
work.x = 0.0f;
work.y = 0.0f;
MtxPosition(&work, &sp24c);
actor->speed.x = sp24c.x;
actor->speed.z = sp24c.z;
actor->speed.y += actor->gravity;
actor->current.pos += actor->speed;
actor->gravity = -5.0f;
if (actor->speed.y < -100.0f) {
actor->speed.y = -100.0f;
}
if (i_this->action != ACTION_STAY && i_this->field_0x6f2 != 0) {
cXyz* move_pos = i_this->stts.GetCCMoveP();
if (move_pos != NULL) {
actor->current.pos.x += move_pos->x;
actor->current.pos.z += move_pos->z;
}
}
if (i_this->field_0x708 > 0.1f) {
work.x = 0.0f;
work.y = 0.0f;
work.z = -i_this->field_0x708;
cMtx_YrotS(*calc_mtx, i_this->field_0x70c);
MtxPosition(&work, &sp24c);
actor->current.pos += sp24c;
cLib_addCalc0(&i_this->field_0x708, 1.0f, TREG_F(12) + 7.0f);
}
}
s16 max_step, sVar2, sVar3;
sVar2 = 0;
sVar3 = 0;
max_step = 0x800;
if (i_this->field_0x700 != 0) {
i_this->field_0x700--;
i_this->field_0x6f4 = 2;
cMtx_YrotS(*calc_mtx, actor->shape_angle.y);
if (i_this->field_0x701 != 0) {
work.x = 100.0f;
} else {
work.x = -100.0f;
}
work.y = JREG_F(4) + 100.0f;
work.z = -100.0f;
MtxPosition(&work, &i_this->find_pos);
i_this->find_pos += actor->current.pos;
max_step = 0x400;
}
if (i_this->field_0x6f4 != 0) {
if (i_this->field_0x6f4 == 5) {
if ((i_this->frame_counter & 15) == 0 && cM_rndF(1.0f) < 0.3f) { // Every 16 frames
i_this->field_0x6fc = cM_rndFX(2500.0f);
}
} else {
if (i_this->field_0x6f4 == 1) {
work = player->eyePos - actor->current.pos;
} else if (i_this->field_0x6f4 == 2) {
work = i_this->find_pos - actor->current.pos;
} else {
work = player->eyePos - actor->current.pos;
}
work.y += -(TREG_F(2) + 150.0f) * l_HIO.model_size;
sVar2 = cM_atan2s(work.x, work.z) - actor->shape_angle.y;
sVar3 = actor->shape_angle.x + cM_atan2s(work.y, JMAFastSqrt(work.x * work.x + work.z * work.z));
if (sVar2 > 0x2710) {
sVar2 = 10000;
} else if (sVar2 < -10000) {
sVar2 = -10000;
}
if (sVar3 > 0x2710) {
sVar3 = 10000;
} else if (sVar3 < -20000) {
sVar3 = -20000;
}
cLib_addCalcAngleS2(&i_this->field_0x6f6, sVar2 / 2, 2, max_step);
cLib_addCalcAngleS2(&i_this->field_0x6f8, sVar3 / 2, 2, max_step);
}
i_this->field_0x6fc = 0;
} else {
cLib_addCalcAngleS2(&i_this->field_0x6f6, 0, 2, max_step);
cLib_addCalcAngleS2(&i_this->field_0x6f8, 0, 2, max_step);
i_this->field_0x6fc = 0;
}
cLib_addCalcAngleS2(&i_this->field_0x6fa, i_this->field_0x6fc, 4, 0x400);
if (i_this->field_0x6fe != 0) {
i_this->field_0x6fe--;
i_this->field_0x6fa = i_this->field_0x6fe * cM_ssin(i_this->field_0x6fe * (BREG_S(5) + 12000)) * (BREG_F(18) + 200.0f);
}
if (i_this->field_0x74c > 1.0f) {
cMtx_YrotS(*calc_mtx, i_this->field_0x750);
work.x = 0.0f;
work.y = 0.0f;
work.z = (TREG_F(7) + 120.0f) * i_this->field_0x74c;
if (work.z > 15000.0f) {
work.z = 15000.0f;
}
MtxPosition(&work, &sp24c);
i_this->field_0x7a4[0].y = sp24c.x;
i_this->field_0x7a4[0].x = sp24c.z;
i_this->field_0x7a4[1].y = sp24c.x;
i_this->field_0x7a4[1].x = sp24c.z;
cLib_addCalc0(&i_this->field_0x74c, 0.5f, TREG_F(7) + 10.0f);
}
if (fabsf(i_this->field_0x75c) > 1.0f) {
i_this->field_0x7a4[1].x = i_this->field_0x75c * cM_scos(i_this->field_0x760) * (BREG_F(0) + 70.0f);
i_this->field_0x7a4[2].x += i_this->field_0x7a4[1].x;
cLib_addCalc0(&i_this->field_0x75c, 1.0f, BREG_F(1) + 3.0f);
i_this->field_0x760 += BREG_S(0) + 4000;
}
if (fabsf(i_this->field_0x754) > 1.0f) {
i_this->field_0x7a4[0].x = i_this->field_0x754 * cM_scos(i_this->field_0x758) * (BREG_F(2) + 70.0f);
cLib_addCalc0(&i_this->field_0x754, 1.0f, BREG_F(3) + 3.0f);
i_this->field_0x758 += BREG_S(1) + 4000;
}
if (actor->speed.y < 0.0f && i_this->objacch.ChkGroundHit()) {
cLib_addCalc0(&i_this->field_0x75c, 1.0f, 30.0f);
cLib_addCalc0(&i_this->field_0x754, 1.0f, 30.0f);
}
if (i_this->field_0x704) {
s16 sVar4 = i_this->field_0x724.y - actor->shape_angle.y;
i_this->field_0x7a4[3].y = 0x4000 + -sVar4;
if (i_this->field_0x7a4[3].y > 6000) { // ~33°
i_this->field_0x7a4[3].y = 6000;
} else if (i_this->field_0x7a4[3].y < -9000) { // ~49.4°
i_this->field_0x7a4[3].y = -9000;
}
i_this->field_0x7a4[4].y = 0x4000 + -sVar4;
if (i_this->field_0x7a4[4].y > 17000) { // ~93.4°
i_this->field_0x7a4[4].y = 17000;
} else if (i_this->field_0x7a4[4].y < 0) {
i_this->field_0x7a4[4].y = 0;
}
i_this->field_0x7a4[5].y = sVar4 + 0x4000;
if (i_this->field_0x7a4[5].y > 6000) {
i_this->field_0x7a4[5].y = 6000;
} else if (i_this->field_0x7a4[5].y < -9000) {
i_this->field_0x7a4[5].y = -9000;
}
i_this->field_0x7a4[6].y = sVar4 + 0x4000;
if (i_this->field_0x7a4[6].y > 17000) {
i_this->field_0x7a4[6].y = 17000;
} else if (i_this->field_0x7a4[6].y < 0) {
i_this->field_0x7a4[6].y = 0;
}
cMtx_YrotS(*calc_mtx, sVar4);
work.x = 0.0f;
work.y = 0.0f;
work.z = BREG_F(8) + 12000.0f;
MtxPosition(&work, &sp24c);
i_this->field_0x836.y = -sp24c.x;
i_this->field_0x836.x = -sp24c.z * 1.3f;
if (i_this->field_0x836.x > (s16)(BREG_S(6) + 10000)) {
i_this->field_0x836.x = BREG_S(6) + 10000;
}
i_this->field_0x836.x += BREG_S(7) + 6000;
}
static s16 j_spd[11] = {
0x4000, 0x4000, 0x4000,
0x1000, 0x1000, 0x1000,
0x1000, 0x4000, 0x4000,
0x4000, 0x4000
};
for (int i = 0; i < 11; i++) {
cLib_addCalcAngleS2(&i_this->field_0x762[i].x, i_this->field_0x7a4[i].x, 2, j_spd[i]);
cLib_addCalcAngleS2(&i_this->field_0x762[i].y, i_this->field_0x7a4[i].y, 2, j_spd[i]);
cLib_addCalcAngleS2(&i_this->field_0x762[i].z, i_this->field_0x7a4[i].z, 2, j_spd[i]);
i_this->field_0x7a4[i].x = i_this->field_0x7a4[i].z = 0;
if (i >= 3 && i <= 6) {
if (i_this->field_0x802[i - 3] == 0) {
s16 max_step;
if (i == 4 || i == 6) {
max_step = 0x600; // ~8.4°
} else {
max_step = 0x800; // 11.25°
}
cLib_addCalcAngleS2(&i_this->field_0x7a4[i].y, 0, 1, max_step);
} else {
i_this->field_0x802[i - 3]--;
}
} else {
i_this->field_0x7a4[i].y = 0;
}
if (i >= 3) {
i_this->field_0x7ec[i] = i_this->field_0x7e8 * cM_scos(i_this->frame_counter * (BREG_S(0) + 4000) + i * (BREG_S(1) + 20000));
}
}
cLib_addCalc0(&i_this->field_0x7e8, 1.0f, BREG_F(11) + 100.0f);
cLib_addCalcAngleS2(&i_this->field_0x830.y, i_this->field_0x836.y, 2, 0x800);
cLib_addCalcAngleS2(&i_this->field_0x830.x, i_this->field_0x836.x, 2, 0x800);
i_this->field_0x836.y = i_this->field_0x836.x = 0;
if (i_this->unk_timer_4 != 0) {
i_this->unk_timer_4--;
}
f32 fVar1 = i_this->unk_timer_4 * (DREG_F(13) + 1.0f);
if (fVar1 > 30.0f) {
fVar1 = 30.0f;
}
fVar1 *= fVar1;
for (int i = 0; i < 4; i++) {
i_this->field_0x80e[i].x = fVar1 * (cM_ssin(i_this->frame_counter * (DREG_S(5) + 5000) + i * (DREG_S(7) + -15000)) * (DREG_F(18) + 5.0f));
i_this->field_0x80e[i].y = fVar1 * (cM_ssin(i_this->frame_counter * (DREG_S(5) + 0x12C0) + i * (DREG_S(7) + -13000)) * (DREG_F(18) + 5.0f));
}
cLib_addCalcAngleS2(&i_this->jnt_tail_y_rot_offset, 0, 4, 0x100);
if (i_this->unk_timer_3 != 0) {
i_this->unk_timer_3--;
if (i_this->field_0x724.x != 0) {
Vec sp258;
cXyz sp264, sp270;
dBgS_GndChk gnd_chk;
s16 sVar6, sVar7;
sVar6 = 0;
sVar7 = 0;
fVar1 = 100.0f;
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
work.set(0.0f, 0.0f, 0.0f);
MtxPosition(&work, &sp264);
sp264.y += 100.0f;
sp264.y += 100.0f;
gnd_chk.SetPos(&sp264);
sp264.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if (sp264.y != -G_CM3D_F_INF) {
sp258.x = sp264.x;
sp258.y = sp264.y + 100.0f;
sp258.z = sp264.z + fVar1;
gnd_chk.SetPos(&sp258);
sp258.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if (sp258.y != -G_CM3D_F_INF) {
f32 z, y;
y = sp258.y - sp264.y;
z = sp258.z - sp264.z;
sVar7 = -cM_atan2s(y, z);
if (sVar7 > 0x3000 || sVar7 < -0x3000) {
sVar7 = 0;
}
}
sp258.x = sp264.x + fVar1;
sp258.y = sp264.y + 100.0f;
sp258.z = sp264.z;
gnd_chk.SetPos(&sp258);
sp258.y = dComIfG_Bgsp().GroundCross(&gnd_chk);
if (sp258.y != -G_CM3D_F_INF) {
f32 x, y;
y = sp258.y - sp264.y;
x = sp258.x - sp264.x;
sVar6 = (s16)cM_atan2s(y, x);
if (sVar6 > 0x3000 || sVar6 < -0x3000) {
sVar6 = 0;
}
}
}
dBgS_LinChk lin_chk;
cXyz work, start, end;
start = actor->current.pos;
start.y += JREG_F(5) + 30.0f;
J3DModel* model = i_this->anm_p->getModel();
work.set(0.0f, 0.0f, 0.0f);
MTXCopy(model->getAnmMtx((int)BREG_S(8) + JNT_NECK02), *calc_mtx);
MtxPosition(&work, &end);
end.y += JREG_F(6) + 30.0f;
lin_chk.Set(&start, &end, actor);
if (dComIfG_Bgsp().LineCross(&lin_chk)) {
work = start - end;
cMtx_YrotS(*calc_mtx, cM_atan2s(work.x, work.z));
work.x = 0.0f;
work.y = 0.0f;
work.z = TREG_F(11) + 50.0f;
MtxPosition(&work, &sp24c);
actor->current.pos += sp24c;
}
i_this->field_0x730.x = sVar7;
i_this->field_0x730.z = sVar6;
}
}
cLib_addCalcAngleS2(&i_this->field_0x72a.x, i_this->field_0x730.x, 1, 0x400);
cLib_addCalcAngleS2(&i_this->field_0x72a.z, i_this->field_0x730.z, 1, 0x400);
if (i_this->set_smoke_flag != 0) {
J3DModel* model = i_this->anm_p->getModel();
work.set(0.0f, 0.0f, 0.0f);
static int foot_idx[2] = {
JNT_FOOTL, JNT_FOOTR,
};
for (int i = 0; i < 2; i++) {
if (i_this->set_smoke_flag == 3 || (i_this->set_smoke_flag == 2 && i == 1) || (i_this->set_smoke_flag == 1 && i == 0)) {
MTXCopy(model->getAnmMtx(foot_idx[i]), *calc_mtx);
MtxPosition(&work, &sp24c);
fopAcM_effSmokeSet2(&i_this->field_0x10e8[i], &i_this->field_0x10f0[i], &sp24c, &actor->shape_angle,
TREG_F(8) + 1.0f, &actor->tevStr);
}
}
i_this->set_smoke_flag = 0;
}
if (i_this->unk_timer_6 != 0) {
i_this->unk_timer_6--;
if (i_this->unk_timer_6 == 0) {
dComIfGp_particle_set(ID_ZI_J_TUBA00, &actor->eyePos, &actor->shape_angle, NULL);
}
}
cXyz sp2a4(1.3f, 1.3f, 1.3f);
setMidnaBindEffect(actor, &i_this->sound, &actor->eyePos, &sp2a4);
}
static void anm_se_set(e_dn_class* i_this) {
int frame = i_this->anm_p->getFrame();
if (i_this->anm_no == ANM_ATTACK_01) {
if (frame == 35) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_TAIL, 0, -1);
} else if (frame == 28) {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_TAIL, -1);
}
} else if (i_this->anm_no == ANM_ATTACK_TAIL_01) {
if (frame == 18) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_KNIFE, 0, -1);
}
} else if (i_this->anm_no == ANM_ATTACK_TAIL_02) {
if (frame == 10) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_KNIFE2_A, 0, -1);
}
if (frame == 24) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_KNIFE2_B, 0, -1);
}
} else if (i_this->anm_no == ANM_WALK) {
if (frame == 3) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_L, 0, -1);
} else if (frame == 18) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_R, 0, -1);
}
} else if (i_this->anm_no == ANM_RUN) {
if (frame == 10) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_L, 0, -1);
} else if (frame == 4) {
i_this->sound.startCreatureSound(Z2SE_EN_DN_FN_RUN_R, 0, -1);
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_BREATH, -1);
}
} else if (i_this->anm_no == ANM_WAIT_03) {
if (frame == 15) {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_SEARCH, -1);
}
} else if (i_this->anm_no == ANM_WAIT_04 && frame == 15) {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_SEARCH2, -1);
}
}
int c_start;
static int daE_DN_Execute(e_dn_class* i_this) {
if (i_this->status != 0) {
return 1;
}
if (c_start == 0 && dComIfGp_event_runCheck() &&
(fopAcM_getTalkEventPartner((fopAc_ac_c*)daPy_getLinkPlayerActorClass()) == daPy_py_c::getMidnaActor() || daPy_getPlayerActorClass()->eventInfo.checkCommandDoor())) {
return 1;
}
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
cXyz work;
cXyz pos;
cXyz downPos;
i_this->frame_counter++;
for (int i = 0; i < 4; i++) {
if (i_this->timer[i] != 0) {
i_this->timer[i]--;
}
}
if (i_this->invulnerability_timer != 0) {
i_this->invulnerability_timer--;
}
if (i_this->unk_timer_2 != 0) {
i_this->unk_timer_2--;
}
if (i_this->unk_timer_5 != 0) {
i_this->unk_timer_5--;
}
if (i_this->unk_timer_1 != 0) {
i_this->unk_timer_1--;
}
i_this->field_0x6f2 = 1;
action(i_this);
if (i_this->unk_timer_5 == 0 && i_this->field_0x5d8 == 0) {
if (i_this->field_0x704) {
cMtx_YrotS(*calc_mtx, i_this->field_0x724.y);
work.x = 0.0f;
work.y = TREG_F(8);
work.z = i_this->field_0x83c;
MtxPosition(&work, &pos);
actor->current.pos += pos;
actor->old.pos += pos;
cLib_addCalc2(&i_this->field_0x83c, i_this->field_0x704 * (2.0f + TREG_F(9)), 1.0f, 5.0f + TREG_F(17));
} else {
cLib_addCalc0(&i_this->field_0x83c, 1.0f, 5.0f + TREG_F(17));
}
i_this->objacch.CrrPos(dComIfG_Bgsp());
if (i_this->field_0x704) {
actor->current.pos -= pos;
actor->old.pos -= pos;
}
if (!i_this->objacch.ChkGroundHit()) {
if (actor->speed.y < -10.0f) {
i_this->unk_counter_2++;
if (i_this->unk_counter_2 == 13) {
i_this->sound.startCreatureVoice(Z2SE_EN_DN_V_DEATH, -1);
}
}
} else {
if (i_this->unk_counter_2 >= 13 + ZREG_S(8)) {
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
actor->speed.y = 0.0f;
i_this->field_0x704 = -1.0;
i_this->field_0x724.x = -0x3000;
i_this->unk_timer_4 = 50 + DREG_S(2);
i_this->invulnerability_timer = 1000;
actor->health = 0;
}
i_this->unk_counter_2 = 0;
}
}
mDoMtx_stack_c::transS(actor->current.pos.x, actor->current.pos.y + i_this->cur_pos_y_offset, actor->current.pos.z);
mDoMtx_stack_c::XrotM((s16) i_this->field_0x72a.x);
mDoMtx_stack_c::ZrotM((s16) i_this->field_0x72a.z);
mDoMtx_stack_c::YrotM((s16) i_this->field_0x724.y);
mDoMtx_stack_c::XrotM((s16) i_this->field_0x724.x);
mDoMtx_stack_c::YrotM(-i_this->field_0x724.y);
mDoMtx_stack_c::YrotM((s16) actor->shape_angle.y);
mDoMtx_stack_c::XrotM((s16) actor->shape_angle.x);
mDoMtx_stack_c::ZrotM(actor->shape_angle.z);
mDoMtx_stack_c::scaleM(l_HIO.model_size * actor->scale.x, l_HIO.model_size * actor->scale.x, l_HIO.model_size * actor->scale.x);
J3DModel* model = i_this->anm_p->getModel();
model->setBaseTRMtx(mDoMtx_stack_c::get());
i_this->anm_p->play(0, 0);
anm_se_set(i_this);
i_this->anm_p->modelCalc();
MTXCopy(model->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
work.set(0.0f, 0.0f, 0.0f);
MtxPosition(&work, &pos);
work.set(YREG_F(1), YREG_F(2), -200.0f + YREG_F(3));
MtxPosition(&work, &downPos);
if (pos.y < downPos.y) {
i_this->left_right_flag = 0;
}
else {
i_this->left_right_flag = 1;
}
cXyz sp50(0.0f, 0.0f, 0.0f);
if (i_this->invulnerability_timer != 0) {
sp50.set(-20000.0f, 200000.0f, 30000.0f);
}
MTXCopy(model->getAnmMtx(JNT_HEAD), *calc_mtx);
work.set(30.0f + KREG_F(12), 30.0f + KREG_F(13), 0.0f + KREG_F(14));
MtxPosition(&work, &actor->eyePos);
i_this->cc_sph[0].SetC(actor->eyePos + sp50);
if (daPy_getPlayerActorClass()->checkHorseRide()) {
i_this->cc_sph[0].SetR(70.0f);
} else {
i_this->cc_sph[0].SetR(50.0f);
}
actor->attention_info.position = actor->eyePos;
actor->attention_info.position.y += 70.0f + BREG_F(7);
MTXCopy(model->getAnmMtx(JNT_BACKBONE01), *calc_mtx);
work.set(-30.0f + BREG_F(11), BREG_F(12), BREG_F(13));
MtxPosition(&work, &pos);
i_this->cc_sph[1].SetC(pos + sp50);
i_this->cc_sph[1].SetR(45.0f);
MTXCopy(model->getAnmMtx(JNT_BACKBONE02), *calc_mtx);
work.set(20.0f + BREG_F(14), BREG_F(15), BREG_F(16));
MtxPosition(&work, &pos);
i_this->cc_sph[2].SetC(pos + sp50);
i_this->cc_sph[2].SetR(45.0f);
for (int i = 0; i <= 2; i++) {
if (i_this->field_0x6f2 != 0) {
i_this->cc_sph[i].OnCoSetBit();
} else {
i_this->cc_sph[i].OffCoSetBit();
}
dComIfG_Ccsp()->Set(&i_this->cc_sph[i]);
}
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_HANDR1), *calc_mtx);
i_this->knife_model->setBaseTRMtx(*calc_mtx);
if (i_this->at_chk_flag != 0 && i_this->tail_at_sph_flag <= 1) {
work.set(BREG_F(7), 60.0f + BREG_F(8), BREG_F(9));
MtxPosition(&work, &pos);
if (i_this->at_sph_center_flag == 0) {
i_this->at_sph_center_flag = 1;
i_this->at_sph.StartCAt(pos);
} else {
i_this->at_sph.MoveCAt(pos);
}
if (i_this->tail_at_sph_flag == 1) {
i_this->at_sph.SetR(l_HIO.model_size * 80.0f);
} else {
i_this->at_sph.SetR(l_HIO.model_size * 50.0f);
}
i_this->at_sph.SetAtAtp(1);
}
if (i_this->skull_model != NULL) {
if (i_this->field_0x694 == 0) {
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_HEAD), mDoMtx_stack_c::get());
mDoMtx_stack_c::multVecZero(&i_this->skull_trans);
} else {
i_this->skull_trans += i_this->field_0x6a4;
if (i_this->field_0x6a4.y <= i_this->objacch.GetGroundH()) {
i_this->skull_model = NULL;
}
i_this->field_0x6a4.y -= 5.0f;
mDoMtx_stack_c::transS(i_this->skull_trans.x, i_this->skull_trans.y, i_this->skull_trans.z);
mDoMtx_stack_c::YrotM(i_this->skull_y_rot);
mDoMtx_stack_c::XrotM(i_this->skull_x_rot);
}
i_this->skull_model->setBaseTRMtx(mDoMtx_stack_c::get());
}
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_ARML2), *calc_mtx);
i_this->tate_model->setBaseTRMtx(*calc_mtx);
if (i_this->at_chk_flag != 0 && i_this->tail_at_sph_flag == 2) {
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_TAIL04), *calc_mtx);
work.set(BREG_F(7), BREG_F(8), BREG_F(9));
MtxPosition(&work, &pos);
if (i_this->at_sph_center_flag == 0) {
i_this->at_sph_center_flag = 1;
i_this->at_sph.StartCAt(pos);
} else {
i_this->at_sph.MoveCAt(pos);
}
i_this->at_sph.SetAtAtp(2);
i_this->at_sph.SetR((70.0f + BREG_F(10)) * l_HIO.model_size);
}
if (i_this->at_chk_flag == 0) {
cXyz sp68(-23500.0f, -20000.0f, -50000.0f);
i_this->at_sph.SetC(actor->current.pos + sp68);
i_this->at_sph_center_flag = 0;
} else {
i_this->at_chk_flag = 0;
}
dComIfG_Ccsp()->Set(&i_this->at_sph);
if (i_this->guard_flag != 0 && i_this->unk_timer_2 == 0) {
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_ARML2), *calc_mtx);
work.set(50.0f + JREG_F(5), JREG_F(6), 30.0f + JREG_F(7));
MtxPosition(&work, &pos);
i_this->tate_sph.SetC(pos);
i_this->tate_sph.SetR((70.0f + JREG_F(8)) * l_HIO.model_size);
if (i_this->tate_sph.ChkTgHit()) {
def_se_set(&i_this->sound, i_this->tate_sph.GetTgHitObj(), 40, 0);
dScnPly_c::setPauseTimer(l_HIO.defense_pause_time);
i_this->unk_timer_2 = 10;
cMtx_YrotS(*calc_mtx, (s16)actor->shape_angle.y);
work.x = KREG_F(0);
work.y = 120.0f + KREG_F(1);
work.z = 50.0f + KREG_F(2);
MtxPosition(&work, &pos);
pos += actor->current.pos;
dComIfGp_setHitMark(2, NULL, &pos, &actor->shape_angle, NULL, 0);
}
} else {
cXyz sp74(-23500.0f, -20000.0f, -30000.0f);
i_this->tate_sph.SetC(actor->current.pos + sp74);
}
i_this->guard_flag = 0;
dComIfG_Ccsp()->Set(&i_this->tate_sph);
if (i_this->death_flag != 0) {
cLib_addCalc2(&i_this->color, -20.0f, 1.0f, 0.4f);
}
fopAc_ac_c* player = dComIfGp_getPlayer(0);
MTXCopy(i_this->anm_p->getModel()->getAnmMtx(JNT_BACKBONE02), mDoMtx_stack_c::get());
mDoMtx_stack_c::multVecZero(&pos);
work = player->current.pos - pos;
s16 tans_val = cM_atan2s(work.x, work.z);
cMtx_YrotS(*calc_mtx, tans_val);
work.x = 0.0;
work.y = NREG_F(18) + 45.0f;
work.z = (BREG_F(12) + 60.0f) - 30.0f;
MtxPosition(&work, &downPos);
downPos += pos;
// The following pokes a hole in the "c-style actors don't inherit" theory....
((fopEn_enemy_c*) i_this)->setDownPos(&downPos);
cXyz sp80(actor->eyePos);
sp80.y += NREG_F(7) + 180.0f;
((fopEn_enemy_c*) i_this)->setHeadLockPos(&sp80);
actor->attention_info.flags |= fopAc_AttnFlag_UNK_0x200000;
if ((actor->current.pos.y - actor->home.pos.y) < -5000.0f) {
fopAcM_delete(actor);
OS_REPORT("DN NARAKU\n");
int swBit = (fopAcM_GetParam(actor) & 0xFF000000) >> 24;
if (swBit != 0xFF) {
dComIfGs_onSwitch(swBit, fopAcM_GetRoomNo(actor));
}
}
// City in the Sky - Dynalfos Room:
// i.e. where you can scare the 2 lizard dudes with the clawshot, make them fall to their deaths,
// then the fan in the middle turns on.
if (strcmp(dComIfGp_getStartStageName(), "D_MN07") == 0 && fopAcM_GetRoomNo(actor) == 8
&& actor->health != 0 && actor->current.pos.y <= -300.0f) {
i_this->action = ACTION_DAMAGE;
i_this->mode = 0;
i_this->field_0x704 = 0.0;
actor->health = 0;
}
return 1;
}
static int daE_DN_IsDelete(e_dn_class* i_this) {
return 1;
}
static int daE_DN_Delete(e_dn_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
fpc_ProcID no = fopAcM_GetID(i_this);
dComIfG_resDelete(&i_this->phase, "E_dn");
if (i_this->hio_init != 0) {
hio_set = 0;
mDoHIO_DELETE_CHILD(l_HIO.no);
}
if (actor->heap != NULL) {
i_this->anm_p->stopZelAnime();
}
return 1;
}
Vec jv_offset = { 0.0f, 0.0f, 0.0f };
dJntColData_c jc_data[12] = {
{0, 1, 2, 40.0f, &jv_offset}, {0, 1, 3, 30.0f, &jv_offset},
{0, 1, 22, 40.0f, &jv_offset}, {0, 1, 11, 15.0f, &jv_offset},
{0, 1, 12, 10.0f, &jv_offset}, {0, 1, 17, 15.0f, &jv_offset},
{0, 1, 18, 10.0f, &jv_offset}, {0, 1, 23, 20.0f, &jv_offset},
{0, 1, 24, 15.0f, &jv_offset}, {0, 1, 27, 20.0f, &jv_offset},
{0, 1, 28, 15.0f, &jv_offset}, {0, 1, 32, 20.0f, &jv_offset},
};
static int useHeapInit(fopAc_ac_c* actor) {
e_dn_class* i_this = (e_dn_class*)actor;
i_this->anm_p = new mDoExt_McaMorfSO((J3DModelData*)dComIfG_getObjectRes("E_dn", 38), NULL, NULL,
(J3DAnmTransform*)dComIfG_getObjectRes("E_dn", 31), 0, 1.0f,
0, -1, &i_this->sound, 0x80000, 0x11000084);
if (i_this->anm_p == NULL || i_this->anm_p->getModel() == NULL) {
return 0;
}
J3DModel* model = i_this->anm_p->getModel();
model->setUserArea((uintptr_t)i_this);
for (u16 i = 0; i < model->getModelData()->getJointNum(); i++) {
if (i != 0) {
model->getModelData()->getJointNodePointer(i)->setCallBack(nodeCallBack);
}
}
if (i_this->jc.init(actor, &jc_data[0], model, 12) == 0) {
return 0;
}
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("E_dn", 39);
JUT_ASSERT(5420, modelData != NULL);
i_this->knife_model = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
if (i_this->knife_model == NULL) {
return 0;
}
modelData = (J3DModelData*)dComIfG_getObjectRes("E_dn", 41);
JUT_ASSERT(5432, modelData != NULL);
i_this->tate_model = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
if (i_this->tate_model == NULL) {
return 0;
}
if (i_this->arg1 == 1) {
modelData = (J3DModelData*)dComIfG_getObjectRes("E_dn", 40);
JUT_ASSERT(5443, modelData != NULL);
i_this->skull_model = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
if (i_this->skull_model == NULL) {
return 0;
}
}
return 1;
}
static cPhs__Step daE_DN_Create(fopAc_ac_c* actor) {
e_dn_class* i_this = (e_dn_class*)actor;
fopAcM_ct(actor, e_dn_class);
cPhs__Step phase = (cPhs__Step)dComIfG_resLoad(&i_this->phase, "E_dn");
if (phase == cPhs_COMPLEATE_e) {
int swBit = (fopAcM_GetParam(actor) & 0xFF000000) >> 24;
if (swBit != 0xFF) {
if (dComIfGs_isSwitch(swBit, fopAcM_GetRoomNo(actor))) {
return cPhs_ERROR_e;
}
}
OS_REPORT("E_dn PARAM %x\n", fopAcM_GetParam(actor));
i_this->arg0 = fopAcM_GetParam(actor);
i_this->arg3 = 1;
i_this->arg1 = (fopAcM_GetParam(actor) & 0xF00) >> 8;
i_this->arg2 = (fopAcM_GetParam(actor) & 0xF000) >> 12;
if ((actor->home.angle.z & 0xFF) == 0 || (actor->home.angle.z & 0xFF) == 0xFF) {
i_this->pl_range = 100000.0f;
} else {
i_this->pl_range = (actor->home.angle.z & 0xFF) * 100.0f;
}
OS_REPORT("E_dn AZ %x\n", actor->home.angle.z);
OS_REPORT("E_dn PR %d\n", (int)i_this->pl_range);
actor->home.angle.z = actor->current.angle.z = actor->shape_angle.z = 0;
u8 param = (fopAcM_GetParam(actor) & 0xFF0000) >> 16;
OS_REPORT("E_dn//////////////E_DN SET 1 !!\n");
if (!fopAcM_entrySolidHeap(actor, useHeapInit, 0x3BF0)) {
OS_REPORT("//////////////E_DN SET NON !!\n");
return cPhs_ERROR_e;
}
if (hio_set == 0) {
i_this->hio_init = 1;
hio_set = 1;
l_HIO.no = mDoHIO_CREATE_CHILD("リザードマン", &l_HIO);
}
fopAcM_OnStatus(actor, fopAcM_STATUS_UNK_0x100);
actor->attention_info.flags = fopAc_AttnFlag_BATTLE_e;
fopAcM_SetMtx(actor, i_this->anm_p->getModel()->getBaseTRMtx());
fopAcM_SetMin(actor, -200.0f, -200.0f, -200.0f);
fopAcM_SetMax(actor, 200.0f, 200.0f, 200.0f);
i_this->objacch.Set(fopAcM_GetPosition_p(actor), fopAcM_GetOldPosition_p(actor), actor, 1,
&i_this->acchcir, fopAcM_GetSpeed_p(actor), NULL, NULL);
i_this->acchcir.SetWall(80.0f, 100.0f);
if (i_this->arg1 == 1) {
actor->field_0x560 = actor->health = 100;
} else {
actor->field_0x560 = actor->health = 100;
}
i_this->stts.Init(200, 0, actor);
static dCcD_SrcSph cc_sph_src = {
{
{0x0, {{0x0, 0x0, 0x0}, {0xD8FBFDFf, 0x3}, 0x75}}, // mObj
{dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt
{dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg
{0x0}, // mGObjCo
}, // mObjInf
{
{{0.0f, 0.0f, 0.0f}, 40.0f} // mSph
} // mSphAttr
};
for (int i = 0; i <= 2; i++) {
i_this->cc_sph[i].Set(cc_sph_src);
i_this->cc_sph[i].SetStts(&i_this->stts);
}
static dCcD_SrcSph at_sph_src = {
{
{0x0, {{AT_TYPE_CSTATUE_SWING, 0x1, 0xD}, {0x0, 0x0}, 0x0}}, // mObj
{dCcD_SE_METAL, 0x0, 0x0, 0x0, 0x0}, // mGObjAt
{dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg
{0x0}, // mGObjCo
}, // mObjInf
{
{{0.0f, 0.0f, 0.0f}, 35.0f} // mSph
} // mSphAttr
};
i_this->at_sph.Set(at_sph_src);
i_this->at_sph.SetStts(&i_this->stts);
static dCcD_SrcSph tate_sph_src = {
{
{0x0, {{0x0, 0x0, 0x0}, {0xD8FBFDFF, 0x3}, 0x0}}, // mObj
{dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt
{dCcD_SE_STONE, 0x5, 0x0, 0x0, 0x3}, // mGObjTg
{0x0}, // mGObjCo
}, // mObjInf
{
{{0.0f, 0.0f, 0.0f}, 100.0f} // mSph
} // mSphAttr
};
i_this->tate_sph.Set(tate_sph_src);
i_this->tate_sph.SetStts(&i_this->stts);
i_this->frame_counter = (int)cM_rndF(65535.0f) & 0xFF00;
if (i_this->arg0 == 0) {
i_this->action = ACTION_STAY;
}
if ((i_this->arg0 == 13 || i_this->arg0 == 14) || (i_this->arg0 == 15 || i_this->arg0 == 16)) {
i_this->status = 1;
i_this->action = ACTION_REG;
fopAcM_OnStatus(actor, fopAcM_STATUS_UNK_0x4000);
i_this->acchcir.SetWall(80.0f, 2.0f);
}
i_this->sound.init(&actor->current.pos, &actor->eyePos, 3, 1);
i_this->sound.setEnemyName("E_dn");
i_this->at_info.mpSound = &i_this->sound;
c_start = 1;
daE_DN_Execute(i_this);
c_start = 0;
}
return phase;
}
e_dn_class::e_dn_class() {}
AUDIO_INSTANCES;
static actor_method_class l_daE_DN_Method = {
(process_method_func)daE_DN_Create,
(process_method_func)daE_DN_Delete,
(process_method_func)daE_DN_Execute,
(process_method_func)daE_DN_IsDelete,
(process_method_func)daE_DN_Draw,
};
actor_process_profile_definition g_profile_E_DN = {
fpcLy_CURRENT_e, // mLayerID
7, // mListID
fpcPi_CURRENT_e, // mListPrio
PROC_E_DN, // mProcName
&g_fpcLf_Method.base, // sub_method
sizeof(e_dn_class), // mSize
0, // mSizeOther
0, // mParameters
&g_fopAc_Method.base, // sub_method
118, // mPriority
&l_daE_DN_Method, // sub_method
0x00040000, // mStatus
fopAc_ENEMY_e, // mActorType
fopAc_CULLBOX_CUSTOM_e, // cullType
};