Files
tww/src/d/actor/d_a_am.cpp
T
LagoLunatic 25e69da75e d_cc_uty OK
2024-01-20 19:27:19 -05:00

1418 lines
53 KiB
C++

//
// Generated by dtk
// Translation Unit: d_a_am.cpp
//
#include "d/actor/d_a_am.h"
#include "f_op/f_op_actor_mng.h"
#include "JSystem/J3DGraphAnimator/J3DNode.h"
#include "SSystem/SComponent/c_xyz.h"
#include "d/d_procname.h"
#include "d/d_cc_d.h"
#include "d/d_bg_s_acch.h"
#include "d/d_bg_s_lin_chk.h"
#include "d/d_particle.h"
#include "d/d_s_play.h"
#include "d/d_com_inf_game.h"
#include "d/d_item_data.h"
#include "c/c_damagereaction.h"
#include "m_Do/m_Do_mtx.h"
#include "d/d_snap.h"
#include "d/actor/d_a_player.h"
#include "d/d_jnt_hit.h"
#include "d/d_cc_uty.h"
#include "d/actor/d_a_bomb.h"
#include "d/actor/d_a_bomb2.h"
// Needed for the .data section to match.
static f32 dummy1[3] = {1.0f, 1.0f, 1.0f};
static f32 dummy2[3] = {1.0f, 1.0f, 1.0f};
static u8 dummy3[4] = {0x02, 0x00, 0x02, 0x01};
static f64 dummy4[2] = {3.0, 0.5};
enum Action {
ACTION_DOUSA = 0x0,
ACTION_MODORU_MOVE = 0x1,
ACTION_HANDOU_MOVE = 0x2,
ACTION_ITAI_MOVE = 0x3,
};
enum AM_RES_FILE_ID { // IDs and indexes are synced
/* BAS */
AM_BAS_BOM_NOMI=0x5,
AM_BAS_BOM_NOMI2=0x6,
AM_BAS_CLOSE=0x7,
AM_BAS_CLOSE_LOOP=0x8,
AM_BAS_DAMAGE=0x9,
AM_BAS_DAMAGE_END=0xA,
AM_BAS_DAMAGE_LOOP=0xB,
AM_BAS_DEAD=0xC,
AM_BAS_OKIRU=0xD,
AM_BAS_OPEN=0xE,
AM_BAS_OPEN_LOOP=0xF,
AM_BAS_SLEEP=0x10,
AM_BAS_SLEEP_LOOP=0x11,
/* BCK */
AM_BCK_BOM_NOMI=0x14,
AM_BCK_CLOSE=0x15,
AM_BCK_CLOSE_LOOP=0x16,
AM_BCK_DAMAGE=0x17,
AM_BCK_DAMAGE_END=0x18,
AM_BCK_DAMAGE_LOOP=0x19,
AM_BCK_DEAD=0x1A,
AM_BCK_OKIRU=0x1B,
AM_BCK_OPEN=0x1C,
AM_BCK_OPEN_LOOP=0x1D,
AM_BCK_SLEEP=0x1E,
AM_BCK_SLEEP_LOOP=0x1F,
/* BDL */
AM_BDL_AM=0x22,
};
/* 00000078-0000021C .text nodeCallBack__FP7J3DNodei */
static BOOL nodeCallBack(J3DNode* node, int param_1) {
if (!param_1) {
J3DJoint* joint = (J3DJoint*)node;
s32 jntNo = joint->getJntNo();
J3DModel* model = j3dSys.getModel();
am_class* i_this = (am_class*)model->getUserArea();
if (i_this) {
if (jntNo >= 1 && jntNo <= 4) {
cMtx_copy(model->getAnmMtx(jntNo), *calc_mtx);
}
cXyz offset;
switch (jntNo) {
case 1: // kosi (waist)
offset.x = 0.0f;
offset.y = 240.0f;
offset.z = 60.0f;
MtxPosition(&offset, &i_this->mEyeballPos);
offset.x = 0.0f;
offset.y = 150.0f;
offset.z = 70.0f;
MtxPosition(&offset, &i_this->mMouthPos);
offset.x = 0.0f;
offset.y = 0.0f;
offset.z = 0.0f;
MtxPosition(&offset, &i_this->mWaistPos);
break;
case 2: // ago (jaw)
offset.x = 0.0f;
offset.y = 0.0f;
offset.z = 0.0f;
MtxPosition(&offset, &i_this->mJawPos);
break;
case 4: // eye
cMtx_YrotM(*calc_mtx, i_this->mEyeRot.y);
cMtx_XrotM(*calc_mtx, i_this->mEyeRot.x);
}
if (jntNo >= 1 && jntNo <= 4) {
model->setAnmMtx(jntNo, *calc_mtx);
cMtx_copy(*calc_mtx, J3DSys::mCurrentMtx);
}
}
}
return TRUE;
}
/* 0000021C-000002E4 .text draw_SUB__FP8am_class */
static void draw_SUB(am_class* i_this) {
J3DModel* model = i_this->mpMorf->getModel();
model->setBaseScale(i_this->mScale);
mDoMtx_stack_c::transS(i_this->current.pos);
cMtx_YrotM(mDoMtx_stack_c::get(), i_this->shape_angle.y);
cMtx_XrotM(mDoMtx_stack_c::get(), i_this->shape_angle.x);
cMtx_ZrotM(mDoMtx_stack_c::get(), i_this->shape_angle.z);
model->setBaseTRMtx(mDoMtx_stack_c::get());
i_this->mpMorf->calc();
g_env_light.settingTevStruct(TEV_TYPE_ACTOR, &i_this->current.pos, &i_this->mTevStr);
}
/* 000002E4-00000378 .text daAM_Draw__FP8am_class */
static BOOL daAM_Draw(am_class* i_this) {
g_env_light.setLightTevColorType(i_this->mpMorf->getModel(), &i_this->mTevStr);
dSnap_RegistFig(DSNAP_TYPE_AM, i_this, 1.0f, 1.0f, 1.0f);
i_this->mpMorf->entryDL();
dComIfGd_setSimpleShadow2(
&i_this->current.pos, i_this->mAcch.GetGroundH(), 90.0f, i_this->mAcch.m_gnd,
0, 1.0f, dDlst_shadowControl_c::getSimpleTex()
);
return TRUE;
}
/* 00000378-000004A4 .text anm_init__FP8am_classifUcfi */
static void anm_init(am_class* i_this, int bckFileIdx, f32 morf, u8 loopMode, f32 speed, int soundFileIdx) {
i_this->mCurrBckIdx = bckFileIdx;
if (soundFileIdx >= 0) {
void* soundAnm = dComIfG_getObjectRes("AM", soundFileIdx);
J3DAnmTransform* bckAnm = (J3DAnmTransform*)dComIfG_getObjectRes("AM", bckFileIdx);
i_this->mpMorf->setAnm(bckAnm, loopMode, morf, speed, 0.0f, -1.0f, soundAnm);
} else {
J3DAnmTransform* bckAnm = (J3DAnmTransform*)dComIfG_getObjectRes("AM", bckFileIdx);
i_this->mpMorf->setAnm(bckAnm, loopMode, morf, speed, 0.0f, -1.0f, NULL);
}
}
/* 000004A4-00000784 .text body_atari_check__FP8am_class */
static void body_atari_check(am_class* i_this) {
daPy_py_c* player = daPy_getPlayerActorClass();
#if VERSION == VERSION_JPN
if (i_this->mStartsInactive == 1 && i_this->mSwitch != 0xFF && !dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
return;
}
#endif
i_this->mStts.Move();
if (i_this->mBodyCyl.ChkTgHit() || i_this->mNeedleCyl.ChkTgHit()) {
if (i_this->mbIsBodyBeingHit) {
return;
}
cCcD_Obj* hitObj;
if (i_this->mBodyCyl.ChkTgHit()) {
hitObj = i_this->mBodyCyl.GetTgHitObj();
} else {
hitObj = i_this->mNeedleCyl.GetTgHitObj();
}
if (!hitObj) {
return;
}
i_this->mbIsBodyBeingHit = true;
switch (hitObj->GetAtType()) {
case AT_TYPE_SWORD:
case AT_TYPE_MACHETE:
case AT_TYPE_UNK800:
case AT_TYPE_DARKNUT_SWORD:
case AT_TYPE_MOBLIN_SPEAR:
fopAcM_seStart(i_this, JA_SE_LK_SW_HIT_S, 0x42);
break;
case AT_TYPE_BOOMERANG:
case AT_TYPE_BOKO_STICK:
case AT_TYPE_UNK2000:
case AT_TYPE_STALFOS_MACE:
fopAcM_seStart(i_this, JA_SE_LK_W_WEP_HIT, 0x42);
break;
case AT_TYPE_SKULL_HAMMER:
fopAcM_seStart(i_this, JA_SE_LK_HAMMER_HIT, 0x42);
#if VERSION != VERSION_JPN
if (i_this->mStartsInactive == 1 && i_this->mSwitch != 0xFF && !dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
return;
}
#endif
if (i_this->mAction == ACTION_HANDOU_MOVE) {
return;
}
if (i_this->mAction == ACTION_ITAI_MOVE) {
return;
}
i_this->mAction = ACTION_HANDOU_MOVE;
i_this->mState = 0x1E;
i_this->mHugeKnockback = 0;
if (player->getCutType() == 0x11) {
// If the player hits the Armos Knight with the Skull Hammer's side swing, knock it back much farther than normal.
i_this->mHugeKnockback = 1;
}
break;
default:
fopAcM_seStart(i_this, JA_SE_LK_MS_WEP_HIT, 0x42);
break;
}
} else {
i_this->mbIsBodyBeingHit = false;
}
}
/* 00000784-00000D14 .text medama_atari_check__FP8am_class */
static BOOL medama_atari_check(am_class* i_this) {
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
cCcD_Obj* hitObj = i_this->mEyeSph.GetTgHitObj();
bool ret = false;
if (i_this->mStartsInactive == 1 && i_this->mSwitch != 0xFF && !dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
return ret;
}
i_this->mStts.Move();
if (!i_this->mEyeSph.ChkTgHit()) {
return ret;
}
if (!hitObj) {
return ret;
}
CcAtInfo atInfo;
atInfo.pParticlePos = NULL;
cXyz hitPos = *i_this->mEyeSph.GetTgHitPosP();
switch (hitObj->GetAtType()) {
case AT_TYPE_GRAPPLING_HOOK:
if (i_this->mCurrBckIdx != AM_BCK_SLEEP && i_this->mCurrBckIdx != AM_BCK_SLEEP_LOOP) {
if (i_this->mStealItemLeft > 0) {
i_this->mMaxHealth = 10;
i_this->mHealth = 10;
atInfo.mpObj = i_this->mEyeSph.GetTgHitObj();
atInfo.pParticlePos = NULL;
cc_at_check(i_this, &atInfo);
i_this->mMaxHealth = 10;
i_this->mHealth = 10;
dComIfGp_particle_set(dPa_name::ID_COMMON_STARS_BLOW, &i_this->mAttentionInfo.mPosition);
} else {
dComIfGp_particle_set(dPa_name::ID_COMMON_PURPLE_HIT, &hitPos);
}
fopAcM_seStart(i_this, JA_SE_LK_MS_WEP_HIT, 0x42);
}
break;
case AT_TYPE_SWORD:
case AT_TYPE_MACHETE:
case AT_TYPE_UNK800:
case AT_TYPE_DARKNUT_SWORD:
case AT_TYPE_MOBLIN_SPEAR:
fopAcM_seStart(i_this, JA_SE_LK_SW_HIT_S, 0x42);
break;
case AT_TYPE_BOOMERANG:
case AT_TYPE_BOKO_STICK:
case AT_TYPE_UNK2000:
case AT_TYPE_STALFOS_MACE:
fopAcM_seStart(i_this, JA_SE_LK_W_WEP_HIT, 0x42);
break;
case AT_TYPE_LIGHT_ARROW:
ret = true;
i_this->mEnemyIce.mLightShrinkTimer = 1;
i_this->mEnemyIce.mParticleScale = 1.0f;
i_this->mEnemyIce.mYOffset = 80.0f;
i_this->mAttentionInfo.mFlags = 0;
break;
case AT_TYPE_NORMAL_ARROW:
case AT_TYPE_FIRE_ARROW:
case AT_TYPE_ICE_ARROW:
// Using the fopAcM_seStart inline multiple times in a single case makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_LK_MS_WEP_HIT, 0x42);
mDoAud_seStart(JA_SE_LK_MS_WEP_HIT, &i_this->mEyePos, 0x42, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
ret = true;
if (i_this->mCurrBckIdx == AM_BCK_SLEEP || i_this->mCurrBckIdx == AM_BCK_SLEEP_LOOP) {
anm_init(i_this, AM_BCK_OKIRU, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
i_this->mAttentionInfo.mFlags = fopAc_Attn_LOCKON_ENEMY_e;
i_this->mNeedleCyl.OnAtSPrmBit(AT_SPRM_SET);
i_this->mNeedleCyl.OnAtHitBit();
i_this->mAction = ACTION_DOUSA;
i_this->mState = 2;
} else {
dComIfGp_particle_set(0x10, &i_this->mEyeballPos, &player->shape_angle);
// fopAcM_seStart(i_this, JA_SE_CM_AM_EYE_DAMAGE, 0);
mDoAud_seStart(JA_SE_CM_AM_EYE_DAMAGE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_EYE_DAMAGE, 0x42);
i_this->mAction = ACTION_ITAI_MOVE;
i_this->mState = 0x28;
}
break;
default:
dComIfGp_particle_set(dPa_name::ID_COMMON_PURPLE_HIT, &hitPos);
fopAcM_seStart(i_this, JA_SE_LK_MS_WEP_HIT, 0x42);
break;
}
// return ret; // Doesn't match, too few instructions
// return ret ? TRUE : FALSE; // Doesn't match, optimized into arithmetic instead of a branch
return ret ? (ret ? TRUE : TRUE) : FALSE; // Matches, tricking the compiler into using a branch
}
/* 00000D14-00000F04 .text bomb_move_set__FP8am_classUc */
static void bomb_move_set(am_class* i_this, u8 alwaysMoveY) {
if (i_this->mSwallowedActorPID == fpcM_ERROR_PROCESS_ID_e) {
return;
}
fopAc_ac_c* swallowedActor = fopAcM_SearchByID(i_this->mSwallowedActorPID);
if (!swallowedActor) {
return;
}
cMtx_YrotS(*calc_mtx, i_this->shape_angle.y);
cXyz mouthOffset(0.0f, 120.0f, 40.0f);
cXyz mouthPos;
MtxPosition(&mouthOffset, &mouthPos);
mouthPos += i_this->current.pos;
// Pull the bomb into the Armos Knight's mouth by 50 units per frame on each axis.
cLib_addCalc2(&swallowedActor->current.pos.x, mouthPos.x, 1.0f, 50.0f);
if (alwaysMoveY || mouthPos.y - 10.0f < swallowedActor->current.pos.y) {
cLib_addCalc2(&swallowedActor->current.pos.y, mouthPos.y, 1.0f, 50.0f);
}
cLib_addCalc2(&swallowedActor->current.pos.z, mouthPos.z, 1.0f, 50.0f);
swallowedActor->mGravity = 0.0f;
swallowedActor->speedF = 0.0f;
swallowedActor->speed.setall(0.0f);
swallowedActor->current.angle.setall(0);
swallowedActor->shape_angle.setall(0);
swallowedActor->current.angle.y = i_this->shape_angle.y;
swallowedActor->shape_angle.y = i_this->shape_angle.y;
if (fpcM_GetName(swallowedActor) == PROC_BOMB) {
daBomb_c* bomb = (daBomb_c*)swallowedActor;
if (i_this->mCountDownTimers[1] == 1) {
bomb->mScale.setall(0.0f);
bomb->setBombNoEff();
} else if (i_this->mCountDownTimers[1] > 1) {
bomb->mScale.setall(1.0f);
}
bomb->setBombRestTime(100);
} else if (fpcM_GetName(swallowedActor) == PROC_Bomb2) {
daBomb2::Act_c* bomb2 = (daBomb2::Act_c*)swallowedActor;
if (i_this->mCountDownTimers[1] == 1) {
bomb2->mScale.setall(0.0f);
bomb2->remove_fuse_effect();
} else if (i_this->mCountDownTimers[1] > 1) {
bomb2->mScale.setall(1.0f);
}
bomb2->set_time(100);
}
}
/* 00000F04-00001138 .text bomb_nomi_check__FP8am_class */
static BOOL bomb_nomi_check(am_class* i_this) {
fopAc_ac_c* actor = i_this;
i_this->mStts.Move();
if (i_this->mCurrBckIdx != AM_BCK_OPEN && i_this->mCurrBckIdx != AM_BCK_OPEN_LOOP &&
i_this->mCurrBckIdx != AM_BCK_DAMAGE && i_this->mCurrBckIdx != AM_BCK_DAMAGE_LOOP)
{
return FALSE;
}
s16 angleToPlayer = fopAcM_searchPlayerAngleY(actor);
s16 angleDiff = cLib_distanceAngleS(actor->shape_angle.y, angleToPlayer);
if (angleDiff > 0x2000) {
return FALSE;
}
if (i_this->mMouthSph.ChkCoHit()) {
cCcD_Obj* hitObj = i_this->mMouthSph.GetCoHitObj();
if (hitObj) {
cCcD_Stts* hitStts = hitObj->GetStts();
if (hitStts == NULL) {
actor = NULL;
} else {
actor = hitStts->GetAc();
}
if (actor) {
if (fpcM_GetName(actor) == PROC_BOMB) {
daBomb_c* bomb = (daBomb_c*)actor;
if (!bomb->getBombCheck_Flag() && bomb->getBombRestTime() > 1) {
f32 offsetY = 20.0f + g_regHIO.mChild[8].mFloatRegs[1];
if (i_this->mMouthPos.y - offsetY < bomb->current.pos.y) {
// Swallow the bomb.
bomb->setBombCheck_Flag();
bomb->change_state((daBomb_c::State_e)2);
i_this->mSwallowedActorPID = fopAcM_GetID(bomb);
bomb->setBombNoHit();
bomb_move_set(i_this, 0);
i_this->mAction = ACTION_ITAI_MOVE;
i_this->mState = 0x2C;
return TRUE;
}
}
} else if (fpcM_GetName(actor) == PROC_Bomb2) {
daBomb2::Act_c* bomb2 = (daBomb2::Act_c*)actor;
if (!bomb2->chk_eat() && bomb2->get_time() > 1) {
f32 offsetY = 20.0f + g_regHIO.mChild[8].mFloatRegs[1];
if (i_this->mMouthPos.y - offsetY < bomb2->current.pos.y) {
// Swallow the bomb.
bomb2->set_eat();
i_this->mSwallowedActorPID = fopAcM_GetID(bomb2);
bomb2->set_no_hit();
bomb_move_set(i_this, 0);
i_this->mAction = ACTION_ITAI_MOVE;
i_this->mState = 0x2C;
return TRUE;
}
}
}
}
}
}
return FALSE;
}
/* 00001138-000011E4 .text BG_check__FP8am_class */
static void BG_check(am_class* i_this) {
f32 halfHeight = 30.0f + g_regHIO.mChild[12].mFloatRegs[3];
f32 radius = 150.0f + g_regHIO.mChild[12].mFloatRegs[4];
i_this->mAcchCir.SetWall(halfHeight, radius);
i_this->current.pos.y -= i_this->m02EC;
i_this->old.pos.y -= i_this->m02EC;
i_this->mAcch.CrrPos(*dComIfG_Bgsp());
i_this->current.pos.y += i_this->m02EC;
i_this->old.pos.y += i_this->m02EC;
}
/* 000011E4-00001504 .text Line_check__FP8am_class4cXyz */
static BOOL Line_check(am_class* i_this, cXyz destPos) {
fopAc_ac_c* actor = i_this;
dBgS_LinChk linChk;
cXyz centerPos = actor->current.pos;
centerPos.y += 100.0f;
destPos.y += 100.0f;
linChk.Set(&centerPos, &destPos, actor);
if (!dComIfG_Bgsp()->LineCross(&linChk)) {
return TRUE;
}
return FALSE;
}
/* 0000193C-00001B00 .text medama_move__FP8am_class */
static void medama_move(am_class* i_this) {
daPy_py_c* player = daPy_getPlayerActorClass();
if (i_this->mCurrBckIdx == AM_BCK_SLEEP || i_this->mCurrBckIdx == AM_BCK_SLEEP_LOOP) {
i_this->mEyeRot.setall(0);
return;
}
f32 diffX = i_this->current.pos.x - player->current.pos.x;
f32 diffY = i_this->mEyePos.y - player->current.pos.y;
f32 diffZ = i_this->current.pos.z - player->current.pos.z;
i_this->mTargetEyeRot.y = cM_atan2s(diffX, diffZ);
if (i_this->mTargetEyeRot.y < -0x71C) {
i_this->mTargetEyeRot.y = -0x71C;
} else if (i_this->mTargetEyeRot.y > 0x71C) {
i_this->mTargetEyeRot.y = 0x71C;
}
i_this->mTargetEyeRot.x = cM_atan2s(diffY, sqrtf(diffX*diffX + diffZ*diffZ));
if (i_this->mTargetEyeRot.x < -0x38E) {
i_this->mTargetEyeRot.x = -0x38E;
} else if (i_this->mTargetEyeRot.x > 0x38E) {
i_this->mTargetEyeRot.x = 0x38E;
}
cLib_addCalcAngleS2(&i_this->mEyeRot.x, i_this->mTargetEyeRot.x, 1, 0x500);
cLib_addCalcAngleS2(&i_this->mEyeRot.y, i_this->mTargetEyeRot.y, 1, 0x500);
}
/* 00001B00-00002564 .text action_dousa__FP8am_class */
static void action_dousa(am_class* i_this) {
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
switch (i_this->mState) {
case 0:
for (int i = 0; i < ARRAY_SIZE(i_this->mCountUpTimers); i++) {
i_this->mCountUpTimers[i] = 0;
}
anm_init(i_this, AM_BCK_SLEEP_LOOP, 1.0f, J3DFrameCtrl::LOOP_REPEAT_e, 1.0f, -1);
i_this->mState += 1;
// Fall-through
case 1:
if (i_this->mStartsInactive == 1 && i_this->mSwitch != 0xFF && !dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
break;
}
fopAcM_OnStatus(i_this, fopAcStts_SHOWMAP_e);
if (fopAcM_searchPlayerDistance(i_this) < 1000.0f) {
f32 yDist = player->current.pos.y - i_this->current.pos.y;
yDist = sqrtf(yDist*yDist); // ???
if (yDist > 300.0f) {
break;
}
if (Line_check(i_this, player->current.pos)) {
anm_init(i_this, AM_BCK_OKIRU, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_AWAKE, 0);
i_this->mAttentionInfo.mFlags = fopAc_Attn_LOCKON_ENEMY_e;
i_this->mNeedleCyl.OnAtSetBit();
i_this->mNeedleCyl.OnAtHitBit();
i_this->mState += 1;
}
}
break;
case 2:
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (!i_this->mpMorf->isStop()) {
mDoExt_McaMorf* morf = i_this->mpMorf;
bool stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (!stopped) {
break;
}
i_this->mState += 1;
// Fall-through
case 3:
if (i_this->mCurrBckIdx != AM_BCK_CLOSE && i_this->mCurrBckIdx != AM_BCK_CLOSE_LOOP) {
if (i_this->mCurrBckIdx != AM_BCK_DAMAGE_END) {
// Using the fopAcM_seStart inline multiple times in a single case makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_OUT, 0);
// fopAcM_seStart(i_this, JA_SE_CM_AM_MOUTH_CLOSE, 0);
mDoAud_seStart(JA_SE_CM_AM_NEEDLE_OUT, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
mDoAud_seStart(JA_SE_CM_AM_MOUTH_CLOSE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
}
anm_init(i_this, AM_BCK_CLOSE, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
i_this->mCountDownTimers[2] = 6;
}
i_this->mTargetAngleY = fopAcM_searchPlayerAngleY(i_this);
i_this->mState += 1;
// Fall-through
case 4:
if (i_this->mCountDownTimers[2] == 1) {
i_this->mNeedleCyl.OnAtSPrmBit(AT_SPRM_SET);
i_this->mNeedleCyl.OnAtHitBit();
}
if (i_this->mCountDownTimers[2] != 0) {
break;
}
if (i_this->mType & 1) {
f32 xDist = i_this->current.pos.x - i_this->mSpawnPos.x;
f32 zDist = i_this->current.pos.z - i_this->mSpawnPos.z;
f32 xzDist = sqrtf(xDist*xDist + zDist*zDist);
if (xzDist > i_this->mAreaRadius) {
i_this->mAction = ACTION_MODORU_MOVE;
i_this->mState = 0x14;
return;
}
} else {
if (fopAcM_searchPlayerDistance(i_this) > 2000.0f) {
i_this->mState = 9;
break;
}
f32 yDist = player->current.pos.y - i_this->current.pos.y;
yDist = sqrtf(yDist*yDist); // ???
if (yDist > 300.0f) {
i_this->mState = 9;
break;
}
}
s16 yRotDiff = cLib_distanceAngleS(i_this->shape_angle.y, i_this->mTargetAngleY);
if (yRotDiff < 0x100) {
i_this->mState += 1;
}
break;
case 5:
i_this->speedF = 30.0f;
i_this->mGravity = -11.0f;
i_this->speed.y = 40.0f;
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_JUMP, 0);
if (!Line_check(i_this, player->current.pos) || player->getDamageWaitTimer() != 0) {
i_this->speedF = 0.0f;
}
i_this->mState += 1;
break;
case 6:
if (i_this->mCurrBckIdx == AM_BCK_CLOSE) {
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (i_this->mpMorf->isStop()) {
mDoExt_McaMorf* morf = i_this->mpMorf;
bool stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (stopped) {
anm_init(i_this, AM_BCK_CLOSE_LOOP, 1.0f, J3DFrameCtrl::LOOP_REPEAT_e, 1.0f, -1);
}
}
if (!i_this->mAcch.ChkGroundHit()) {
break;
}
fopAcM_seStart(i_this, JA_SE_CM_AM_JUMP, 0);
i_this->mSmokeCbs[0].end();
dComIfGp_particle_setToon(
0xA125, &i_this->mWaistPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[0], fopAcM_GetRoomNo(i_this)
);
dComIfGp_getVibration().StartShock(3, -0x21, cXyz(0.0f, 1.0f, 0.0f));
i_this->speedF = 0.0f;
i_this->mCountDownTimers[0] = 0;
if (i_this->mCountUpTimers[0] < 2) {
i_this->mCountDownTimers[0] = 10;
}
i_this->mState += 1;
// Fall-through
case 7:
if (i_this->mCountDownTimers[0] != 0) {
break;
}
i_this->mCountUpTimers[0]++;
if (i_this->mCountUpTimers[0] > 2) {
i_this->mCountDownTimers[0] = 100;
i_this->mCountUpTimers[0] = 0;
anm_init(i_this, AM_BCK_DAMAGE, 0.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
// Using the fopAcM_seStart inline multiple times in a single case makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_IN, 0);
// fopAcM_seStart(i_this, JA_SE_CM_AM_MOUTH_OPEN, 0);
mDoAud_seStart(JA_SE_CM_AM_NEEDLE_IN, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
mDoAud_seStart(JA_SE_CM_AM_MOUTH_OPEN, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_OPEN_MOUTH, 0);
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
if (i_this->mSmokeCbs[2].getEmitter() == NULL) {
dComIfGp_particle_setToon(
0xA154, &i_this->mWaistPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[2], fopAcM_GetRoomNo(i_this)
);
}
i_this->mState = 8;
} else {
i_this->mState = 3;
}
break;
case 8:
if (i_this->mAcch.ChkGroundHit()) {
i_this->mGravity = -6.0f;
i_this->speed.y = 15.0f;
fopAcM_seStart(i_this, JA_SE_CM_AM_JUMP_S, 0);
i_this->mTargetAngleY = fopAcM_searchPlayerAngleY(i_this);
}
if (i_this->mCountDownTimers[0] == 0) {
i_this->mSmokeCbs[2].end();
i_this->mState = 3;
}
break;
case 9:
anm_init(i_this, AM_BCK_SLEEP, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_IN, 0);
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
i_this->mAttentionInfo.mFlags = 0;
i_this->mState += 1;
break;
case 10:
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (i_this->mpMorf->isStop()) {
morf = i_this->mpMorf;
stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (stopped) {
i_this->mState = 0;
}
break;
}
medama_move(i_this);
if (i_this->mState != 2 && medama_atari_check(i_this)) {
i_this->mSmokeCbs[2].end();
} else if (bomb_nomi_check(i_this)) {
i_this->mSmokeCbs[2].end();
}
}
/* 00002564-000028C4 .text action_modoru_move__FP8am_class */
static void action_modoru_move(am_class* i_this) {
switch (i_this->mState) {
case 0x14:
anm_init(i_this, AM_BCK_CLOSE_LOOP, 1.0f, J3DFrameCtrl::LOOP_REPEAT_e, 1.0f, -1);
i_this->mNeedleCyl.OnAtSetBit();
i_this->mNeedleCyl.OnAtHitBit();
i_this->mGravity = -11.0f;
i_this->speed.y = 40.0f;
i_this->speedF = 15.0f;
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_JUMP, 0x42);
f32 xDistToSpawn = i_this->mSpawnPos.x - i_this->current.pos.x;
f32 zDistToSpawn = i_this->mSpawnPos.z - i_this->current.pos.z;
i_this->mTargetAngleY = cM_atan2s(xDistToSpawn, zDistToSpawn);
i_this->mState += 1;
break;
case 0x15:
xDistToSpawn = i_this->mSpawnPos.x - i_this->current.pos.x;
zDistToSpawn = i_this->mSpawnPos.z - i_this->current.pos.z;
if (i_this->mAcch.ChkGroundHit()) {
i_this->mSmokeCbs[0].end();
dComIfGp_particle_setToon(
0xA125, &i_this->mWaistPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[0], fopAcM_GetRoomNo(i_this)
);
dComIfGp_getVibration().StartShock(1, -0x21, cXyz(0.0f, 1.0f, 0.0f));
// The fopAcM_seStart inline makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_JUMP, 0);
mDoAud_seStart(JA_SE_CM_AM_JUMP, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_JUMP, 0x42);
i_this->speed.y = 40.0f;
i_this->speedF = 15.0f;
i_this->mTargetAngleY = cM_atan2s(xDistToSpawn, zDistToSpawn);
}
f32 xzDist = sqrtf(xDistToSpawn*xDistToSpawn + zDistToSpawn*zDistToSpawn);
if (xzDist < 20.0f) {
i_this->mTargetAngleY = i_this->mSpawnRotY;
i_this->speedF = 0.0f;
i_this->mState += 1;
}
break;
case 0x16:
s16 angleDiff = cLib_distanceAngleS(i_this->shape_angle.y, i_this->mTargetAngleY);
if (angleDiff < 0x100) {
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
i_this->mAttentionInfo.mFlags = 0;
i_this->mAction = ACTION_DOUSA;
i_this->mState = 0;
}
break;
}
}
/* 000028C4-00002A6C .text action_handou_move__FP8am_class */
static void action_handou_move(am_class* i_this) {
/* Nonmatching */
daPy_py_c* player = daPy_getPlayerActorClass();
switch (i_this->mState) {
case 0x1E:
i_this->speedF = 20.0f;
s16 angleToPlayer = fopAcM_searchPlayerAngleY(i_this);
i_this->current.angle.y = angleToPlayer + 0x8000;
if (i_this->mHugeKnockback == 1) {
i_this->current.angle.y = player->shape_angle.y - 0x4000;
i_this->speedF = 40.0f;
}
i_this->mTargetAngleY = i_this->current.angle.y;
if (i_this->mCurrBckIdx != AM_BCK_CLOSE && i_this->mCurrBckIdx != AM_BCK_CLOSE_LOOP) {
// Using the fopAcM_seStart inline multiple times makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_OUT, 0);
// fopAcM_seStart(i_this, JA_SE_CM_AM_MOUTH_CLOSE, 0);
mDoAud_seStart(JA_SE_CM_AM_NEEDLE_OUT, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
mDoAud_seStart(JA_SE_CM_AM_MOUTH_CLOSE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
anm_init(i_this, AM_BCK_CLOSE, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
}
i_this->mState += 1;
case 0x1F:
cLib_addCalc0(&i_this->speedF, 0.8f, 2.0f);
if (i_this->speedF < 0.1f) {
i_this->speedF = 0.0f;
i_this->mCountDownTimers[2] = 6;
i_this->current.angle.y = i_this->shape_angle.y;
i_this->mAction = ACTION_DOUSA;
i_this->mState = 3;
}
}
}
/* 00002A6C-000034F4 .text action_itai_move__FP8am_class */
static void action_itai_move(am_class* i_this) {
switch (i_this->mState) {
case 0x28:
i_this->mEyeRot.setall(0);
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
i_this->speedF = -20.0f;
i_this->current.angle.y = fopAcM_searchPlayerAngleY(i_this);
i_this->mTargetAngleY = i_this->current.angle.y;
fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_IN, 0);
anm_init(i_this, AM_BCK_DAMAGE, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
i_this->mState += 1;
// Fall-through
case 0x29:
cLib_addCalc0(&i_this->speedF, 0.8f, 2.0f);
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (!i_this->mpMorf->isStop()) {
mDoExt_McaMorf* morf = i_this->mpMorf;
bool stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (!stopped) {
break;
}
i_this->mCountDownTimers[0] = 100;
i_this->speedF = 0.0f;
anm_init(i_this, AM_BCK_DAMAGE_LOOP, 1.0f, J3DFrameCtrl::LOOP_REPEAT_e, 1.0f, -1);
i_this->mState += 1;
break;
case 0x2A:
if (i_this->mCountDownTimers[0] != 0) {
break;
}
anm_init(i_this, AM_BCK_DAMAGE_END, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
// Using the fopAcM_seStart inline multiple times in a single case makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_NEEDLE_OUT, 0);
// fopAcM_seStart(i_this, JA_SE_CM_AM_MOUTH_CLOSE, 0);
mDoAud_seStart(JA_SE_CM_AM_NEEDLE_OUT, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
mDoAud_seStart(JA_SE_CM_AM_MOUTH_CLOSE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
i_this->mState += 1;
break;
case 0x2B:
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (!i_this->mpMorf->isStop()) {
morf = i_this->mpMorf;
stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (!stopped) {
break;
}
i_this->mNeedleCyl.OnAtSetBit();
i_this->mNeedleCyl.OnAtHitBit();
i_this->mCountUpTimers[0] = 0;
i_this->mAction = ACTION_DOUSA;
i_this->mState = 3;
break;
case 0x2C:
i_this->mSmokeCbs[3].end();
i_this->mStts.SetWeight(0xFF);
dComIfGp_particle_setToon(
0xA155, &i_this->mJawPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[3], fopAcM_GetRoomNo(i_this)
);
fopAcM_seStart(i_this, JA_SE_CM_AM_MOUTH_CLOSE, 0);
anm_init(i_this, AM_BCK_BOM_NOMI, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
mDoAud_onEnemyDamage();
i_this->mEyeRot.setall(0);
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
i_this->mCountDownTimers[1] = 10;
i_this->mState += 1;
// Fall-through
case 0x2D:
bomb_move_set(i_this, 0);
if (i_this->mpMorf->checkFrame(3.0f)) {
// The fopAcM_seStart inline makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_EAT_BOMB, 0);
mDoAud_seStart(JA_SE_CM_AM_EAT_BOMB, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_EAT_BOMB, 0);
}
if (i_this->mpMorf->checkFrame(6.0f)) {
i_this->mSmokeCbs[1].end();
i_this->mNeedleCyl.OnAtSetBit();
i_this->mNeedleCyl.OnAtHitBit();
dComIfGp_particle_setToon(
0xA126, &i_this->mJawPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[1], fopAcM_GetRoomNo(i_this)
);
i_this->m033C = dComIfGp_particle_set(0x8157, &i_this->mJawPos);
i_this->m0340 = dComIfGp_particle_set(0x8156, &i_this->mJawPos);
}
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (!i_this->mpMorf->isStop()) {
morf = i_this->mpMorf;
stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (!stopped) {
break;
}
i_this->mCountDownTimers[0] = 100;
i_this->mTargetAngleY = fopAcM_searchPlayerAngleY(i_this);
i_this->mState += 1;
break;
case 0x2E:
bomb_move_set(i_this, 1);
i_this->shape_angle.y += 0x1000;
if (i_this->mAcch.ChkGroundHit()) {
i_this->mSmokeCbs[0].end();
// The fopAcM_seStart inline makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_JUMP, 0);
mDoAud_seStart(JA_SE_CM_AM_JUMP, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
dComIfGp_particle_setToon(
0xA125, &i_this->mWaistPos, &i_this->shape_angle, NULL,
0xB9, &i_this->mSmokeCbs[0], fopAcM_GetRoomNo(i_this)
);
dComIfGp_getVibration().StartShock(1, -0x21, cXyz(0.0f, 1.0f, 0.0f));
// The fopAcM_seStart inline makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_JUMP_L, 0);
mDoAud_seStart(JA_SE_CM_AM_JUMP_L, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_monsSeStart(i_this, JA_SE_CV_AM_JITABATA, 0);
i_this->speed.y = 25.0f;
i_this->mGravity = -10.0f;
i_this->speedF = 10.0f;
}
if (i_this->mCountDownTimers[0] != 0) {
break;
}
anm_init(i_this, AM_BCK_DEAD, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
dComIfGp_particle_set(0x8127, &i_this->mWaistPos);
dComIfGp_particle_set(0x8128, &i_this->mWaistPos);
// The fopAcM_seStart inline makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_BEF_EXPLODE, 0);
mDoAud_seStart(JA_SE_CM_AM_BEF_EXPLODE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
i_this->mTargetAngleY = i_this->current.angle.y;
if (i_this->m033C) {
i_this->m033C->becomeInvalidEmitter();
i_this->m033C = NULL;
}
if (i_this->m0340) {
i_this->m0340->becomeInvalidEmitter();
i_this->m0340 = NULL;
}
i_this->speedF = 0.0f;
i_this->mState += 1;
break;
case 0x2F:
bomb_move_set(i_this, 1);
// Using the mDoExt_McaMorf::isStop inline causes regswap.
// if (!i_this->mpMorf->isStop()) {
morf = i_this->mpMorf;
stopped = true;
if (!morf->mFrameCtrl.checkState(J3DFrameCtrl::STATE_STOP_E) && morf->mFrameCtrl.getRate() != 0.0f) { stopped = false; }
if (!stopped) {
break;
}
cXyz centerPos = i_this->current.pos;
centerPos.y += 150.0f;
if (i_this->mSwallowedActorPID != fpcM_ERROR_PROCESS_ID_e) {
fopAc_ac_c* swallowedActor = fopAcM_SearchByID(i_this->mSwallowedActorPID);
if (swallowedActor) {
swallowedActor->mScale.setall(1.0f);
if (fpcM_GetName(swallowedActor) == PROC_BOMB) {
daBomb_c* bomb = (daBomb_c*)swallowedActor;
bomb->setBombRestTime(1);
} else if (fpcM_GetName(swallowedActor) == PROC_Bomb2) {
daBomb2::Act_c* bomb2 = (daBomb2::Act_c*)swallowedActor;
bomb2->set_time(1);
}
}
}
// Using the fopAcM_seStart inline multiple times in a single case makes the codegen not match.
// fopAcM_seStart(i_this, JA_SE_CM_AM_EXPLODE, 0);
// fopAcM_seStart(i_this, JA_SE_LK_LAST_HIT, 0);
mDoAud_seStart(JA_SE_CM_AM_EXPLODE, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
mDoAud_seStart(JA_SE_LK_LAST_HIT, &i_this->mEyePos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));
fopAcM_createDisappear(i_this, &centerPos, 5);
fopAcM_onActor(i_this);
fopAcM_delete(i_this);
break;
}
if (i_this->m033C) {
i_this->m033C->setGlobalRTMatrix(i_this->mpMorf->getModel()->getAnmMtx(2));
}
if (i_this->m0340) {
i_this->m0340->setGlobalRTMatrix(i_this->mpMorf->getModel()->getAnmMtx(2));
}
if (i_this->mState == 0x29 || i_this->mState == 0x2A) {
bomb_nomi_check(i_this);
}
}
/* 000034F4-000039A4 .text daAM_Execute__FP8am_class */
static BOOL daAM_Execute(am_class* i_this) {
fopAcM_setGbaName(i_this, BOW, 0xC, 0x2A);
if (enemy_ice(&i_this->mEnemyIce)) {
i_this->mpMorf->getModel()->setBaseTRMtx(mDoMtx_stack_c::get());
i_this->mpMorf->calc();
return TRUE;
}
for (int i = 0; i < ARRAY_SIZE(i_this->mCountDownTimers); i++) {
if (i_this->mCountDownTimers[i] != 0) {
i_this->mCountDownTimers[i]--;
}
}
switch (i_this->mAction) {
case ACTION_DOUSA:
action_dousa(i_this);
break;
case ACTION_MODORU_MOVE:
action_modoru_move(i_this);
break;
case ACTION_HANDOU_MOVE:
action_handou_move(i_this);
break;
case ACTION_ITAI_MOVE:
action_itai_move(i_this);
break;
}
if (i_this->mAction != ACTION_ITAI_MOVE && i_this->mSpawnPosY - 1500.0f > i_this->current.pos.y) {
anm_init(i_this, AM_BCK_DEAD, 1.0f, J3DFrameCtrl::LOOP_ONCE_e, 1.0f, -1);
dComIfGp_particle_set(0x8127, &i_this->mWaistPos);
dComIfGp_particle_set(0x8128, &i_this->mWaistPos);
fopAcM_seStart(i_this, JA_SE_CM_AM_BEF_EXPLODE, 0);
i_this->mTargetAngleY = i_this->current.angle.y;
if (i_this->m033C) {
i_this->m033C->becomeInvalidEmitter();
i_this->m033C = NULL;
}
if (i_this->m0340) {
i_this->m0340->becomeInvalidEmitter();
i_this->m0340 = NULL;
}
i_this->speedF = 0.0f;
i_this->mAction = ACTION_ITAI_MOVE;
i_this->mState = 0x2F;
}
cLib_addCalcAngleS2(&i_this->current.angle.y, i_this->mTargetAngleY, 1, 0x500);
if (i_this->mState != 0x2E && i_this->mState != 0x2F && i_this->mState != 0x1F) {
cLib_addCalcAngleS2(&i_this->shape_angle.y, i_this->current.angle.y, 1, 0x500);
}
if (i_this->mCountDownTimers[1] == 0) {
i_this->mpMorf->play(NULL, 0, 0);
}
cMtx_YrotS(*calc_mtx, i_this->current.angle.y);
cMtx_XrotM(*calc_mtx, i_this->current.angle.x);
cXyz offset;
offset.x = 0.0f;
offset.y = 0.0f;
offset.z = i_this->speedF;
cXyz rotOffset;
MtxPosition(&offset, &rotOffset);
i_this->speed.x = rotOffset.x;
i_this->speed.z = rotOffset.z;
i_this->speed.y += i_this->mGravity;
if (i_this->speed.y < -100.0f) {
i_this->speed.y = -100.0f;
}
body_atari_check(i_this);
i_this->mAttentionInfo.mPosition = i_this->current.pos;
i_this->mAttentionInfo.mPosition.y += 330.0f;
i_this->mEyePos = i_this->current.pos;
i_this->mEyePos.y += 250.0f;
cXyz needlePos = i_this->current.pos;
i_this->mEyeSph.SetC(i_this->mEyeballPos);
i_this->mEyeSph.SetR(60.0f);
dComIfG_Ccsp()->Set(&i_this->mEyeSph);
i_this->mMouthSph.SetC(i_this->mMouthPos);
i_this->mMouthSph.SetR(100.0f);
dComIfG_Ccsp()->Set(&i_this->mMouthSph);
i_this->mBodyCyl.SetC(i_this->current.pos);
i_this->mBodyCyl.SetH(300.0f);
i_this->mBodyCyl.SetR(80.0f);
dComIfG_Ccsp()->Set(&i_this->mBodyCyl);
needlePos.y += 40.0f;
i_this->mNeedleCyl.SetC(needlePos);
i_this->mNeedleCyl.SetH(30.0f);
i_this->mNeedleCyl.SetR(130.0f);
dComIfG_Ccsp()->Set(&i_this->mNeedleCyl);
fopAcM_posMove(i_this, i_this->mStts.GetCCMoveP());
BG_check(i_this);
draw_SUB(i_this);
return TRUE;
}
/* 000039A4-000039AC .text daAM_IsDelete__FP8am_class */
static BOOL daAM_IsDelete(am_class* i_this) {
return TRUE;
}
/* 000039AC-00003A84 .text daAM_Delete__FP8am_class */
static BOOL daAM_Delete(am_class* i_this) {
dComIfG_resDelete(&i_this->mPhs, "AM");
for (int i = 0; i < 4; i++) {
i_this->mSmokeCbs[i].end();
}
i_this->mSmokeCbs[2].end();
if (i_this->m033C) {
i_this->m033C->becomeInvalidEmitter();
i_this->m033C = NULL;
}
if (i_this->m0340) {
i_this->m0340->becomeInvalidEmitter();
i_this->m0340 = NULL;
}
return TRUE;
}
/* 00003A84-00003C00 .text useHeapInit__FP10fopAc_ac_c */
static BOOL useHeapInit(fopAc_ac_c* i_actor) {
am_class* i_this = (am_class*)i_actor;
i_this->mpMorf = new mDoExt_McaMorf(
(J3DModelData*)dComIfG_getObjectRes("AM", AM_BDL_AM),
NULL, NULL,
(J3DAnmTransformKey*)dComIfG_getObjectRes("AM", AM_BCK_SLEEP_LOOP),
J3DFrameCtrl::LOOP_REPEAT_e, 1.0f, 0, -1, 1,
NULL,
0x00000000,
0x11020203
);
if (!i_this->mpMorf || !i_this->mpMorf->getModel()) {
return FALSE;
}
i_this->mpMorf->getModel()->setUserArea((u32)i_this);
for (u16 i = 0; i < i_this->mpMorf->getModel()->getModelData()->getJointNum(); i++) {
i_this->mpMorf->getModel()->getModelData()->getJointNodePointer(i)->setCallBack(nodeCallBack);
}
static Vec cyl2_eye_offset[] = {
{0.0f, 0.0f, 70.0f},
{0.0f, 0.0f, 80.0f},
};
static __jnt_hit_data_c search_data[] = {
{
/* mShapeType */ 2, // Cylinder
/* mJointIndex */ 0x05, // hitomi (pupil) joint
/* mRadius */ 5.0f,
/* mpOffsets */ cyl2_eye_offset,
},
};
i_this->mEyeJntHit = JntHit_create(i_this->mpMorf->getModel(), search_data, ARRAY_SIZE(search_data));
if (i_this->mEyeJntHit) {
i_this->mJntHit = i_this->mEyeJntHit;
} else {
return FALSE;
}
return TRUE;
}
/* 00003C00-00003F5C .text daAM_Create__FP10fopAc_ac_c */
static s32 daAM_Create(fopAc_ac_c* i_actor) {
fopAcM_SetupActor(i_actor, am_class);
am_class* i_this = (am_class*)i_actor;
s32 phase_state = dComIfG_resLoad(&i_this->mPhs, "AM");
if (phase_state == cPhs_COMPLEATE_e) {
if (!fopAcM_entrySolidHeap(i_this, useHeapInit, 0x1C80)) {
return cPhs_ERROR_e;
}
i_this->mStealItemLeft = 3;
i_this->mSmokeCbs[0].setRateOff(0);
i_this->mSmokeCbs[1].setRateOff(0);
i_this->mSmokeCbs[3].setRateOff(0);
i_this->mType = (fopAcM_GetParam(i_this) >> 0x00) & 0xFF;
i_this->mPrmAreaRadius = (fopAcM_GetParam(i_this) >> 0x08) & 0xFF;
i_this->mStartsInactive = (fopAcM_GetParam(i_this) >> 0x10) & 0xFF;
i_this->mSwitch = (fopAcM_GetParam(i_this) >> 0x18) & 0xFF;
if (i_this->mType == 0xFF) {
i_this->mType = 0;
}
if (i_this->mStartsInactive == 0xFF) {
i_this->mStartsInactive = 0;
}
if (g_regHIO.mChild[8].mShortRegs[9] != 0) {
i_this->mType = 1;
}
if (i_this->mPrmAreaRadius == 0xFF || i_this->mPrmAreaRadius == 0) {
i_this->mAreaRadius = 400.0f;
} else {
i_this->mAreaRadius = i_this->mPrmAreaRadius * 100.0f;
}
i_this->mSpawnPosY = i_this->current.pos.y;
i_this->mSwallowedActorPID = fpcM_ERROR_PROCESS_ID_e;
if (i_this->mStartsInactive == 0 && i_this->mSwitch != 0xFF && dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
// When mStartsInactive is 0, the Armos Knight starts active and attacking the player.
// mSwitch being set disables it from spawning again in the future.
return cPhs_ERROR_e;
}
if (i_this->mStartsInactive == 1 && i_this->mSwitch != 0xFF && !dComIfGs_isSwitch(i_this->mSwitch, dComIfGp_roomControl_getStayNo())) {
// When mStartsInactive is 1, the Armos Knight is initially inactive.
// mSwitch being set causes it to become active and attack the player.
fopAcM_OffStatus(i_this, fopAcStts_SHOWMAP_e);
}
i_this->mItemTableIdx = dComIfGp_CharTbl()->GetNameIndex("amos", 0);
i_this->mMaxHealth = 10;
i_this->mHealth = 10;
fopAcM_SetMtx(i_this, i_this->mpMorf->mpModel->getBaseTRMtx());
fopAcM_setCullSizeBox(i_this, -100.0f, -10.0f, -80.0f, 120.0f, 400.0f, 100.0f);
i_this->mAttentionInfo.mFlags = 0;
i_this->mAcch.Set(
fopAcM_GetPosition_p(i_this), fopAcM_GetOldPosition_p(i_this),
i_this, 1, &i_this->mAcchCir, fopAcM_GetSpeed_p(i_this)
);
i_this->mStts.Init(254, 1, i_this);
i_this->mGravity = -10.0f;
i_this->mEnemyIce.mpActor = i_this;
i_this->mEnemyIce.mWallRadius = 80.0f;
i_this->mEnemyIce.mCylHeight = 300.0f;
static dCcD_SrcSph eye_co_sph_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ AT_TYPE_UNK1000,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ AT_TYPE_NORMAL_ARROW | AT_TYPE_FIRE_ARROW | AT_TYPE_ICE_ARROW | AT_TYPE_LIGHT_ARROW | AT_TYPE_GRAPPLING_HOOK,
/* SrcObjTg SPrm */ TG_SPRM_SET | TG_SPRM_IS_ENEMY,
/* SrcObjCo SPrm */ 0,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_NO_CON_HIT | G_TG_SPRM_NO_HIT_MARK,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGSphS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 15.0f,
},
};
i_this->mEyeSph.Set(eye_co_sph_src);
i_this->mEyeSph.SetStts(&i_this->mStts);
static dCcD_SrcSph mouth_co_sph_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ AT_TYPE_UNK1000,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ 0,
/* SrcObjTg SPrm */ 0,
/* SrcObjCo SPrm */ CO_SPRM_SET | CO_SPRM_IS_UNK4 | CO_SPRM_VS_UNK8 | CO_SPRM_NO_CRR,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_NO_CON_HIT,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGSphS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 15.0f,
},
};
i_this->mMouthSph.Set(mouth_co_sph_src);
i_this->mMouthSph.SetStts(&i_this->mStts);
static dCcD_SrcCyl body_co_cyl_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ AT_TYPE_UNK1000,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ ~(AT_TYPE_WATER | AT_TYPE_UNK20000 | AT_TYPE_WIND | AT_TYPE_UNK400000 | AT_TYPE_LIGHT),
/* SrcObjTg SPrm */ TG_SPRM_SET | TG_SPRM_IS_ENEMY,
/* SrcObjCo SPrm */ CO_SPRM_SET | CO_SPRM_IS_UNK4 | CO_SPRM_VSGRP,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ G_TG_MARK_PURPLE_HIT,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_SHIELD | G_TG_SPRM_NO_CON_HIT,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGCylS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 15.0f,
/* Height */ 0.0f,
},
};
i_this->mBodyCyl.Set(body_co_cyl_src);
i_this->mBodyCyl.SetStts(&i_this->mStts);
static dCcD_SrcCyl sword_co_cyl_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ AT_TYPE_UNK1000,
/* SrcObjAt Atp */ 2,
/* SrcObjAt SPrm */ AT_SPRM_SET | AT_SPRM_GRP,
/* SrcObjTg Type */ 0,
/* SrcObjTg SPrm */ 0,
/* SrcObjCo SPrm */ CO_SPRM_SET | CO_SPRM_IS_UNK4 | CO_SPRM_VSGRP,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0x06,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ G_TG_MARK_PURPLE_HIT,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_SHIELD | G_TG_SPRM_NO_CON_HIT,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGCylS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 15.0f,
/* Height */ 0.0f,
},
};
i_this->mNeedleCyl.Set(sword_co_cyl_src);
i_this->mNeedleCyl.SetStts(&i_this->mStts);
i_this->mNeedleCyl.OffAtSetBit();
i_this->mNeedleCyl.OffAtSetBit();
i_this->mTargetAngleY = i_this->current.angle.y;
i_this->mSpawnPos = i_this->current.pos;
i_this->mSpawnRotY = i_this->current.angle.y;
draw_SUB(i_this);
}
return phase_state;
}
static actor_method_class l_daAM_Method = {
(process_method_func)daAM_Create,
(process_method_func)daAM_Delete,
(process_method_func)daAM_Execute,
(process_method_func)daAM_IsDelete,
(process_method_func)daAM_Draw,
};
actor_process_profile_definition g_profile_AM = {
/* LayerID */ fpcLy_CURRENT_e,
/* ListID */ 7,
/* ListPrio */ fpcPi_CURRENT_e,
/* ProcName */ PROC_AM,
/* Proc SubMtd */ &g_fpcLf_Method.mBase,
/* Size */ sizeof(am_class),
/* SizeOther */ 0,
/* Parameters */ 0,
/* Leaf SubMtd */ &g_fopAc_Method.base,
/* Priority */ 0x00BD,
/* Actor SubMtd */ &l_daAM_Method,
/* Status */ fopAcStts_SHOWMAP_e | fopAcStts_CULL_e | fopAcStts_UNK40000_e,
/* Group */ fopAc_ENEMY_e,
/* CullType */ fopAc_CULLBOX_CUSTOM_e,
};