From 2e10e625d37c66dc405e02ac0ddb734f8183a42b Mon Sep 17 00:00:00 2001 From: Niklas Bauer Date: Mon, 21 Apr 2025 10:05:58 +0900 Subject: [PATCH] d_a_e_tk_ball Matching (#2402) * d_a_e_tk_ball matching * d_a_e_tk_ball cleanup * d_a_e_tk_ball comments --- configure.py | 2 +- include/SSystem/SComponent/c_cc_d.h | 2 + include/d/actor/d_a_e_tk_ball.h | 38 +- src/d/actor/d_a_e_tk.cpp | 2 +- src/d/actor/d_a_e_tk2.cpp | 2 +- src/d/actor/d_a_e_tk_ball.cpp | 764 +++++++++++++++------------- 6 files changed, 453 insertions(+), 357 deletions(-) diff --git a/configure.py b/configure.py index 1ab5eecf91b..905eb0ef1e6 100755 --- a/configure.py +++ b/configure.py @@ -1676,7 +1676,7 @@ config.libs = [ ActorRel(MatchingFor("GZ2E01"), "d_a_e_th_ball"), ActorRel(MatchingFor("GZ2E01"), "d_a_e_tk"), ActorRel(MatchingFor("GZ2E01"), "d_a_e_tk2"), - ActorRel(NonMatching, "d_a_e_tk_ball"), + ActorRel(MatchingFor("GZ2E01"), "d_a_e_tk_ball"), ActorRel(NonMatching, "d_a_e_tt"), ActorRel(NonMatching, "d_a_e_vt"), ActorRel(NonMatching, "d_a_e_warpappear"), diff --git a/include/SSystem/SComponent/c_cc_d.h b/include/SSystem/SComponent/c_cc_d.h index de6af75a727..c8c413edc84 100644 --- a/include/SSystem/SComponent/c_cc_d.h +++ b/include/SSystem/SComponent/c_cc_d.h @@ -522,6 +522,8 @@ public: void OnTgSetBit() { mObjTg.OnSPrmBit(1); } void OffTgSetBit() { mObjTg.ClrSet(); } void OnCoSetBit() { mObjCo.OnSPrmBit(1); } + void OffAtVsEnemyBit() { mObjAt.OffSPrmBit(0x2); } + void OnAtVsEnemyBit() { mObjAt.OnSPrmBit(0x2); } void OffAtVsPlayerBit() { mObjAt.OffSPrmBit(0xC); } void OnAtVsPlayerBit() { mObjAt.OnSPrmBit(0xC); } void OnCoSPrmBit(u32 flag) { mObjCo.OnSPrmBit(flag); } diff --git a/include/d/actor/d_a_e_tk_ball.h b/include/d/actor/d_a_e_tk_ball.h index 5c990cb2b02..7b391fa4cff 100644 --- a/include/d/actor/d_a_e_tk_ball.h +++ b/include/d/actor/d_a_e_tk_ball.h @@ -1,21 +1,45 @@ #ifndef D_A_E_TK_BALL_H #define D_A_E_TK_BALL_H -#include "f_op/f_op_actor_mng.h" + +#include "f_op/f_op_actor.h" +#include "d/d_cc_d.h" /** * @ingroup actors-enemies * @class e_tk_ball_class * @brief Fire/Water Toadpoli Ball - * - * @details - * + * + * @details Projectiles spat by Toadpoli enemies at the player. + * Two types exist: fire and water. Link can deflect these balls + * with his shield or slice them with his sword. When deflected + * while locked on to the enemy, they will return to the Toadpoli + * that fired them. */ + class e_tk_ball_class : public fopEn_enemy_c { public: - /* 0x5ac */ u8 field_0x5ac[0x8cc - 0x5ac]; + /* 0x5AC */ request_of_phase_process_class mPhaseReq; + /* 0x5B4 */ u8 mType; + /* 0x5B5 */ u8 mArg1; + /* 0x5B8 */ J3DModel* mpModel; + /* 0x5BC */ Z2SoundObjSimple mSound; + /* 0x5DC */ s16 mLifetime; + /* 0x5DE */ s16 mAction; + /* 0x5E0 */ s16 mMode; + /* 0x5E2 */ s16 mActionTimer[2]; + /* 0x5E6 */ s16 mInvincibilityTimer; + /* 0x5E8 */ cXyz mInitalPosition; + /* 0x5F4 */ f32 mInitalDistance; + /* 0x5F8 */ f32 mArcHeight; + /* 0x5FC */ dCcD_Stts mStts; + /* 0x638 */ dCcD_Sph mAtSph; + /* 0x770 */ dCcD_Sph mTgSph; + /* 0x8A8 */ u32 mParticleKey[2]; + /* 0x8B0 */ cXyz mParticleDirection; + /* 0x8BC */ cXyz mPreviousPosition; + /* 0x8C8 */ bool mSuspended; }; -STATIC_ASSERT(sizeof(e_tk_ball_class) == 0x8cc); - +STATIC_ASSERT(sizeof(e_tk_ball_class) == 0x8CC); #endif /* D_A_E_TK_BALL_H */ diff --git a/src/d/actor/d_a_e_tk.cpp b/src/d/actor/d_a_e_tk.cpp index 2ea2209d7ee..3589d9c3835 100644 --- a/src/d/actor/d_a_e_tk.cpp +++ b/src/d/actor/d_a_e_tk.cpp @@ -630,7 +630,7 @@ static int daE_TK_Execute(e_tk_class* i_this) { static_cast(fopAcM_SearchByID(i_this->mBallID)); if (ball_actor != NULL) { ball_actor->current.pos = i_this->eyePos; - ball_actor->field_0x5ac[0x31C] = 0x0; + ball_actor->mSuspended = false; } cXyz scale; diff --git a/src/d/actor/d_a_e_tk2.cpp b/src/d/actor/d_a_e_tk2.cpp index 024928f67ab..11488cf10b7 100644 --- a/src/d/actor/d_a_e_tk2.cpp +++ b/src/d/actor/d_a_e_tk2.cpp @@ -441,7 +441,7 @@ static int daE_TK2_Execute(e_tk2_class* i_this) { static_cast(fopAcM_SearchByID(i_this->mBallID)); if (ball_actor != NULL) { ball_actor->current.pos = i_this->eyePos; - ball_actor->field_0x5ac[0x31C] = 0x0; + ball_actor->mSuspended = false; } cXyz scale; scale.setall(2.0f); diff --git a/src/d/actor/d_a_e_tk_ball.cpp b/src/d/actor/d_a_e_tk_ball.cpp index 559059e629e..9c5cbb641ad 100644 --- a/src/d/actor/d_a_e_tk_ball.cpp +++ b/src/d/actor/d_a_e_tk_ball.cpp @@ -1,400 +1,470 @@ /** * @file d_a_e_tk_ball.cpp - * -*/ + * + */ #include "d/actor/d_a_e_tk_ball.h" -#include "d/d_cc_d.h" -#include "dol2asm.h" +#include "d/actor/d_a_player.h" +enum Action { + /* 0x00 */ ACT_TK_BALL_MOVE, // Move in a straight line + /* 0x01 */ ACT_TK_BALL_RETURN, // Return to sender (when player locks on target and reflects) + /* 0x02 */ ACT_TK_BALL_DROP, // Fall to the ground (when reflected without lock-on) +}; -// -// Forward References: -// +enum Mode { + /* 0x00 */ MODE_TK_BALL_INIT, // Initialization state + /* 0x01 */ MODE_TK_BALL_MOVE, // Active state +}; -extern "C" static void daE_TK_BALL_Draw__FP15e_tk_ball_class(); -extern "C" static void simple_bg_check__FP15e_tk_ball_class(); -extern "C" static void impact_eff_set__FP15e_tk_ball_class(); -extern "C" static void e_tk_ball_move__FP15e_tk_ball_class(); -extern "C" static void e_tk_ball_return__FP15e_tk_ball_class(); -extern "C" static void e_tk_ball_drop__FP15e_tk_ball_class(); -extern "C" static void action__FP15e_tk_ball_class(); -extern "C" static void daE_TK_BALL_Execute__FP15e_tk_ball_class(); -extern "C" static bool daE_TK_BALL_IsDelete__FP15e_tk_ball_class(); -extern "C" static void daE_TK_BALL_Delete__FP15e_tk_ball_class(); -extern "C" static void useHeapInit__FP10fopAc_ac_c(); -extern "C" static void daE_TK_BALL_Create__FP10fopAc_ac_c(); -extern "C" void __dt__8cM3dGSphFv(); -extern "C" void __dt__8cM3dGAabFv(); -extern "C" extern char const* const d_a_e_tk_ball__stringBase0; - -// -// External References: -// - -extern "C" void mDoMtx_XrotM__FPA4_fs(); -extern "C" void mDoMtx_YrotS__FPA4_fs(); -extern "C" void mDoMtx_YrotM__FPA4_fs(); -extern "C" void scaleM__14mDoMtx_stack_cFfff(); -extern "C" void mDoExt_modelUpdateDL__FP8J3DModel(); -extern "C" void mDoExt_J3DModel__create__FP12J3DModelDataUlUl(); -extern "C" void __ct__10fopAc_ac_cFv(); -extern "C" void fopAcIt_Judge__FPFPvPv_PvPv(); -extern "C" void fopAcM_delete__FP10fopAc_ac_c(); -extern "C" void fopAcM_entrySolidHeap__FP10fopAc_ac_cPFP10fopAc_ac_c_iUl(); -extern "C" void fpcSch_JudgeByID__FPvPv(); -extern "C" void dComIfG_resLoad__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfG_resDelete__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfGp_getReverb__Fi(); -extern "C" void getRes__14dRes_control_cFPCclP11dRes_info_ci(); -extern "C" void getEmitter__Q213dPa_control_c7level_cFUl(); -extern "C" void -set__13dPa_control_cFUcUsPC4cXyzPC12dKy_tevstr_cPC5csXyzPC4cXyzUcP18dPa_levelEcallBackScPC8_GXColorPC8_GXColorPC4cXyzf(); -extern "C" void -set__13dPa_control_cFUlUcUsPC4cXyzPC12dKy_tevstr_cPC5csXyzPC4cXyzUcP18dPa_levelEcallBackScPC8_GXColorPC8_GXColorPC4cXyzf(); -extern "C" void LockonTarget__12dAttention_cFl(); -extern "C" void LockonTruth__12dAttention_cFv(); -extern "C" void LineCross__4cBgSFP11cBgS_LinChk(); -extern "C" void __ct__11dBgS_LinChkFv(); -extern "C" void __dt__11dBgS_LinChkFv(); -extern "C" void Set__11dBgS_LinChkFPC4cXyzPC4cXyzPC10fopAc_ac_c(); -extern "C" void __ct__10dCcD_GSttsFv(); -extern "C" void Init__9dCcD_SttsFiiP10fopAc_ac_c(); -extern "C" void __ct__12dCcD_GObjInfFv(); -extern "C" void ChkAtHit__12dCcD_GObjInfFv(); -extern "C" void ChkTgHit__12dCcD_GObjInfFv(); -extern "C" void Set__8dCcD_SphFRC11dCcD_SrcSph(); -extern "C" void StartCAt__8dCcD_SphFR4cXyz(); -extern "C" void MoveCAt__8dCcD_SphFR4cXyz(); -extern "C" void settingTevStruct__18dScnKy_env_light_cFiP4cXyzP12dKy_tevstr_c(); -extern "C" void setLightTevColorType_MAJI__18dScnKy_env_light_cFP12J3DModelDataP12dKy_tevstr_c(); -extern "C" void Set__4cCcSFP8cCcD_Obj(); -extern "C" void __pl__4cXyzCFRC3Vec(); -extern "C" void __mi__4cXyzCFRC3Vec(); -extern "C" void cM_atan2s__Fff(); -extern "C" void cM_rndFX__Ff(); -extern "C" void SetC__8cM3dGSphFRC4cXyz(); -extern "C" void MtxPosition__FP4cXyzP4cXyz(); -extern "C" void deleteObject__14Z2SoundObjBaseFv(); -extern "C" void __ct__16Z2SoundObjSimpleFv(); -extern "C" void __dl__FPv(); -extern "C" void _savegpr_24(); -extern "C" void _savegpr_25(); -extern "C" void _savegpr_26(); -extern "C" void _restgpr_24(); -extern "C" void _restgpr_25(); -extern "C" void _restgpr_26(); -extern "C" extern void* __vt__8dCcD_Sph[36]; -extern "C" extern void* __vt__9dCcD_Stts[11]; -extern "C" extern void* __vt__12cCcD_SphAttr[25]; -extern "C" extern void* __vt__14cCcD_ShapeAttr[22]; -extern "C" extern void* __vt__9cCcD_Stts[8]; -extern "C" u8 now__14mDoMtx_stack_c[48]; -extern "C" extern u8 g_dComIfG_gameInfo[122384]; -extern "C" u8 sincosTable___5JMath[65536]; -extern "C" extern void* calc_mtx[1 + 1 /* padding */]; -extern "C" u8 mParticleTracePCB__13dPa_control_c[4 + 4 /* padding */]; - -// -// Declarations: -// +enum Type { + /* 0x00 */ TYPE_TK_BALL_WATER, // Water Toadpoli Ball + /* 0x01 */ TYPE_TK_BALL_FIRE, // Fire Toadpoli Ball + /* 0xFF */ TYPE_TK_BALL_UNK = 0xFF, +}; /* 807BBFF8-807BC070 000078 0078+00 1/0 0/0 0/0 .text daE_TK_BALL_Draw__FP15e_tk_ball_class */ -static void daE_TK_BALL_Draw(e_tk_ball_class* param_0) { - // NONMATCHING +static int daE_TK_BALL_Draw(e_tk_ball_class* i_this) { + if (i_this->mSuspended) { + return 1; + } + + g_env_light.settingTevStruct(0, &i_this->current.pos, &i_this->tevStr); + g_env_light.setLightTevColorType_MAJI(i_this->mpModel, &i_this->tevStr); + mDoExt_modelUpdateDL(i_this->mpModel); + return 1; } -/* ############################################################################################## */ -/* 807BD56C-807BD570 000000 0004+00 4/4 0/0 0/0 .rodata @3710 */ -SECTION_RODATA static u8 const lit_3710[4] = { - 0x00, - 0x00, - 0x00, - 0x00, -}; -COMPILER_STRIP_GATE(0x807BD56C, &lit_3710); - -/* 807BD570-807BD574 000004 0004+00 0/1 0/0 0/0 .rodata @3711 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3711 = 30.0f; -COMPILER_STRIP_GATE(0x807BD570, &lit_3711); -#pragma pop - -/* 807BD574-807BD578 000008 0004+00 1/2 0/0 0/0 .rodata @3712 */ -SECTION_RODATA static f32 const lit_3712 = -50.0f; -COMPILER_STRIP_GATE(0x807BD574, &lit_3712); - -/* 807BD578-807BD57C 00000C 0004+00 0/1 0/0 0/0 .rodata @3713 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3713 = -30.0f; -COMPILER_STRIP_GATE(0x807BD578, &lit_3713); -#pragma pop - -/* 807BD57C-807BD580 000010 0004+00 0/2 0/0 0/0 .rodata @3714 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3714 = 50.0f; -COMPILER_STRIP_GATE(0x807BD57C, &lit_3714); -#pragma pop - /* 807BC070-807BC1CC 0000F0 015C+00 3/3 0/0 0/0 .text simple_bg_check__FP15e_tk_ball_class */ -static void simple_bg_check(e_tk_ball_class* param_0) { - // NONMATCHING +static int simple_bg_check(e_tk_ball_class* i_this) { + fopAc_ac_c* actor = i_this; + + cXyz current_pos = actor->current.pos; + current_pos.y += i_this->mArcHeight; + cMtx_YrotS(*calc_mtx, actor->current.angle.y); + + cXyz start_pos; + cXyz end_pos; + cXyz ray_offset(0.0f, 30.0f, -50.0f); + + cXyz mtx_offset; + MtxPosition(&ray_offset, &mtx_offset); + start_pos = current_pos + mtx_offset; + + ray_offset.y = -30.0f; + ray_offset.z = 50.0f; + MtxPosition(&ray_offset, &mtx_offset); + end_pos = current_pos + mtx_offset; + + dBgS_LinChk line_check; + line_check.Set(&start_pos, &end_pos, actor); + if (dComIfG_Bgsp().LineCross(&line_check)) { + return 1; + } else { + return 0; + } } -/* ############################################################################################## */ -/* 807BD580-807BD584 000014 0004+00 3/4 0/0 0/0 .rodata @3763 */ -SECTION_RODATA static f32 const lit_3763 = 2.0f; -COMPILER_STRIP_GATE(0x807BD580, &lit_3763); - -/* 807BD584-807BD588 000018 0004+00 1/2 0/0 0/0 .rodata @3764 */ -SECTION_RODATA static f32 const lit_3764 = 1.0f; -COMPILER_STRIP_GATE(0x807BD584, &lit_3764); - /* 807BC1CC-807BC3F8 00024C 022C+00 3/3 0/0 0/0 .text impact_eff_set__FP15e_tk_ball_class */ -static void impact_eff_set(e_tk_ball_class* param_0) { - // NONMATCHING +static void impact_eff_set(e_tk_ball_class* i_this) { + cXyz pos = i_this->current.pos; + pos.y += i_this->mArcHeight; + + cXyz scale(2.0f, 2.0f, 2.0f); + + csXyz rotation = i_this->current.angle; + rotation.y -= 0x8000; + + if (i_this->mType == TYPE_TK_BALL_WATER) { + dComIfGp_particle_set(0x819B, &pos, &rotation, &scale); + dComIfGp_particle_set(0x819C, &pos, &rotation, &scale); + i_this->mSound.startSound(Z2SE_EN_TK_HIT, 0, -1); + } else { + dComIfGp_particle_set(0x8198, &pos, &rotation, &scale); + dComIfGp_particle_set(0x8199, &pos, &rotation, &scale); + i_this->mSound.startSound(Z2SE_EN_TK2_HIT, 0, -1); + } } -/* ############################################################################################## */ -/* 807BD588-807BD58C 00001C 0004+00 0/1 0/0 0/0 .rodata @3923 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3923 = -20.0f; -COMPILER_STRIP_GATE(0x807BD588, &lit_3923); -#pragma pop - -/* 807BD58C-807BD594 000020 0008+00 0/2 0/0 0/0 .rodata @3924 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3924[8] = { - 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x807BD58C, &lit_3924); -#pragma pop - -/* 807BD594-807BD59C 000028 0008+00 0/2 0/0 0/0 .rodata @3925 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3925[8] = { - 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x807BD594, &lit_3925); -#pragma pop - -/* 807BD59C-807BD5A4 000030 0008+00 0/2 0/0 0/0 .rodata @3926 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3926[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x807BD59C, &lit_3926); -#pragma pop - -/* 807BD5A4-807BD5A8 000038 0004+00 0/1 0/0 0/0 .rodata @3927 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3927 = 10.0f; -COMPILER_STRIP_GATE(0x807BD5A4, &lit_3927); -#pragma pop - -/* 807BD5A8-807BD5AC 00003C 0004+00 0/1 0/0 0/0 .rodata @3928 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3928 = -3.0f / 10.0f; -COMPILER_STRIP_GATE(0x807BD5A8, &lit_3928); -#pragma pop - -/* 807BD5AC-807BD5B0 000040 0004+00 0/1 0/0 0/0 .rodata @3929 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3929 = 60.0f; -COMPILER_STRIP_GATE(0x807BD5AC, &lit_3929); -#pragma pop - /* 807BC3F8-807BCA18 000478 0620+00 1/1 0/0 0/0 .text e_tk_ball_move__FP15e_tk_ball_class */ -static void e_tk_ball_move(e_tk_ball_class* param_0) { - // NONMATCHING +static void e_tk_ball_move(e_tk_ball_class* i_this) { + fopAc_ac_c* actor = i_this; + fopAc_ac_c* player = dComIfGp_getPlayer(0); + + cXyz direction_vec; + cXyz speed_vec; + cXyz target_center; + + switch (i_this->mMode) { + case MODE_TK_BALL_INIT: + i_this->mMode = MODE_TK_BALL_MOVE; + i_this->mInitalPosition = actor->current.pos; + direction_vec = player->eyePos; + direction_vec.y += -20.0f; + direction_vec -= i_this->mInitalPosition; + + i_this->mInitalDistance = direction_vec.abs(); + if (i_this->mInitalDistance < 10.0f) { + i_this->mInitalDistance = 10.0f; + } + actor->current.angle.y = cM_atan2s(direction_vec.x, direction_vec.z); + actor->current.angle.x = + -cM_atan2s(direction_vec.y, JMAFastSqrt(direction_vec.x * direction_vec.x + + direction_vec.z * direction_vec.z)); + cMtx_YrotS(*calc_mtx, actor->current.angle.y); + cMtx_XrotM(*calc_mtx, actor->current.angle.x); + + direction_vec.set(0.0f, 0.0f, 50.0f); + MtxPosition(&direction_vec, &actor->speed); + + i_this->mAtSph.OnAtVsPlayerBit(); + i_this->mAtSph.OffAtVsEnemyBit(); + i_this->mAtSph.StartCAt(actor->current.pos); + i_this->mActionTimer[0] = 100; + /* [[fallthrough]] */ + + case MODE_TK_BALL_MOVE: + actor->current.pos += actor->speed; + break; + } + + target_center = actor->current.pos; + target_center.y += i_this->mArcHeight; + i_this->mTgSph.SetC(target_center); + dComIfG_Ccsp()->Set(&i_this->mTgSph); + + s8 actor_lockon = false; + fopAc_ac_c* parent_actor = fopAcM_SearchByID(actor->parentActorID); + if (parent_actor != NULL) { + dAttention_c* attention = &dComIfGp_getAttention(); + if (attention->Lockon() && parent_actor == attention->LockonTarget(0)) { + actor_lockon = true; + parent_actor->attention_info.flags |= 0x200000; + } + } + if (i_this->mTgSph.ChkTgHit() || i_this->mAtSph.ChkAtShieldHit()) { + impact_eff_set(i_this); + actor->current.angle.x *= -1; + if (actor_lockon && daPy_getPlayerActorClass()->getCutType() != 0x00) { + i_this->mAction = ACT_TK_BALL_RETURN; + i_this->mMode = MODE_TK_BALL_INIT; + actor->current.angle.y -= 0x8000; + } else { + i_this->mAction = ACT_TK_BALL_DROP; + i_this->mMode = MODE_TK_BALL_INIT; + actor->speed.x *= -0.3f; + actor->speed.z *= -0.3f; + actor->speed.y = 0.0f; + actor->current.pos += actor->speed; + i_this->mActionTimer[0] = 60; + return; + } + + actor->current.pos.y += i_this->mArcHeight; + actor->home.pos = actor->current.pos; + direction_vec = i_this->mInitalPosition - actor->home.pos; + i_this->mInitalDistance = direction_vec.abs(); + speed_vec.x = 0.0; + speed_vec.y = 0.0; + if (daPy_getPlayerActorClass()->getCutType() != 0x00) { + speed_vec.z = 60.0f; + } + cMtx_YrotS(*calc_mtx, actor->current.angle.y); + cMtx_XrotM(*calc_mtx, actor->current.angle.x); + MtxPosition(&speed_vec, &actor->speed); + i_this->mAtSph.OffAtVsPlayerBit(); + i_this->mAtSph.OnAtVsEnemyBit(); + i_this->mActionTimer[0] = 100; + i_this->mActionTimer[1] = 10; + actor->current.pos += actor->speed; + } else { + i_this->mAtSph.MoveCAt(actor->current.pos); + dComIfG_Ccsp()->Set(&i_this->mAtSph); + + if (simple_bg_check(i_this) || i_this->mAtSph.ChkAtHit()) { + impact_eff_set(i_this); + fopAcM_delete(actor); + } + } } /* 807BCA18-807BCAF4 000A98 00DC+00 1/1 0/0 0/0 .text e_tk_ball_return__FP15e_tk_ball_class */ -static void e_tk_ball_return(e_tk_ball_class* param_0) { - // NONMATCHING +static void e_tk_ball_return(e_tk_ball_class* i_this) { + switch (i_this->mMode) { + case MODE_TK_BALL_INIT: + i_this->current.pos += i_this->speed; + if (i_this->mActionTimer[1] == 0) { + i_this->mTgSph.SetTgHitMark(CcG_Tg_UNK_MARK_0); + } + break; + } + + cXyz new_center = i_this->current.pos; + new_center.y += i_this->mArcHeight; + i_this->mAtSph.MoveCAt(new_center); + dComIfG_Ccsp()->Set(&i_this->mAtSph); + + if (i_this->mActionTimer[1] == 0 && (simple_bg_check(i_this) || i_this->mAtSph.ChkAtHit())) { + impact_eff_set(i_this); + fopAcM_delete(i_this); + } } /* 807BCAF4-807BCB94 000B74 00A0+00 1/1 0/0 0/0 .text e_tk_ball_drop__FP15e_tk_ball_class */ -static void e_tk_ball_drop(e_tk_ball_class* param_0) { - // NONMATCHING +static void e_tk_ball_drop(e_tk_ball_class* i_this) { + switch (i_this->mMode) { + case MODE_TK_BALL_INIT: + i_this->current.pos += i_this->speed; + i_this->speed.y -= 2.0f; + if (i_this->speed.y < -50.0f) { + i_this->speed.y = -50.0f; + } + break; + } + + if (simple_bg_check(i_this) || i_this->mActionTimer[0] == 0) { + impact_eff_set(i_this); + fopAcM_delete(i_this); + } } -/* ############################################################################################## */ -/* 807BD5B0-807BD5B4 000044 0004+00 0/1 0/0 0/0 .rodata @4115 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4115 = 1.0f / 10.0f; -COMPILER_STRIP_GATE(0x807BD5B0, &lit_4115); -#pragma pop - -/* 807BD5B4-807BD5B8 000048 0004+00 0/1 0/0 0/0 .rodata @4116 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4116 = 300.0f; -COMPILER_STRIP_GATE(0x807BD5B4, &lit_4116); -#pragma pop - -/* 807BD5B8-807BD5BC 00004C 0004+00 1/2 0/0 0/0 .rodata @4117 */ -SECTION_RODATA static f32 const lit_4117 = 32768.0f; -COMPILER_STRIP_GATE(0x807BD5B8, &lit_4117); - -/* 807BD5BC-807BD5C0 000050 0004+00 0/1 0/0 0/0 .rodata @4118 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4118 = 1.5f; -COMPILER_STRIP_GATE(0x807BD5BC, &lit_4118); -#pragma pop - -/* 807BD5C0-807BD5C4 000054 0004+00 0/1 0/0 0/0 .rodata @4119 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4119 = 4.0f / 5.0f; -COMPILER_STRIP_GATE(0x807BD5C0, &lit_4119); -#pragma pop - -/* 807BD5D0-807BD5D8 000000 0006+02 1/1 0/0 0/0 .data e_id$3988 */ -SECTION_DATA static u8 e_id[6 + 2 /* padding */] = { - 0x81, - 0x9D, - 0x81, - 0x9E, - 0x81, - 0x9A, - /* padding */ - 0x00, - 0x00, -}; - /* 807BCB94-807BCF84 000C14 03F0+00 1/1 0/0 0/0 .text action__FP15e_tk_ball_class */ -static void action(e_tk_ball_class* param_0) { - // NONMATCHING +static void action(e_tk_ball_class* i_this) { + fopAc_ac_c* actor = i_this; + + static u16 e_id[4] = {0x819D, 0x819E, 0x819A, 0x0000}; + + s8 is_moving = true; + switch (i_this->mAction) { + case ACT_TK_BALL_MOVE: + e_tk_ball_move(i_this); + break; + case ACT_TK_BALL_RETURN: + e_tk_ball_return(i_this); + break; + case ACT_TK_BALL_DROP: + e_tk_ball_drop(i_this); + is_moving = false; + break; + } + + if (is_moving) { + cXyz position_diff = actor->home.pos - actor->current.pos; + f32 pos_diff_abs = position_diff.abs(); + f32 height_scale = i_this->mInitalDistance * 0.1f; + if (height_scale > 300.0f) { + height_scale = 300.0f; + } + i_this->mArcHeight = + height_scale * cM_ssin((pos_diff_abs / i_this->mInitalDistance) * 32768.0f); + if (pos_diff_abs > i_this->mInitalDistance * 1.5f) { + fopAcM_delete(actor); + } + } else { + i_this->mArcHeight = 0.0f; + } + + cXyz particle_position = actor->current.pos; + particle_position.y += i_this->mArcHeight; + + cXyz particle_scale(2.0f, 2.0f, 2.0f); + + for (int i = 0; i < 2; i++) { + i_this->mParticleKey[i] = dComIfGp_particle_set( + i_this->mParticleKey[i], e_id[i + i_this->mType * 2], &particle_position, NULL, NULL); + + JPABaseEmitter* particle_emitter = dComIfGp_particle_getEmitter(i_this->mParticleKey[i]); + if (particle_emitter != NULL) { + particle_emitter->setGlobalScale(particle_scale); + if (i_this->mType == TYPE_TK_BALL_FIRE) { + particle_emitter->setParticleCallBackPtr(dPa_control_c::getParticleTracePCB()); + i_this->mParticleDirection = particle_position - i_this->mPreviousPosition; + i_this->mParticleDirection *= 0.8f; + particle_emitter->setUserWork((u32)&i_this->mParticleDirection); + i_this->mPreviousPosition = particle_position; + break; + } + } + } + + if (i_this->mType == TYPE_TK_BALL_FIRE) { + i_this->mSound.startLevelSound(Z2SE_EN_TK2_SHOT, 0, -1); + } else { + i_this->mSound.startLevelSound(Z2SE_EN_TK_SHOT, 0, -1); + } } /* 807BCF84-807BD0C0 001004 013C+00 2/1 0/0 0/0 .text daE_TK_BALL_Execute__FP15e_tk_ball_class */ -static void daE_TK_BALL_Execute(e_tk_ball_class* param_0) { - // NONMATCHING +static int daE_TK_BALL_Execute(e_tk_ball_class* i_this) { + if (i_this->mSuspended) { + return 1; + } + + i_this->mLifetime++; + for (int i = 0; i < 2; i++) { + if (i_this->mActionTimer[i] != 0) { + i_this->mActionTimer[i]--; + } + } + if (i_this->mInvincibilityTimer != 0) { + i_this->mInvincibilityTimer--; + } + + action(i_this); + + i_this->shape_angle.y += 0x1000; + i_this->shape_angle.x += 0xE00; + + mDoMtx_stack_c::transS(i_this->current.pos.x, i_this->current.pos.y + i_this->mArcHeight, + i_this->current.pos.z); + mDoMtx_stack_c::YrotM(i_this->shape_angle.y); + mDoMtx_stack_c::XrotM(i_this->shape_angle.x); + mDoMtx_stack_c::scaleM(2.0f, 2.0f, 2.0f); + i_this->mpModel->setBaseTRMtx(mDoMtx_stack_c::get()); + + i_this->mSound.framework(0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this))); + return 1; } /* 807BD0C0-807BD0C8 001140 0008+00 1/0 0/0 0/0 .text daE_TK_BALL_IsDelete__FP15e_tk_ball_class */ -static bool daE_TK_BALL_IsDelete(e_tk_ball_class* param_0) { - return true; +static int daE_TK_BALL_IsDelete(e_tk_ball_class* i_this) { + return 1; } -/* ############################################################################################## */ -/* 807BD5C4-807BD5C4 000058 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */ -#pragma push -#pragma force_active on -SECTION_DEAD static char const* const stringBase_807BD5C4 = "E_tk"; -SECTION_DEAD static char const* const stringBase_807BD5C9 = "E_tk2"; -#pragma pop - /* 807BD0C8-807BD13C 001148 0074+00 1/0 0/0 0/0 .text daE_TK_BALL_Delete__FP15e_tk_ball_class */ -static void daE_TK_BALL_Delete(e_tk_ball_class* param_0) { - // NONMATCHING +static int daE_TK_BALL_Delete(e_tk_ball_class* i_this) { + if (i_this->mType == TYPE_TK_BALL_WATER) { + dComIfG_resDelete(&i_this->mPhaseReq, "E_tk"); + } else { + dComIfG_resDelete(&i_this->mPhaseReq, "E_tk2"); + } + if (i_this->heap != NULL) { + i_this->mSound.deleteObject(); + } + return 1; } /* 807BD13C-807BD1EC 0011BC 00B0+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */ -static void useHeapInit(fopAc_ac_c* param_0) { - // NONMATCHING +static int useHeapInit(fopAc_ac_c* i_this) { + e_tk_ball_class* a_this = static_cast(i_this); + J3DModelData* ball_model; + + if (a_this->mType == TYPE_TK_BALL_WATER) { + ball_model = (J3DModelData*)dComIfG_getObjectRes("E_tk", 0xD); + } else { + ball_model = (J3DModelData*)dComIfG_getObjectRes("E_tk2", 0xD); + } + a_this->mpModel = mDoExt_J3DModel__create(ball_model, 0x80000, 0x11000084); + + if (a_this->mpModel == NULL) { + return 0; + } else { + return 1; + } } -/* ############################################################################################## */ -/* 807BD5D8-807BD618 000008 0040+00 1/1 0/0 0/0 .data at_sph_src$4199 */ -static dCcD_SrcSph at_sph_src = { - { - {0x0, {{AT_TYPE_CSTATUE_SWING, 0x1, 0xd}, {0x0, 0x0}, 0x0}}, // mObj - {dCcD_SE_METAL, 0x1, 0x0, 0x0, 0x0}, // mGObjAt - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg - {0x0}, // mGObjCo - }, // mObjInf - { - {{0.0f, 0.0f, 0.0f}, 20.0f} // mSph - } // mSphAttr -}; +/* 807BD1EC-807BD4D4 00126C 02E8+00 1/0 0/0 0/0 .text daE_TK_BALL_Create__FP10fopAc_ac_c + */ +static int daE_TK_BALL_Create(fopAc_ac_c* i_this) { + static dCcD_SrcSph at_sph_src = { + { + {0x0, {{AT_TYPE_CSTATUE_SWING, 0x1, 0xd}, {0x0, 0x0}, 0x0}}, // mObj + {dCcD_SE_METAL, 0x1, 0x0, 0x0, 0x0}, // mGObjAt + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg + {0x0}, // mGObjCo + }, // mObjInf + { + {{0.0f, 0.0f, 0.0f}, 20.0f} // mSph + } // mSphAttr + }; -/* 807BD618-807BD658 000048 0040+00 1/1 0/0 0/0 .data tg_sph_src$4200 */ -static dCcD_SrcSph tg_sph_src = { - { - {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt - {dCcD_SE_METAL, 0x5, 0x0, 0x0, 0x2}, // mGObjTg - {0x0}, // mGObjCo - }, // mObjInf - { - {{0.0f, 0.0f, 0.0f}, 35.0f} // mSph - } // mSphAttr -}; + static dCcD_SrcSph tg_sph_src = { + { + {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt + {dCcD_SE_METAL, 0x5, 0x0, 0x0, 0x2}, // mGObjTg + {0x0}, // mGObjCo + }, // mObjInf + { + {{0.0f, 0.0f, 0.0f}, 35.0f} // mSph + } // mSphAttr + }; + + fopAcM_SetupActor(i_this, e_tk_ball_class); + e_tk_ball_class* a_this = static_cast(i_this); + + a_this->mType = fopAcM_GetParam(a_this); + if (a_this->mType == TYPE_TK_BALL_UNK) { + a_this->mType = TYPE_TK_BALL_WATER; + } + + cPhs__Step phase; + u32 size; + if (a_this->mType == TYPE_TK_BALL_WATER) { + phase = (cPhs__Step)dComIfG_resLoad(&a_this->mPhaseReq, "E_tk"); + size = 0x820; + } else { + phase = (cPhs__Step)dComIfG_resLoad(&a_this->mPhaseReq, "E_tk2"); + size = 0xEE0; + } + + if (phase == cPhs_COMPLEATE_e) { + a_this->mArg1 = fopAcM_GetParamBit(i_this, 8, 8); + if (a_this->mArg1 == 0xff) { + a_this->mArg1 = 0x00; + } + + if (!fopAcM_entrySolidHeap(i_this, useHeapInit, size)) { + return cPhs_ERROR_e; + } + fopAcM_SetMtx(a_this, a_this->mpModel->getBaseTRMtx()); + a_this->mStts.Init(0xff, 0, a_this); + a_this->mAtSph.Set(at_sph_src); + a_this->mAtSph.SetStts(&a_this->mStts); + if (a_this->mType == TYPE_TK_BALL_FIRE) { + a_this->mAtSph.SetAtType(AT_TYPE_100); + a_this->mAtSph.SetAtMtrl(dCcD_MTRL_FIRE); + } + + a_this->mTgSph.Set(tg_sph_src); + a_this->mTgSph.SetStts(&a_this->mStts); + + a_this->mSound.init(&a_this->current.pos, 1); + a_this->shape_angle.y = cM_rndFX(32768.0f); + a_this->shape_angle.x = cM_rndFX(32768.0f); + a_this->mSuspended = true; + + mDoMtx_stack_c::scaleS(0.0f, 0.0f, 0.0f); + a_this->mpModel->setBaseTRMtx(mDoMtx_stack_c::get()); + daE_TK_BALL_Execute(a_this); + } + return phase; +} /* 807BD658-807BD678 -00001 0020+00 1/0 0/0 0/0 .data l_daE_TK_BALL_Method */ static actor_method_class l_daE_TK_BALL_Method = { - (process_method_func)daE_TK_BALL_Create__FP10fopAc_ac_c, - (process_method_func)daE_TK_BALL_Delete__FP15e_tk_ball_class, - (process_method_func)daE_TK_BALL_Execute__FP15e_tk_ball_class, - (process_method_func)daE_TK_BALL_IsDelete__FP15e_tk_ball_class, - (process_method_func)daE_TK_BALL_Draw__FP15e_tk_ball_class, + (process_method_func)daE_TK_BALL_Create, (process_method_func)daE_TK_BALL_Delete, + (process_method_func)daE_TK_BALL_Execute, (process_method_func)daE_TK_BALL_IsDelete, + (process_method_func)daE_TK_BALL_Draw, }; /* 807BD678-807BD6A8 -00001 0030+00 0/0 0/0 1/0 .data g_profile_E_TK_BALL */ extern actor_process_profile_definition g_profile_E_TK_BALL = { - fpcLy_CURRENT_e, // mLayerID - 7, // mListID - fpcPi_CURRENT_e, // mListPrio - PROC_E_TK_BALL, // mProcName - &g_fpcLf_Method.base, // sub_method - sizeof(e_tk_ball_class), // mSize - 0, // mSizeOther - 0, // mParameters - &g_fopAc_Method.base, // sub_method - 151, // mPriority - &l_daE_TK_BALL_Method, // sub_method - 0x00040120, // mStatus - fopAc_ACTOR_e, // mActorType - fopAc_CULLBOX_0_e, // cullType + fpcLy_CURRENT_e, // mLayerID + 7, // mListID + fpcPi_CURRENT_e, // mListPrio + PROC_E_TK_BALL, // mProcName + &g_fpcLf_Method.base, // sub_method + sizeof(e_tk_ball_class), // mSize + 0, // mSizeOther + 0, // mParameters + &g_fopAc_Method.base, // sub_method + 151, // mPriority + &l_daE_TK_BALL_Method, // sub_method + 0x00040120, // mStatus + fopAc_ACTOR_e, // mActorType + fopAc_CULLBOX_0_e, // cullType }; - -/* 807BD6A8-807BD6B4 0000D8 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGSph */ -SECTION_DATA extern void* __vt__8cM3dGSph[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGSphFv, -}; - -/* 807BD6B4-807BD6C0 0000E4 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGAab */ -SECTION_DATA extern void* __vt__8cM3dGAab[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGAabFv, -}; - -/* 807BD1EC-807BD4D4 00126C 02E8+00 1/0 0/0 0/0 .text daE_TK_BALL_Create__FP10fopAc_ac_c - */ -static void daE_TK_BALL_Create(fopAc_ac_c* param_0) { - // NONMATCHING -} - -/* 807BD4D4-807BD51C 001554 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGSphFv */ -// cM3dGSph::~cM3dGSph() { -extern "C" void __dt__8cM3dGSphFv() { - // NONMATCHING -} - -/* 807BD51C-807BD564 00159C 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGAabFv */ -// cM3dGAab::~cM3dGAab() { -extern "C" void __dt__8cM3dGAabFv() { - // NONMATCHING -} - -/* 807BD5C4-807BD5C4 000058 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */