tp/src/d/actor/d_a_e_fb.cpp

1043 lines
35 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file d_a_e_fb.cpp
*
*/
#include "d/dolzel_rel.h" // IWYU pragma: keep
#include "d/actor/d_a_e_fb.h"
#include "Z2AudioLib/Z2Instances.h"
#include "d/actor/d_a_obj_carry.h"
#include "d/d_s_play.h"
/* 806B64AC-806B6520 0000EC 0074+00 1/1 0/0 0/0 .text __ct__12daE_FB_HIO_cFv */
daE_FB_HIO_c::daE_FB_HIO_c() {
field_0x4 = -1;
model_size = 1.5f;
player_detection_range = 1500.0f;
next_attack_waiting_time = 30;
maximum_rotation_width = 0x300;
minimum_turning_range = 0x10;
rotation_width_stairs = 120;
color_register_1r = 0x87;
color_register_1g = 0x96;
color_register_1b = 0x91;
color_register_1a = 0xB6;
maximum_rotation_width_2 = 120;
}
#if DEBUG
void daE_FB_HIO_c::genMessage(JORMContext* ctext) {
// "Frizzard (large)"
ctext->genLabel("フリザド(大)", 0x80000001, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Model size"
ctext->genSlider("モデルサイズ", &model_size, 0.0f, 10.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Player detection range"
ctext->genSlider("プレイヤー発見距離", &player_detection_range, 0.0f, 10000.0f, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Next attack wait time"
ctext->genSlider("次回攻撃待ち時間", &next_attack_waiting_time, 0, 1000, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Maximum rotation width"
ctext->genSlider("最大回転幅", &maximum_rotation_width, 0, 10000, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Minimum turning range"
ctext->genSlider("最小回転幅", &minimum_turning_range, 0, 10000, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Stage rotation amplitude (speed)"
ctext->genSlider("階段用回転幅(速度)", &rotation_width_stairs, 0, 10000, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Color Regi 1R"
ctext->genSlider("カラレジ1R", &color_register_1r, 0, 0xFF, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Color Regi 1G"
ctext->genSlider("カラレジ1G", &color_register_1g, 0, 0xFF, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Color Regi 1B"
ctext->genSlider("カラレジ1B", &color_register_1b, 0, 0xFF, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Color Regi 1α "
ctext->genSlider("カラレジ1α ", &color_register_1a, 0, 0xFF, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
// "Maximum rotation width"
ctext->genSlider("最大回転幅", &maximum_rotation_width_2, 0, 180, 0, NULL, 0xFFFF, 0xFFFF, 0x200, 24);
}
#endif
namespace {
dCcD_SrcSph cc_fb_src = {
{
{0, {{AT_TYPE_100, 1, 0x1D}, {0x48FBFDFF, 0x43}, 0x75}},
{dCcD_SE_METAL, 0, 0, 2, {0}},
{dCcD_SE_NONE, 2, 0, 0, {0x103}},
{0},
},
{{
{0.0f, 0.0f, 0.0f},
40.0f,
}},
};
dCcD_SrcSph cc_fb_at_src = {
{
{0, {{AT_TYPE_100, 1, 0x1D}, {0, 0}, 0}},
{dCcD_SE_METAL, 0, 0xC, 2, {0}},
{dCcD_SE_NONE, 0, 0, 0, {0x2}},
{0},
},
{{
{0.0f, 0.0f, 0.0f},
40.0f,
}},
};
}
/* 806B6520-806B65C0 000160 00A0+00 1/1 0/0 0/0 .text ctrlJoint__8daE_FB_cFP8J3DJointP8J3DModel */
int daE_FB_c::ctrlJoint(J3DJoint* i_joint, J3DModel* i_model) {
J3DJoint* my_joint = i_joint;
int jnt_no = my_joint->getJntNo();
mDoMtx_stack_c::copy(i_model->getAnmMtx(jnt_no));
switch (jnt_no) {
case 2:
mDoMtx_stack_c::ZrotM(mHeadAngle);
}
#if DEBUG
if (TREG_S(0) && jnt_no == TREG_S(0)) {
mDoMtx_stack_c::XrotM(TREG_S(1));
mDoMtx_stack_c::YrotM(TREG_S(2));
mDoMtx_stack_c::ZrotM(TREG_S(3));
}
#endif
i_model->setAnmMtx(jnt_no, mDoMtx_stack_c::get());
cMtx_copy(mDoMtx_stack_c::get(), J3DSys::mCurrentMtx);
return 1;
}
/* 806B65C0-806B660C 000200 004C+00 1/1 0/0 0/0 .text JointCallBack__8daE_FB_cFP8J3DJointi */
int daE_FB_c::JointCallBack(J3DJoint* i_joint, int param_1) {
if (param_1 == 0) {
J3DModel* model = j3dSys.getModel();
daE_FB_c* freezard_p = (daE_FB_c*) model->getUserArea();
if (freezard_p) {
freezard_p->ctrlJoint(i_joint, model);
}
}
return 1;
}
#if VERSION == VERSION_SHIELD_DEBUG
static f32 dummy_117095() {
// For rodata ordering in the debug version, this must be put here:
return 100.0f;
}
#endif
bool lbl_188_bss_45;
/* 806B91FC-806B9220 000054 0024+00 6/7 0/0 0/0 .bss l_HIO */
static daE_FB_HIO_c l_HIO;
/* 806B660C-806B67C0 00024C 01B4+00 1/1 0/0 0/0 .text draw__8daE_FB_cFv */
int daE_FB_c::draw() {
if (mType == 10 || mType == 11) {
return 1;
}
J3DModel* model = mpMorf->getModel();
g_env_light.settingTevStruct(0, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(model, &tevStr);
J3DMaterial* material = model->getModelData()->getMaterialNodePointer(0);
material->getTevColor(1)->r = l_HIO.color_register_1r;
material->getTevColor(1)->g = l_HIO.color_register_1g;
material->getTevColor(1)->b = l_HIO.color_register_1b;
material->getTevColor(1)->a = l_HIO.color_register_1a;
mpBrkAnm->entry(model->getModelData());
mInvisibleModel.entryDL(NULL);
cXyz my_vec;
my_vec.set(current.pos.x, 10.0f + current.pos.y, current.pos.z);
GXTexObj* tex_obj = dDlst_shadowControl_c::getSimpleTex();
mShadowKey = dComIfGd_setShadow(mShadowKey, 1, model, &my_vec, 1300.0f, 0.0f,
current.pos.y, mObjAcch.GetGroundH(), mObjAcch.m_gnd,
&tevStr, 0, 1.0f, tex_obj);
return 1;
}
/* 806B67C0-806B67E0 000400 0020+00 1/0 0/0 0/0 .text daE_FB_Draw__FP8daE_FB_c */
static int daE_FB_Draw(daE_FB_c* i_this) {
return static_cast<daE_FB_c*>(i_this)->draw();
}
/* 806B67E0-806B688C 000420 00AC+00 3/3 0/0 0/0 .text setBck__8daE_FB_cFiUcff */
void daE_FB_c::setBck(int i_index, u8 i_attr, f32 i_morf, f32 i_rate) {
mpMorf->setAnm((J3DAnmTransform *) dComIfG_getObjectRes("E_FL", i_index), i_attr, i_morf, i_rate, 0.0f, -1.0f);
field_0x670 = i_index;
}
/* 806B688C-806B6898 0004CC 000C+00 5/5 0/0 0/0 .text setActionMode__8daE_FB_cFii */
void daE_FB_c::setActionMode(int i_action, int i_mode) {
mActionMode = i_action;
mMoveMode = i_mode;
}
/* 806B6898-806B6D20 0004D8 0488+00 1/1 0/0 0/0 .text damage_check__8daE_FB_cFv */
void daE_FB_c::damage_check() {
if (mType == 10 || mType == 11) {
return;
}
fopAc_ac_c* tg_hit_ac = NULL;
fopAc_ac_c* player = dComIfGp_getPlayer(0);
mStts.Move();
field_0x560 = health = 200;
if (mSphere.ChkTgHit()) {
mAtInfo.mpCollider = mSphere.GetTgHitObj();
if (mSphere.GetTgHitObj()->ChkAtType(AT_TYPE_IRON_BALL)) {
cCcD_Obj* hit_obj = mSphere.GetTgHitObj();
if (!field_0x68c && mActionMode != 2) {
tg_hit_ac = mSphere.GetTgHitAc();
++field_0x68e;
if (player == tg_hit_ac) {
++field_0x68e;
} else if (((daObjCarry_c*)tg_hit_ac)->checkCannon()) {
field_0x68e = 3;
}
if (field_0x68e > 2) {
health = 0;
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER5, 0x1F, cXyz(0.0f, 1.0f, 0.0f));
fopAcM_OffStatus(this, 0);
attention_info.flags &= ~fopAc_AttnFlag_BATTLE_e;
mSphere.OffAtSetBit();
mSphere.OffTgSetBit();
mSphere2.OffAtSetBit();
mSphere2.OffTgSetBit();
mCreatureSound.startCollisionSE(Z2SE_HIT_HAMMER, 0x20);
mCreatureSound.startCreatureSound(Z2SE_EN_FL_DEATH, 0, -1);
} else {
mCreatureSound.startCollisionSE(Z2SE_HIT_HAMMER, 0x1E);
mCreatureSound.startCreatureSound(Z2SE_EN_FL_DAMAGE, 0, -1);
}
setActionMode(2, 0);
} else {
mCreatureSound.startCollisionSE(dCcD_GObjInf::getHitSeID(((dCcD_GObjInf*) hit_obj)->GetAtSe(), 0), 0x2A);
}
mSphere.ClrTgHit();
}
}
if (mSphere2.ChkTgHit()) {
mAtInfo.mpCollider = mSphere2.GetTgHitObj();
if (mSphere2.GetTgHitObj()->ChkAtType(AT_TYPE_IRON_BALL)) {
cCcD_Obj* hit_obj = mSphere2.GetTgHitObj();
if (!field_0x68c && mActionMode != 2) {
tg_hit_ac = mSphere2.GetTgHitAc();
++field_0x68e;
if (player == tg_hit_ac) {
++field_0x68e;
} else if (((daObjCarry_c*)tg_hit_ac)->checkCannon()) {
field_0x68e = 3;
}
if (field_0x68e > 2) {
health = 0;
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER5, 0x1F, cXyz(0.0f, 1.0f, 0.0f));
fopAcM_OffStatus(this, 0);
attention_info.flags &= ~fopAc_AttnFlag_BATTLE_e;
mSphere.OffAtSetBit();
mSphere.OffTgSetBit();
mSphere2.OffAtSetBit();
mSphere2.OffTgSetBit();
mCreatureSound.startCollisionSE(Z2SE_HIT_HAMMER, 0x20);
mCreatureSound.startCreatureSound(Z2SE_EN_FL_DEATH, 0, -1);
} else {
mCreatureSound.startCollisionSE(Z2SE_HIT_HAMMER, 0x1E);
mCreatureSound.startCreatureSound(Z2SE_EN_FL_DAMAGE, 0, -1);
}
setActionMode(2, 0);
} else {
mCreatureSound.startCollisionSE(dCcD_GObjInf::getHitSeID(((dCcD_GObjInf*) hit_obj)->GetAtSe(), 0), 0x2A);
}
mSphere2.ClrTgHit();
}
}
}
/* 806B6D20-806B6DF4 000960 00D4+00 3/3 0/0 0/0 .text mBgLineCheck__8daE_FB_cFv */
bool daE_FB_c::mBgLineCheck() {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
dBgS_LinChk linchk;
cXyz vec;
vec.set(player->current.pos);
vec.y += 100.0f;
linchk.Set(&attention_info.position, &vec, this);
if (dComIfG_Bgsp().LineCross(&linchk) && !dComIfGp_checkPlayerStatus0(0, 0x02000000)) {
return true;
}
return false;
}
/* 806B6DF4-806B6F40 000A34 014C+00 2/2 0/0 0/0 .text search_check__8daE_FB_cFv */
bool daE_FB_c::search_check() {
bool retval = false;
if (fopAcM_searchPlayerDistance(this) <= l_HIO.player_detection_range) {
if (!field_0x69c) {
mRotation = fopAcM_searchPlayerAngleY(this);
field_0x69c = 0x1E;
field_0x696 = 0;
}
retval = true;
} else if (mActionMode != 1 && !field_0x69c) {
mRotation = home.angle.y;
field_0x69c = 0x1E;
field_0x696 = 0;
}
cLib_addCalcAngleS2(&field_0x696, l_HIO.maximum_rotation_width, 1, l_HIO.minimum_turning_range);
cLib_addCalcAngleS2(&shape_angle.y, mRotation, 1, field_0x696);
if (retval == true && abs(s16(shape_angle.y - mRotation)) > 0x200) {
mCreatureSound.startCreatureSoundLevel(Z2SE_EN_FL_ROTATE, 0, -1);
retval = false;
}
return retval;
}
/* 806B6F40-806B70FC 000B80 01BC+00 1/1 0/0 0/0 .text executeWait__8daE_FB_cFv */
void daE_FB_c::executeWait() {
if (field_0x680) {
--field_0x680;
}
switch (mMoveMode) {
case 0:
field_0x680 = l_HIO.next_attack_waiting_time;
/* fallthrough */
case 2:
setBck(8, 2, 6.0f, 1.0f);
mRotation = home.angle.y;
mMoveMode = 1;
/* fallthrough */
case 1:
if (mType == 1) {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
if (fopAcM_searchPlayerDistanceY(this) > 300.0f) {
break;
}
if (fopAcM_searchPlayerDistanceY(this) < -300.0f) {
break;
}
if (current.pos.y <= 300.0f) {
if (player->current.pos.x > -2800.0f) {
break;
}
} else if (player->current.pos.x < -3600.0f) {
break;
}
setActionMode(1, 0);
} else if (search_check() && !field_0x680) {
if (mType == 0) {
if (mBgLineCheck()) {
break;
}
} else if (mType == 2) {
if (BREG_S(9)) {
OS_REPORT("fopAcM_searchPlayerDistanceY(this) %f\n", fopAcM_searchPlayerDistanceY(this));
}
if (fopAcM_searchPlayerDistanceY(this) > 300.0f) {
break;
}
if (fopAcM_searchPlayerDistanceY(this) < -700.0f + JREG_F(1)) {
break;
}
}
setActionMode(1, 0);
}
break;
}
current.angle.y = shape_angle.y;
}
/* 806B9220-806B9224 000078 0004+00 2/2 0/0 0/0 .bss mFireTimer */
static int mFireTimer;
/* 806B70FC-806B78A0 000D3C 07A4+00 1/1 0/0 0/0 .text executeAttack__8daE_FB_cFv */
void daE_FB_c::executeAttack() {
// NONMATCHING - regalloc purgatory
static u16 a_eff_id[3] = {
dPa_RM(ID_ZI_S_FL_BREATH_A),
dPa_RM(ID_ZI_S_FL_BREATH_B),
dPa_RM(ID_ZI_S_FL_BREATH_C),
};
cXyz sp_0x48;
cXyz child_pos; // dbg sp 0x3C
cXyz sp_0x30(mModelSize, mModelSize, mModelSize);
switch (mMoveMode) {
case 0:
field_0x68f = 0;
mFireTimer = 0;
field_0x690 = 0;
if (mType == 2 && dComIfGp_checkPlayerStatus0(0, 0x02000000)) {
setBck(6, 2, 6.0f, 1.0f);
mMoveMode = 2;
} else if (mType == 1) {
setBck(6, 2, 6.0f, 1.0f);
mMoveMode = 3;
mRotation = home.angle.y - ((l_HIO.maximum_rotation_width_2 >> 1) * 0xB6);
if (BREG_S(6)) {
OS_REPORT("\n\n");
// "First rotation %d\n"
OS_REPORT("最初の回転 %d\n", mRotation);
// "First rotation %x\n"
OS_REPORT("最初の回転 %x\n", mRotation);
OS_REPORT("\n\n");
}
} else {
setBck(5, 0, 6.0f, 1.0f);
mCreatureSound.startCreatureSound(Z2SE_EN_FL_BLIZZARD, 0, -1);
mMoveMode = 1;
}
break;
case 1:
case 3:
if (field_0x670 == 5) {
if (int(mpMorf->getFrame()) == 160) {
mCreatureSound.startCreatureSound(Z2SE_EN_FL_BLIZZARD_END, 0, -1);
}
}
/* fallthrough */
case 2:
if (mMoveMode != 3) {
search_check();
}
if (mType == 0 && mBgLineCheck()) {
field_0x69c = 0;
field_0x680 = l_HIO.next_attack_waiting_time;
setActionMode(0, 0);
break;
}
if ((mpMorf->getFrame() >= 36.0f && mpMorf->getFrame() <= 160.0f) || mMoveMode == 2 || mMoveMode == 3) {
for (int idx = 0; idx < 3; ++idx) {
mKeys[idx + 5] = dComIfGp_particle_set(mKeys[idx + 5], a_eff_id[idx],
&current.pos, &shape_angle, &sp_0x30);
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(mKeys[idx + 5]);
if (emitter != NULL) {
emitter->setGlobalSRTMatrix(mpMorf->getModel()->getAnmMtx(2));
}
}
mCreatureSound.startCreatureVoiceLevel(Z2SE_EN_FL_BREATH, -1);
++field_0x68f;
field_0x68f &= (u8) 1;
if (field_0x68f == 0) {
csXyz sp_0x28;
int child_type = 10;
sp_0x28 = shape_angle;
sp_0x28.x = mHeadAngle + 0x2BC + JREG_S(1);
if (mType == 1) {
if (current.pos.y <= 300.0f) {
sp_0x28.x = mHeadAngle + 2000 + BREG_S(2);
} else {
sp_0x28.x = mHeadAngle + 2000 + BREG_S(3);
}
}
if (dComIfGp_event_runCheck() == FALSE) {
cMtx_YrotS(*calc_mtx, current.angle.y);
cMtx_XrotM(*calc_mtx, sp_0x28.x);
sp_0x48.x = 0.0f;
sp_0x48.y = 250.0f + BREG_F(2);
sp_0x48.z = 200.0f + BREG_F(3);
MtxPosition(&sp_0x48, &child_pos);
child_pos += current.pos;
if (mType == 1) {
child_type = 11;
}
fopAcM_createChild(PROC_E_FB, fopAcM_GetID(this), child_type, &child_pos,
fopAcM_GetRoomNo(this), &sp_0x28, NULL, -1, NULL);
}
}
}
if (mMoveMode == 3) {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
cLib_addCalcAngleS2(&shape_angle.y, mRotation, 1, l_HIO.rotation_width_stairs);
if (current.pos.y <= 300.0f) {
mHeadAngle = f32(NREG_S(1) + 14000 - abs(shape_angle.y)) / (6.0f + NREG_F(1));
if (player->current.pos.x > -2800.0f) {
field_0x69c = 0;
current.angle.y = shape_angle.y;
setActionMode(0, 0);
return;
}
} else {
mHeadAngle = NREG_S(2) - 2500;
mHeadAngle = mHeadAngle - abs(shape_angle.y) * (-0.2f + NREG_F(2));
if (player->current.pos.x < -3600.0f) {
field_0x69c = 0;
current.angle.y = shape_angle.y;
setActionMode(0, 0);
return;
}
}
if (fopAcM_searchPlayerDistanceY(this) > 300.0f
|| fopAcM_searchPlayerDistanceY(this) < -300.0f) {
field_0x69c = 0;
current.angle.y = shape_angle.y;
setActionMode(0, 0);
return;
}
if (BREG_S(9)) {
OS_REPORT("shape_angle.sy %x\n", abs(shape_angle.y));
OS_REPORT("mHeadAngle %x\n\n", mHeadAngle);
}
mCreatureSound.startCreatureSoundLevel(Z2SE_EN_FL_ROTATE, 0, -1);
if (abs(s16(shape_angle.y - mRotation)) < 0x200) {
if (field_0x690 == 0) {
mRotation = home.angle.y + (l_HIO.maximum_rotation_width_2 >> 1) * 0xB6;
} else {
mRotation = home.angle.y - (l_HIO.maximum_rotation_width_2 >> 1) * 0xB6;
}
++field_0x690;
field_0x690 &= (u8) 1;
if (BREG_S(6)) {
OS_REPORT("\n\n");
// "Next rotation %d\n"
OS_REPORT("次回転 %d\n", mRotation);
// "Next rotation %x\n"
OS_REPORT("次回転 %x\n", mRotation);
OS_REPORT("\n\n");
}
}
}
if (mMoveMode == 1 && mpMorf->isStop()) {
field_0x69c = 0;
field_0x680 = l_HIO.next_attack_waiting_time;
setActionMode(0, 0);
} else if (mMoveMode == 2 && dComIfGp_checkPlayerStatus0(0, 0x02000000) == FALSE
&& fopAcM_searchPlayerDistanceY(this) < -900.0f) {
if (NREG_S(6)) {
OS_REPORT("\n\n");
OS_REPORT("fopAcM_searchPlayerDistanceY %f\n", fopAcM_searchPlayerDistanceY(this));
OS_REPORT("\n\n");
}
field_0x69c = 0;
field_0x680 = l_HIO.next_attack_waiting_time;
setActionMode(0, 0);
}
}
current.angle.y = shape_angle.y;
}
/* 806B78A0-806B7B88 0014E0 02E8+00 1/1 0/0 0/0 .text executeDamage__8daE_FB_cFv */
void daE_FB_c::executeDamage() {
static u16 d_eff_id[2] = {
dPa_RM(ID_ZI_S_FL_HIT_A),
dPa_RM(ID_ZI_S_FL_HIT_B)
};
cXyz sp_0x34(mModelSize, mModelSize, mModelSize);
int keys[2];
switch (mMoveMode) {
case 0:
for (int idx = 0; idx < 2; ++idx) {
keys[idx] = dComIfGp_particle_set(keys[idx], d_eff_id[idx],
&current.pos, &shape_angle, &sp_0x34);
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(keys[idx]);
if (emitter != NULL) {
emitter->setGlobalSRTMatrix(mpMorf->getModel()->getAnmMtx(1));
}
}
if (field_0x68e <= 2) {
setBck(7, 0, 3.0f, 1.0f);
mMoveMode = 1;
} else {
csXyz mini_angle;
cXyz mini_pos;
// Spawn the mini freezard babies!
int num_babies = 4;
for (int idx = 0; idx < num_babies; ++idx) {
mini_angle = shape_angle;
mini_angle.y = fopAcM_searchPlayerAngleY(this) + 0x8000;
mini_angle.y += s16(cM_rndFX(4000.0f));
mini_pos = current.pos;
mini_pos.x += cM_rndF(50.0f);
mini_pos.y += cM_rndF(100.0f) + 100.0f;
mini_pos.z += cM_rndF(50.0f);
fopAcM_create(PROC_E_FZ, 1, &mini_pos, fopAcM_GetRoomNo(this), &mini_angle, NULL, -1);
}
dead_eff_set();
if (swBit0 != 0xFF) {
fopAcM_onSwitch(this, swBit0);
}
fopAcM_delete(this);
}
break;
case 1:
if (mpMorf->isStop()) {
setActionMode(0, 0);
mMoveMode = 2;
field_0x680 = 0;
}
break;
}
current.angle.y = shape_angle.y;
}
/* 806B9224-806B9228 00007C 0004+00 2/3 0/0 0/0 .bss None */
static u8 lbl_188_bss_7C;
/* 806B7B88-806B7DDC 0017C8 0254+00 1/1 0/0 0/0 .text executeBullet__8daE_FB_cFv */
void daE_FB_c::executeBullet() {
cXyz sp_0x20;
cXyz sp_0x14;
switch (mMoveMode) {
case 0:
field_0x69c = mFireTimer;
mFireTimer += 3;
if (mFireTimer > 36 + JREG_S(0)) {
mFireTimer = 36 + JREG_S(0);
}
++mMoveMode;
/* fallthrough */
case 1:
speedF = 35.0f + JREG_F(2);
if (parentActorID) {
fopAc_ac_c* actor_p = fopAcM_SearchByID(fopAcM_GetLinkId(this));
if (actor_p != NULL) {
s16 ang_diff = actor_p->shape_angle.y - home.angle.y;
current.angle.y -= s16(ang_diff * (0.1f + JREG_F(3)));
}
}
cMtx_YrotS(*calc_mtx, current.angle.y);
cMtx_XrotM(*calc_mtx, current.angle.x);
sp_0x20.x = 0.0f;
sp_0x20.y = 0.0f;
sp_0x20.z = speedF;
MtxPosition(&sp_0x20, &sp_0x14);
speed.y = sp_0x14.y;
break;
}
cXyz sp_0x8(speedF * cM_ssin(current.angle.y), 0.0f, speedF * cM_scos(current.angle.y));
mAtSph.SetC(current.pos);
mAtSph.SetR(40.0f + BREG_F(1));
mAtSph.SetAtVec(sp_0x8);
dComIfG_Ccsp()->Set(&mAtSph);
if (mAtSph.ChkAtHit()) {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
fopAc_ac_c* at_hit_ac = mAtSph.GetAtHitAc();
if (player == at_hit_ac && lbl_188_bss_7C < 2) {
++lbl_188_bss_7C;
}
mAtSph.ClrAtHit();
}
if (mObjAcch.ChkGroundHit() || field_0x69c == 0) {
fopAcM_delete(this);
}
}
/* 806B7DDC-806B80A4 001A1C 02C8+00 1/1 0/0 0/0 .text action__8daE_FB_cFv */
void daE_FB_c::action() {
mModelSize = l_HIO.model_size;
if (mType == 1) {
mModelSize = 1.3f;
}
if (mType == 2 && lbl_188_bss_7C == 2) {
lbl_188_bss_7C = 3;
if (swBit1 != 0xFF) {
fopAcM_onSwitch(this, swBit1);
}
}
if (mType == 0 || mType == 2) {
fopAc_ac_c* player = dComIfGp_getPlayer(0);
cXyz sp_0x14;
cXyz sp_0x8;
mDoMtx_stack_c::copy(mpMorf->getModel()->getAnmMtx(2));
mDoMtx_stack_c::multVecZero(&sp_0x14);
sp_0x8.set(player->current.pos);
sp_0x8.y += 200.0f;
sp_0x14 -= sp_0x8;
s16 var_r29 = sp_0x14.atan2sY_XZ() * -1.0f;
if (var_r29 < 0) {
var_r29 = 0;
} else if (var_r29 > 3400) {
var_r29 = 3400;
}
cLib_addCalcAngleS2(&mHeadAngle, s16(var_r29), 2 + NREG_S(4), 0x200 + NREG_S(5));
}
if (!mBgLineCheck() || mType == 1) {
fopAcM_OnStatus(this, 0);
attention_info.flags |= fopAc_AttnFlag_BATTLE_e;
} else {
fopAcM_OffStatus(this, 0);
attention_info.flags &= ~fopAc_AttnFlag_BATTLE_e;
}
int var_r28 = 0;
damage_check();
switch (mActionMode) {
case 0:
executeWait();
break;
case 1:
executeAttack();
var_r28 = 1;
break;
case 2:
executeDamage();
break;
case 3:
executeBullet();
break;
}
if (mType == 10 || mType == 11) {
fopAcM_posMoveF(this, mStts.GetCCMoveP());
return;
}
mCreatureSound.setLinkSearch(var_r28);
mpBrkAnm->setFrame(field_0x68e);
mpMorf->play(0, dComIfGp_getReverb(fopAcM_GetRoomNo(this)));
}
/* 806B80A4-806B811C 001CE4 0078+00 1/1 0/0 0/0 .text mtx_set__8daE_FB_cFv */
void daE_FB_c::mtx_set() {
mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z);
mDoMtx_stack_c::ZXYrotM(shape_angle);
mDoMtx_stack_c::scaleM(mModelSize, mModelSize, mModelSize);
J3DModel* model = mpMorf->getModel();
model->setBaseTRMtx(mDoMtx_stack_c::get());
mpMorf->modelCalc();
}
/* 806B811C-806B82B4 001D5C 0198+00 1/1 0/0 0/0 .text cc_set__8daE_FB_cFv */
void daE_FB_c::cc_set() {
cXyz sp8;
mDoMtx_stack_c::copy(mpMorf->getModel()->getAnmMtx(2));
mDoMtx_stack_c::transS(mDoMtx_stack_c::get()[0][3],
mDoMtx_stack_c::get()[1][3],
mDoMtx_stack_c::get()[2][3]);
mDoMtx_stack_c::multVecZero(&attention_info.position);
attention_info.position.y += 100.0f;
mDoMtx_stack_c::copy(mpMorf->getModel()->getAnmMtx(2));
mDoMtx_stack_c::transM(-20.0f, 30.0f, 0.0f);
mDoMtx_stack_c::multVecZero(&sp8);
mSphere.SetC(sp8);
mSphere.SetR(150.0f);
dComIfG_Ccsp()->Set(&mSphere);
mDoMtx_stack_c::copy(mpMorf->getModel()->getAnmMtx(1));
mDoMtx_stack_c::transM(-40.0f, 30.0f, -20.0f);
mDoMtx_stack_c::multVecZero(&sp8);
mSphere2.SetC(sp8);
mSphere2.SetR(170.0f);
dComIfG_Ccsp()->Set(&mSphere2);
eyePos = sp8;
}
/* 806B82B4-806B83F0 001EF4 013C+00 1/1 0/0 0/0 .text normal_eff_set__8daE_FB_cFv */
void daE_FB_c::normal_eff_set() {
static u16 n_eff_id[5] = {
dPa_RM(ID_ZI_S_FL_REIKI_A),
dPa_RM(ID_ZI_S_FL_REIKI_B),
dPa_RM(ID_ZI_S_FL_REIKI_C),
dPa_RM(ID_ZI_S_FL_REIKI_D),
dPa_RM(ID_ZI_S_FL_REIKI_E),
};
static int n_joint_id[5] = {0, 0, 1, 2, 0};
cXyz sp_0x14(mModelSize, mModelSize, mModelSize);
cXyz sp8;
for (int idx = 0; idx < 5; ++idx) {
sp8.set(current.pos);
if (n_joint_id[idx]) {
mDoMtx_stack_c::copy(mpMorf->getModel()->getAnmMtx(n_joint_id[idx]));
mDoMtx_stack_c::multVecZero(&sp8);
}
mKeys[idx] = dComIfGp_particle_set(mKeys[idx], n_eff_id[idx],
&sp8, &shape_angle, &sp_0x14);
}
}
/* 806B83F0-806B8518 002030 0128+00 1/1 0/0 0/0 .text dead_eff_set__8daE_FB_cFv */
void daE_FB_c::dead_eff_set() {
static u16 d_eff_id[5] = {
dPa_RM(ID_ZI_S_FL_DEAD_A),
dPa_RM(ID_ZI_S_FL_DEAD_B),
dPa_RM(ID_ZI_S_FL_DEAD_C),
dPa_RM(ID_ZI_S_FL_DEAD_D),
dPa_RM(ID_ZI_S_FL_DEAD_E),
};
static int d_joint_id[5] = {2, 1, 2, 2, 1};
cXyz sp_0x14(mModelSize, mModelSize, mModelSize);
cXyz sp8;
int keys[5];
for (int idx = 0; idx < 5; ++idx) {
keys[idx] = dComIfGp_particle_set(keys[idx], d_eff_id[idx],
&current.pos, &shape_angle, &sp_0x14);
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(keys[idx]);
if (emitter != NULL) {
emitter->setGlobalSRTMatrix(mpMorf->getModel()->getAnmMtx(d_joint_id[idx]));
}
}
}
#if VERSION == VERSION_SHIELD_DEBUG
static char* dummy_117771() {
return "Delete -> E_FB(id=%d)\n";
}
#endif
/* 806B8518-806B85A0 002158 0088+00 1/1 0/0 0/0 .text execute__8daE_FB_cFv */
int daE_FB_c::execute() {
if (field_0x69c != 0) {
--field_0x69c;
}
if (field_0x68c != 0) {
--field_0x68c;
}
action();
if (mType != 10 && mType != 11) {
mtx_set();
cc_set();
normal_eff_set();
}
return 1;
}
/* 806B85A0-806B85C0 0021E0 0020+00 2/1 0/0 0/0 .text daE_FB_Execute__FP8daE_FB_c */
static int daE_FB_Execute(daE_FB_c* i_this) {
return i_this->execute();
}
/* 806B85C0-806B85C8 002200 0008+00 1/0 0/0 0/0 .text daE_FB_IsDelete__FP8daE_FB_c */
static int daE_FB_IsDelete(daE_FB_c*) {
return 1;
}
/* 806B85C8-806B8658 002208 0090+00 1/1 0/0 0/0 .text _delete__8daE_FB_cFv */
int daE_FB_c::_delete() {
dComIfG_resDelete(&mPhaseReq, "E_FL");
if (mType == 10 || mType == 11) {
return 1;
}
if (mHIOInit) {
lbl_188_bss_7C = 0;
// TODO: dbg HIO stuff.
}
if (heap != NULL) {
mCreatureSound.deleteObject();
}
return 1;
}
/* 806B8658-806B8678 002298 0020+00 1/0 0/0 0/0 .text daE_FB_Delete__FP8daE_FB_c */
static int daE_FB_Delete(daE_FB_c* i_this) {
int id = fopAcM_GetID(i_this);
return static_cast<daE_FB_c*>(i_this)->_delete();
}
/* 806B8678-806B8878 0022B8 0200+00 1/1 0/0 0/0 .text CreateHeap__8daE_FB_cFv */
int daE_FB_c::CreateHeap() {
J3DModelData* modelData = (J3DModelData*) dComIfG_getObjectRes("E_FL", 0xB);
JUT_ASSERT(1516, modelData != NULL);
mpMorf = new mDoExt_McaMorfSO(modelData, NULL, NULL,
(J3DAnmTransform*)dComIfG_getObjectRes("E_FL", 0x8),
0, 1.0f, 0, -1, &mCreatureSound, 0, 0x31000084);
if (mpMorf == NULL || mpMorf->getModel() == NULL) {
return 0;
}
if (mInvisibleModel.create(mpMorf->getModel(), 1) == FALSE) {
return 0;
}
model = mpMorf->getModel();
model->setUserArea((uintptr_t)this);
for (u16 idx = 0; idx < model->getModelData()->getJointNum(); ++idx) {
if (idx != 0) {
model->getModelData()->getJointNodePointer(idx)->setCallBack(&daE_FB_c::JointCallBack);
}
}
mpBrkAnm = new mDoExt_brkAnm();
if (mpBrkAnm == NULL) {
return 0;
}
if (mpBrkAnm->init(mpMorf->getModel()->getModelData(), (J3DAnmTevRegKey*) dComIfG_getObjectRes("E_FL", 0xE),
1, 2, 1.0f, 0, -1) == FALSE) {
return 0;
}
return 1;
}
/* 806B88C0-806B88E0 002500 0020+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */
static int useHeapInit(fopAc_ac_c* i_this) {
daE_FB_c* a_this = static_cast<daE_FB_c*>(i_this);
return a_this->CreateHeap();
}
/* 806B88E0-806B8C1C 002520 033C+00 1/1 0/0 0/0 .text create__8daE_FB_cFv */
cPhs__Step daE_FB_c::create() {
fopAcM_ct(this, daE_FB_c);
mType = fopAcM_GetParam(this);
swBit0 = (fopAcM_GetParam(this) & 0xFF00) >> 8;
swBit1 = (fopAcM_GetParam(this) & 0xFF0000) >> 16;
if (mType == 0xFF) {
mType = 0;
}
cPhs__Step phase = (cPhs__Step) dComIfG_resLoad(&mPhaseReq, "E_FL");
if (phase == cPhs_COMPLEATE_e) {
if (mType == 10 || mType == 11) {
fopAcM_OffStatus(this, 0);
attention_info.flags &= ~fopAc_AttnFlag_BATTLE_e;
attention_info.distances[fopAc_attn_BATTLE_e] = 0;
fopAcM_SetGroup(this, 0);
mStts.Init(0xFF, 0, this);
mAtSph.Set(cc_fb_src);
mAtSph.SetStts(&mStts);
setActionMode(3, 0);
} else {
if (swBit0 != 0xFF && fopAcM_isSwitch(this, swBit0)) {
return cPhs_ERROR_e;
}
if (!fopAcM_entrySolidHeap(this, useHeapInit, 0x2830)) {
return cPhs_ERROR_e;
}
if (lbl_188_bss_45 == false) {
lbl_188_bss_45 = true;
mHIOInit = 1;
l_HIO.field_0x4 = -1;
}
attention_info.flags = fopAc_AttnFlag_BATTLE_e;
attention_info.distances[fopAc_attn_BATTLE_e] = 0x45;
if (mType == 1) {
// Pretty sure these are the caged freezards
// in Snowpeak Ruins - Spiral Room.
attention_info.distances[fopAc_attn_BATTLE_e] = 0x1D;
}
fopAcM_SetMtx(this, mpMorf->getModel()->getBaseTRMtx());
fopAcM_SetMin(this, -200.0f, -200.0f, -200.0f);
fopAcM_SetMax(this, 200.0f, 200.0f, 200.0f);
mObjAcch.Set(fopAcM_GetPosition_p(this), fopAcM_GetOldPosition_p(this), this, 1, &mAcchCir,
fopAcM_GetSpeed_p(this), NULL, NULL);
onWolfNoLock();
mAcchCir.SetWall(40.0f, 80.0f);
mObjAcch.CrrPos(dComIfG_Bgsp());
mStts.Init(0xFA, 0, this);
field_0x560 = health = 200;
lbl_188_bss_7C = 0;
mSphere.Set(cc_fb_src);
mSphere.SetStts(&mStts);
mSphere2.Set(cc_fb_src);
mSphere2.SetStts(&mStts);
mAtSph.Set(cc_fb_at_src);
mAtSph.SetStts(&mStts);
mCreatureSound.init(&current.pos, &eyePos, 3, 1);
mCreatureSound.setEnemyName("E_fb");
mAtInfo.mpSound = &mCreatureSound;
mAtInfo.mPowerType = 6;
#if VERSION != VERSION_SHIELD_DEBUG
attention_info.position.x = current.pos.x;
attention_info.position.y = current.pos.y;
attention_info.position.z = current.pos.z;
#endif
setActionMode(0, 0);
}
daE_FB_Execute(this);
}
return phase;
}
/* 806B8C1C-806B8DC4 00285C 01A8+00 1/1 0/0 0/0 .text __ct__8daE_FB_cFv */
daE_FB_c::daE_FB_c() {
// Empty function.
}
/* 806B8EC4-806B8EE4 002B04 0020+00 1/0 0/0 0/0 .text daE_FB_Create__FP8daE_FB_c */
static int daE_FB_Create(daE_FB_c* i_this) {
return i_this->create();
}
/* 806B9100-806B9120 -00001 0020+00 1/0 0/0 0/0 .data l_daE_FB_Method */
static actor_method_class l_daE_FB_Method = {
(process_method_func)daE_FB_Create,
(process_method_func)daE_FB_Delete,
(process_method_func)daE_FB_Execute,
(process_method_func)daE_FB_IsDelete,
(process_method_func)daE_FB_Draw,
};
/* 806B9120-806B9150 -00001 0030+00 0/0 0/0 1/0 .data g_profile_E_FB */
extern actor_process_profile_definition g_profile_E_FB = {
fpcLy_CURRENT_e, // mLayerID
7, // mListID
fpcPi_CURRENT_e, // mListPrio
PROC_E_FB, // mProcName
&g_fpcLf_Method.base, // sub_method
sizeof(daE_FB_c), // mSize
0, // mSizeOther
0, // mParameters
&g_fopAc_Method.base, // sub_method
176, // mPriority
&l_daE_FB_Method, // sub_method
0x00040100, // mStatus
fopAc_ENEMY_e, // mActorType
fopAc_CULLBOX_CUSTOM_e, // cullType
};
AUDIO_INSTANCES;