diff --git a/config/SOUE01/rels/d_a_girahimu_sword_beamNP/symbols.txt b/config/SOUE01/rels/d_a_girahimu_sword_beamNP/symbols.txt index 5725bf77..7131775a 100644 --- a/config/SOUE01/rels/d_a_girahimu_sword_beamNP/symbols.txt +++ b/config/SOUE01/rels/d_a_girahimu_sword_beamNP/symbols.txt @@ -4,36 +4,36 @@ _unresolved = .text:0x00000060; // type:function size:0x4 scope:global __register_global_object = .text:0x00000070; // type:function size:0x1C scope:global __destroy_global_chain = .text:0x00000090; // type:function size:0x54 scope:global dAcGirahimuSwordBeam_c_classInit__Fv = .text:0x000000F0; // type:function size:0x15C -fn_240_250 = .text:0x00000250; // type:function size:0x58 -fn_240_2B0 = .text:0x000002B0; // type:function size:0x90 +__dt__15dShadowCircle_cFv = .text:0x00000250; // type:function size:0x58 +__dt__22dCcD_Linked<8dCcD_Cps>Fv = .text:0x000002B0; // type:function size:0x90 __dt__35sFState_c<22dAcGirahimuSwordBeam_c>Fv = .text:0x00000340; // type:function size:0x58 __dt__38sFStateFct_c<22dAcGirahimuSwordBeam_c>Fv = .text:0x000003A0; // type:function size:0x6C __dt__91sStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000410; // type:function size:0xA0 __dt__61sFStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c>Fv = .text:0x000004B0; // type:function size:0xA4 -fn_240_560 = .text:0x00000560; // type:function size:0x8 -fn_240_570 = .text:0x00000570; // type:function size:0x1EC +createHeap__22dAcGirahimuSwordBeam_cFv = .text:0x00000560; // type:function size:0x8 +create__22dAcGirahimuSwordBeam_cFv = .text:0x00000570; // type:function size:0x1EC changeState__91sStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000760; // type:function size:0x10 -fn_240_770 = .text:0x00000770; // type:function size:0x8 -fn_240_780 = .text:0x00000780; // type:function size:0x5A4 +doDelete__22dAcGirahimuSwordBeam_cFv = .text:0x00000770; // type:function size:0x8 +actorExecute__22dAcGirahimuSwordBeam_cFv = .text:0x00000780; // type:function size:0x5A4 executeState__91sStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000D30; // type:function size:0x10 getStateID__91sStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00000D40; // type:function size:0x10 -fn_240_D50 = .text:0x00000D50; // type:function size:0x8C +draw__22dAcGirahimuSwordBeam_cFv = .text:0x00000D50; // type:function size:0x8C initializeState_BulletMove__22dAcGirahimuSwordBeam_cFv = .text:0x00000DE0; // type:function size:0xA8 executeState_BulletMove__22dAcGirahimuSwordBeam_cFv = .text:0x00000E90; // type:function size:0x10C finalizeState_BulletMove__22dAcGirahimuSwordBeam_cFv = .text:0x00000FA0; // type:function size:0x4 initializeState_Damage__22dAcGirahimuSwordBeam_cFv = .text:0x00000FB0; // type:function size:0x28 executeState_Damage__22dAcGirahimuSwordBeam_cFv = .text:0x00000FE0; // type:function size:0x4 finalizeState_Damage__22dAcGirahimuSwordBeam_cFv = .text:0x00000FF0; // type:function size:0x4 -fn_240_1000 = .text:0x00001000; // type:function size:0xC0 -fn_240_10C0 = .text:0x000010C0; // type:function size:0x6C -fn_240_1130 = .text:0x00001130; // type:function size:0x24 -fn_240_1160 = .text:0x00001160; // type:function size:0x8C -fn_240_11F0 = .text:0x000011F0; // type:function size:0x18C -fn_240_1380 = .text:0x00001380; // type:function size:0x338 -fn_240_16C0 = .text:0x000016C0; // type:function size:0x44 -fn_240_1710 = .text:0x00001710; // type:function size:0xA8 -fn_240_17C0 = .text:0x000017C0; // type:function size:0x44 -fn_240_1810 = .text:0x00001810; // type:function size:0xD0C +swordBeamReturn__22dAcGirahimuSwordBeam_cFl = .text:0x00001000; // type:function size:0xC0 +startMoveEmitters__22dAcGirahimuSwordBeam_cFv = .text:0x000010C0; // type:function size:0x6C +startDisappearEmitter__22dAcGirahimuSwordBeam_cFv = .text:0x00001130; // type:function size:0x24 +transformMatrix__22dAcGirahimuSwordBeam_cFv = .text:0x00001160; // type:function size:0x8C +fn_240_11F0__22dAcGirahimuSwordBeam_cFv = .text:0x000011F0; // type:function size:0x18C +fn_240_1380__22dAcGirahimuSwordBeam_cFv = .text:0x00001380; // type:function size:0x338 +fn_240_16C0__22dAcGirahimuSwordBeam_cFv = .text:0x000016C0; // type:function size:0x44 +fn_240_1710__22dAcGirahimuSwordBeam_cFv = .text:0x00001710; // type:function size:0xA8 +fn_240_17C0__22dAcGirahimuSwordBeam_cFl = .text:0x000017C0; // type:function size:0x44 +fn_240_1810__22dAcGirahimuSwordBeam_cFUlR7mAng3_cRC4mAng = .text:0x00001810; // type:function size:0xD0C __dt__22dAcGirahimuSwordBeam_cFv = .text:0x00002520; // type:function size:0x1A4 build__38sFStateFct_c<22dAcGirahimuSwordBeam_c>FRC12sStateIDIf_c = .text:0x000026D0; // type:function size:0x60 dispose__38sFStateFct_c<22dAcGirahimuSwordBeam_c>FRP10sStateIf_c = .text:0x00002730; // type:function size:0xC @@ -52,7 +52,7 @@ initializeState__37sFStateID_c<22dAcGirahimuSwordBeam_c>CFR22dAcGirahimuSwordBea __sinit_\d_a_girahimu_sword_beam_cpp = .text:0x00002890; // type:function size:0x1C8 scope:local __dt__37sFStateID_c<22dAcGirahimuSwordBeam_c>Fv = .text:0x00002A60; // type:function size:0x58 isSameName__37sFStateID_c<22dAcGirahimuSwordBeam_c>CFPCc = .text:0x00002AC0; // type:function size:0x88 -fn_240_2B50 = .text:0x00002B50; // type:function size:0x8 +@272@__dt__22dCcD_Linked<8dCcD_Cps>Fv = .text:0x00002B50; // type:function size:0x8 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global @@ -69,16 +69,16 @@ lbl_240_data_9C = .data:0x0000009C; // type:object size:0x4 data:4byte lbl_240_data_A0 = .data:0x000000A0; // type:object size:0x4 data:4byte lbl_240_data_A4 = .data:0x000000A4; // type:object size:0x4 data:4byte lbl_240_data_A8 = .data:0x000000A8; // type:object size:0x30 data:4byte -lbl_240_data_D8 = .data:0x000000D8; // type:object size:0x80 -lbl_240_data_158 = .data:0x00000158; // type:object size:0x30 -lbl_240_data_188 = .data:0x00000188; // type:object size:0x30 -lbl_240_data_1B8 = .data:0x000001B8; // type:object size:0x18 -lbl_240_data_1D0 = .data:0x000001D0; // type:object size:0x18 -lbl_240_data_1E8 = .data:0x000001E8; // type:object size:0x70 -lbl_240_data_258 = .data:0x00000258; // type:object size:0xA8 +__vt__22dAcGirahimuSwordBeam_c = .data:0x000000D8; // type:object size:0x80 +__vt__61sFStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c> = .data:0x00000158; // type:object size:0x30 +__vt__91sStateMgr_c<22dAcGirahimuSwordBeam_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x00000188; // type:object size:0x30 +__vt__38sFStateFct_c<22dAcGirahimuSwordBeam_c> = .data:0x000001B8; // type:object size:0x18 +__vt__35sFState_c<22dAcGirahimuSwordBeam_c> = .data:0x000001D0; // type:object size:0x18 +__vt__22dCcD_Linked<8dCcD_Cps> = .data:0x000001E8; // type:object size:0x70 +__vt__15dShadowCircle_c = .data:0x00000258; // type:object size:0xA8 lbl_240_data_300 = .data:0x00000300; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global lbl_240_bss_8 = .bss:0x00000008; // type:object size:0x10 data:2byte -lbl_240_bss_18 = .bss:0x00000018; // type:object size:0x40 data:4byte -lbl_240_bss_58 = .bss:0x00000058; // type:object size:0x30 data:4byte -lbl_240_bss_88 = .bss:0x00000088; // type:object size:0x2 data:2byte +StateID_BulletMove__22dAcGirahimuSwordBeam_c = .bss:0x00000018; // type:object size:0x30 data:4byte +StateID_Damage__22dAcGirahimuSwordBeam_c = .bss:0x00000058; // type:object size:0x30 data:4byte +sSomeAngle = .bss:0x00000088; // type:object size:0x2 data:2byte diff --git a/include/d/a/d_a_girahimu_sword_beam.h b/include/d/a/d_a_girahimu_sword_beam.h index 7f81614c..f06b621d 100644 --- a/include/d/a/d_a_girahimu_sword_beam.h +++ b/include/d/a/d_a_girahimu_sword_beam.h @@ -1,19 +1,83 @@ #ifndef D_A_GIRAHIMU_SWORD_BEAM_H #define D_A_GIRAHIMU_SWORD_BEAM_H +#include "c/c_lib.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_cc.h" +#include "d/d_shadow.h" +#include "m/m_angle.h" #include "s/s_State.hpp" +#include "toBeSorted/d_emitter.h" class dAcGirahimuSwordBeam_c : public dAcObjBase_c { public: dAcGirahimuSwordBeam_c() : mStateMgr(*this) {} virtual ~dAcGirahimuSwordBeam_c() {} + virtual int create() override; + virtual int doDelete() override; + virtual int draw() override; + virtual bool createHeap() override; + virtual int actorExecute() override; + STATE_FUNC_DECLARE(dAcGirahimuSwordBeam_c, BulletMove); STATE_FUNC_DECLARE(dAcGirahimuSwordBeam_c, Damage); + STATE_MGR_DEFINE_UTIL_CHANGESTATE(dAcGirahimuSwordBeam_c); + STATE_MGR_DEFINE_UTIL_EXECUTESTATE(dAcGirahimuSwordBeam_c); + STATE_MGR_DEFINE_UTIL_ISSTATE(dAcGirahimuSwordBeam_c); + + void swordBeamReturn(s32); + void startMoveEmitters(); + void startDisappearEmitter(); + void transformMatrix(); + void fn_240_11F0(); + void fn_240_1380(); + void fn_240_16C0(); + void fn_240_1710(); + void fn_240_17C0(s32); + void fn_240_1810(u32, mAng3_c &, const mAng &); + + void setB00(s16 x, s16 y, s16 z) { + field_0xB00 = x; + field_0xB02 = y; + field_0xB04 = z; + } + + mAng getLinkedAngle() const { + return (cLib::targetAngleY(mPosition, field_0xAF4.get()->mPosition)); + } + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcGirahimuSwordBeam_c); + /* 0x330 */ dShadowCircle_c mShadow; + /* 0x338 */ dBgS_AcchCir mAcchCir; + /* 0x394 */ dBgS_ObjAcch mAcch; + /* 0x744 */ dCcD_Linked mCps0; + /* 0x8C4 */ dCcD_Linked mCps1; + /* 0xA40 */ dColliderLinkedList mCollider; + /* 0xA50 */ STATE_MGR_DECLARE(dAcGirahimuSwordBeam_c); + /* 0xA8C */ dEmitter_c mEmitter0; + /* 0xAC0 */ dEmitter_c mEmitter1; + /* 0xAF4 */ dAcObjRef_c field_0xAF4; + /* 0xB00 */ s16 field_0xB00; + /* 0xB02 */ s16 field_0xB02; + /* 0xB04 */ s16 field_0xB04; + /* 0xB06 */ s16 field_0xB06; + /* 0xB08 */ s16 field_0xB08; + /* 0xB0A */ s16 field_0xB0A; + /* 0xB0C */ f32 field_0xB0C; + /* 0xB10 */ s32 field_0xB10; + /* 0xB14 */ mAng field_0xB14; + /* 0xB16 */ s16 field_0xB16; + /* 0xB18 */ u16 field_0xB18; + /* 0xB1C */ s32 field_0xB1C; + /* 0xB20 */ s32 field_0xB20; + /* 0xB24 */ u8 field_0xB24; + /* 0xB25 */ u8 field_0xB25; + /* 0xB26 */ u8 field_0xB26; + /* 0xB27 */ u8 field_0xB27; }; #endif diff --git a/src/REL/d/a/d_a_girahimu_sword_beam.cpp b/src/REL/d/a/d_a_girahimu_sword_beam.cpp index e0fecd1b..01033dc6 100644 --- a/src/REL/d/a/d_a_girahimu_sword_beam.cpp +++ b/src/REL/d/a/d_a_girahimu_sword_beam.cpp @@ -1,13 +1,680 @@ #include "d/a/d_a_girahimu_sword_beam.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_cc.h" +#include "d/d_vec.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "m/m_angle.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_sphere.h" +#include "m/m_vec.h" +#include "toBeSorted/d_emitter.h" + SPECIAL_ACTOR_PROFILE(GH_SWORD_BEAM, dAcGirahimuSwordBeam_c, fProfile::GH_SWORD_BEAM, 0x116, 0, 0); STATE_DEFINE(dAcGirahimuSwordBeam_c, BulletMove); STATE_DEFINE(dAcGirahimuSwordBeam_c, Damage); -void dAcGirahimuSwordBeam_c::initializeState_BulletMove() {} -void dAcGirahimuSwordBeam_c::executeState_BulletMove() {} +static dCcD_SrcCps sSrcCps0 = { + { + {AT_TYPE_DAMAGE, 0x1000D, {0, 0, 0}, 4, 0, 0, 0, CUT_DIR_NONE, 0}, + {~(AT_TYPE_COMMON0 | AT_TYPE_DAMAGE), 0x111, {0, 0, 0x407}, 0, CUT_DIR_NONE}, + {0}, + }, + {20.0f}, +}; +static dCcD_SrcCps sSrcCps1 = { + { + {AT_TYPE_DAMAGE, 0x1001D, {0, 0, 0}, 4, 0, 0, 0, CUT_DIR_NONE, 0}, + {(AT_TYPE_0x800000 | AT_TYPE_0x40 | AT_TYPE_SWORD), 0x111, {0, 0, 0x407}, 0, CUT_DIR_NONE}, + {0}, + }, + {50.0f}, +}; + +struct dAcGirahimuSwordBeam_HIO_c { + f32 f0; + f32 f1; + u16 s0; + u16 s1; + + static const dAcGirahimuSwordBeam_HIO_c sInstance; +}; +const dAcGirahimuSwordBeam_HIO_c dAcGirahimuSwordBeam_HIO_c::sInstance = {1.17f, 1.21f, 20, 15}; + +static mAng sSomeAngle = 0; + +bool dAcGirahimuSwordBeam_c::createHeap() { + return true; +} + +int dAcGirahimuSwordBeam_c::create() { + mAngle.y = getXZAngleToPlayer(); + field_0xB1C = getFromParams(0, 0xF); + CREATE_ALLOCATOR(dAcGirahimuSwordBeam_c); + mAcch.Set(this, 1, &mAcchCir); + mAcchCir.SetWall(50.0f, 70.0f); + mStts.SetRank(3); + mCollider.addCc(mCps1, sSrcCps1); + mCollider.addCc(mCps0, sSrcCps0); + mCollider.SetStts(mStts); + + mCps0.ClrTgSet(); + mCps0.ClrCoSet(); + + mCps1.ClrAtSet(); + mCps1.ClrCoSet(); + + mRotation.x = 0; + mRotation.z = 0; + if (field_0xB1C == 0) { + mRotation.z -= 0x4000; + } + transformMatrix(); + mMaxSpeed = -60.0f; + + mEmitter0.init(this); + mEmitter1.init(this); + + field_0xB16 = -1; + field_0xB24 = 0; + field_0xB25 = 0; + + field_0xB00 = 0; + field_0xB02 = 0; + field_0xB04 = 0; + field_0xB26 = 0; + field_0xB27 = 0; + field_0xB18 = 0; + if (field_0xB1C == 1) { + field_0xB0C = 250.0f; + } else { + field_0xB0C = 150.0f; + } + field_0xB06 = 0; + field_0xB08 = 0; + field_0xB0A = 0; + field_0xB10 = 200; + + startSound(SE_BGh3_SW_BEAM_ATTACK); + changeState(StateID_BulletMove); + + return SUCCEEDED; +} + +int dAcGirahimuSwordBeam_c::doDelete() { + return SUCCEEDED; +} + +int dAcGirahimuSwordBeam_c::actorExecute() { + s32 _weird_zero = 0; + holdSound(SE_BGh3_SW_BEAM_LV); + + if (field_0xB20 == 0 && field_0xB25 == 1) { + field_0xB16 = 0xF; + field_0xB25 = 0; + } + + if (field_0xB18 == 0) { + if (mCps1.ChkTgSet() == 0) { + mCps1.OnTgSet(); + } + fn_240_11F0(); + } + + executeState(); + + mMtx_c m; + m.YrotS(mAngle.y); + m.XrotM(-mAngle.x); + mVec3_c vel(0.0f, 0.0f, mSpeed); + m.multVec(vel, mVelocity); + + mPosition += mVelocity; + + if (field_0xB27 == 0) { + mRotation.x = -mAngle.x; + mRotation.y = mAngle.y; + } else { + mRotation.x += field_0xB06; + mRotation.z += field_0xB0A; + mRotation.y += field_0xB08; + field_0xB14 += sSomeAngle; + } + + transformMatrix(); + + if (isState(StateID_BulletMove)) { + startMoveEmitters(); + + if (field_0xB24 != 0) { + mAcch.SetGroundUpY(_weird_zero + -80.0f); + } else if (field_0xB1C == 0) { + mAcch.SetGroundUpY(_weird_zero + 60.0f); + } else if (field_0xB1C == 1) { + mAcch.SetGroundUpY(_weird_zero + 40.0f); + } + + mAcch.CrrPos(*dBgS::GetInstance()); + } + + mMtx_c m1; + m1.ZXYrotS(mRotation); + m1.ZrotM(0x4000); + mVec3_c b1; + m1.getBase(1, b1); + + f32 scale1 = 50.0f; + b1 *= 110.0f; + b1 *= mScale.x; + scale1 *= mScale.x; + mVec3_c p1 = mPosition; + if (field_0xB20 == 0) { + getXZCirclePoint(p1, mAngle.y, scale1); + } + mCps0.Set(p1 + b1, p1 - b1); + + f32 scale0 = 45.0f; + scale0 *= mScale.x; + b1 *= 0.85f; + mVec3_c p0 = p1; + getXZCirclePoint(p0, mAngle.y, scale0); + mCps1.Set(p0 + b1, p0 - b1); + + ; + mCollider.registerColliders(); + if (field_0xB20 != 1) { + if (field_0xB16 > 0) { + field_0xB16--; + if (field_0xB16 < 10) { + if (field_0xB26 != 0) { + mEmitter0.setFading(10); + } else { + mEmitter1.setFading(10); + } + field_0xB10 -= 10.0f; + } + } else if (field_0xB16 == 0) { + deleteRequest(); + } + } + + if (field_0xB18 != 0) { + field_0xB18--; + if (mCps1.ChkTgSet()) { + mCps1.ClrTgSet(); + } + } + + return SUCCEEDED; +} + +int dAcGirahimuSwordBeam_c::draw() { + mSphere_c sph(mVec3_c(0.0f, 0.0f, 0.0f), field_0xB0C); + drawShadow(mShadow, nullptr, mWorldMtx, &sph, -1, field_0xB10, -1, -1, -1, mPosition.y - mAcch.GetGroundH()); + return SUCCEEDED; +} + +void dAcGirahimuSwordBeam_c::initializeState_BulletMove() { + s32 _weird_zero = 0; + mSpeed = 29.0f + _weird_zero; + mMtx_c m; + m.YrotS(mAngle.y); + m.XrotM(-mAngle.x); + mVec3_c vel(0.0f, 0.0f, mSpeed); + m.multVec(vel, mVelocity); +} +void dAcGirahimuSwordBeam_c::executeState_BulletMove() { + if ((mCps0.ChkAtHit() && !mCps0.GetAtFlag0x8()) || mAcch.ChkGndHit() || mAcch.ChkWallHit(nullptr) || + mAcch.ChkWaterIn()) { + mCps0.SetAtRpm(0); + mCps0.ClrAtActorInfo(); + mCps0.SubtractAtEffCounter(); + + if (field_0xB26 != 0) { + mEmitter0.remove(true); + } else { + mEmitter1.remove(true); + } + + startDisappearEmitter(); + + startSound(SE_BGh3_SW_BEAM_DISAPPEAR); + changeState(StateID_Damage); + } +} void dAcGirahimuSwordBeam_c::finalizeState_BulletMove() {} -void dAcGirahimuSwordBeam_c::initializeState_Damage() {} -void dAcGirahimuSwordBeam_c::executeState_Damage() {} + +void dAcGirahimuSwordBeam_c::initializeState_Damage() { + mSpeed = 0.0f; + mVelocity.set(0.0f, 0.0f, 0.0f); + mCps0.ClrAtSet(); +} +void dAcGirahimuSwordBeam_c::executeState_Damage() { + deleteRequest(); +} void dAcGirahimuSwordBeam_c::finalizeState_Damage() {} + +void dAcGirahimuSwordBeam_c::swordBeamReturn(s32 param1) { + if (field_0xB20 == 1) { + fn_240_17C0(param1); + mAngle.y = getXZAngleToPlayer(); + mCps0.SetAtGrp(0xC); + mCps0.OffAtGrp(0x2); + fn_240_16C0(); + field_0xB20 = 0; + field_0xB18 = 10; + field_0xB0C += 30.0f; + mEmitter0.remove(true); + startSound(SE_BGh3_SW_BEAM_RETURN); + field_0xB26 = 0; + } +} + +void dAcGirahimuSwordBeam_c::startMoveEmitters() { + if (field_0xB26 != 0) { + if (field_0xB27 == 0) { + // the beam trail + mEmitter0.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_882_, mWorldMtx, nullptr, nullptr); + } else { + // deflect sparkles? + mEmitter0.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_940_, mWorldMtx, nullptr, nullptr); + } + } else { + // the beam trail + mEmitter1.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_882_, mWorldMtx, nullptr, nullptr); + } +} + +void dAcGirahimuSwordBeam_c::startDisappearEmitter() { + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_881_, mWorldMtx, nullptr, nullptr, 0, 0); +} + +void dAcGirahimuSwordBeam_c::transformMatrix() { + mWorldMtx.transS(mPosition); + mWorldMtx.ZXYrotM(mRotation); + if (field_0xB27) { + mWorldMtx.YrotM(field_0xB14); + } + mWorldMtx.scaleM(mScale); +} + +void dAcGirahimuSwordBeam_c::fn_240_11F0() { + if (field_0xB20 == 0) { + fn_240_1380(); + } + if (mCps1.ChkTgHit()) { + if (mCps1.GetTgAtHitType() == AT_TYPE_0x800000) { + if (field_0xB26 != 0) { + mEmitter0.remove(true); + } else { + mEmitter1.remove(true); + } + + startDisappearEmitter(); + startSound(SE_BGh3_SW_BEAM_DISAPPEAR); + changeState(StateID_Damage); + } else if (mCps1.GetTgAtHitType()) { + // Assuming this was a another branch + } + } + + if (mCps0.ChkAtHit() && mCps0.GetAtFlag0x8()) { + mAng3_c a0; + a0.x = a0.z = 0; + if (field_0xAF4.isLinked()) { + a0.y = dAcPy_c::GetLink()->mRotation.y; + } + field_0xB24 = 1; + + mAng3_c a1 = a0; + fn_240_1810(0, a1, mRotation.y + 0x4000); + } +} + +void dAcGirahimuSwordBeam_c::fn_240_1380() { + if (!mCps1.ChkTgHit()) { + return; + } + + if (mCps1.GetTgAtHitType() != AT_TYPE_SWORD) { + return; + } + + mAng3_c a; + a.x = 0; + a.y = mCps1.GetTgAtHitDir().atan2sX_Z(); + a.z = 0; + mAng playerAngle = cLib::targetAngleY(mPosition, dAcPy_c::GetLink()->mPosition); + mAng hitAngle = cLib::targetAngleY(mPosition, const_cast &>(mCps1).GetTgHitPos()); + if (field_0xAF4.isLinked()) { + cLib::targetAngleY(mPosition, field_0xAF4.get()->mPosition); + } + + s32 cutDir = dAcPy_c::GetLink()->getSpecificAttackDirection(); + switch (cutDir) { + case CUT_DIR_U: { + if (field_0xB1C == 0) { + s32 a = mRotation.y - playerAngle; + if (mAng::abs(a) < 0xAAB) { + fn_240_1710(); + } else { + field_0xB24 = 0; + } + } else if (field_0xB1C == 1) { + field_0xB24 = 0; + } + } break; + case CUT_DIR_D: { + if (field_0xB1C == 0) { + s32 a = mRotation.y - playerAngle; + if (mAng::abs(a) < 0xAAB) { + fn_240_1710(); + } else { + field_0xB24 = 1; + } + } else if (field_0xB1C == 1) { + field_0xB24 = 1; + } + } break; + case CUT_DIR_L: { + if (field_0xB1C == 0) { + field_0xB24 = 0; + } else if (field_0xB1C == 1) { + s32 a = (mRotation.y + 0x1555) - playerAngle; + if (mAng::abs(a) < 0x1C72) { + fn_240_1710(); + } else { + field_0xB24 = 0; + } + } + } break; + case CUT_DIR_R: { + if (field_0xB1C == 0) { + field_0xB24 = 0; + } else if (field_0xB1C == 1) { + s32 a = (mRotation.y - 0x1555) - playerAngle; + if (mAng::abs(a) < 0x1C72) { + fn_240_1710(); + } else { + field_0xB24 = 0; + } + } + } break; + case CUT_DIR_LU: field_0xB24 = 0; break; + case CUT_DIR_LD: field_0xB24 = 1; break; + case CUT_DIR_RU: field_0xB24 = 0; break; + case CUT_DIR_RD: field_0xB24 = 1; break; + case CUT_DIR_STAB: field_0xB24 = 0; break; + default: field_0xB24 = 0; break; + } + + mAng3_c a1 = a; + mAng a2 = hitAngle; + fn_240_1810(cutDir, a1, a2); +} + +void dAcGirahimuSwordBeam_c::fn_240_16C0() { + mSpeed *= 1.21f; + mScale *= 1.17f; +} + +void dAcGirahimuSwordBeam_c::fn_240_1710() { + if (field_0xB20 == 0) { + if (field_0xAF4.isLinked()) { + mAngle.y = cLib::targetAngleY(mPosition, field_0xAF4.get()->mPosition); + } + mCps0.SetAtGrp(2); + mCps0.OffAtGrp(0xC); + field_0xB18 = 10; + field_0xB20 = 1; + mEmitter1.remove(true); + startSound(SE_BGh3_SW_BEAM_RETURN); + field_0xB26 = 1; + } +} + +void dAcGirahimuSwordBeam_c::fn_240_17C0(s32 val) { + if (val == (field_0xB1C & 0xFF)) { + return; + } + + field_0xB1C = val; + mRotation.z = 0; + if (val == 0) { + mRotation.z -= 0x4000; + } +} + +inline mAng rndAngle(f32 amp) { + return cM::rndFX(amp); +} +void dAcGirahimuSwordBeam_c::fn_240_1810(u32 cutDir, mAng3_c &angle, const mAng &ay) { + s32 _weird_zero = 0; + mAng3_c inAngle = angle; + mAng3_c playerAngle; + mAng angleToPlayer = cLib::targetAngleY(mPosition, dAcPy_c::GetLink()->mPosition); + mAng relativeAngle = (mRotation.y - 0x4000) - angleToPlayer; + mAng angDiff = relativeAngle - mRotation.y; + + if (field_0xB20 != 0) { + return; + } + + field_0xB18 = 10; + + // ??? + mAng3_c m; + mAng &linkedAngleY = m.x; + if (field_0xAF4.isLinked()) { + linkedAngleY = (cLib::targetAngleY(mPosition, field_0xAF4.get()->mPosition)); + } + + switch (cutDir) { + case CUT_DIR_RD: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) + 0x1C72; + angle.x += 0x700; + mRotation.y = angle.y + 0x4E39; + s32 ang = relativeAngle.abs(); + if (ang < 0x38E4) { + field_0xB0A = -0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + field_0xB08 = 0x5B0; + } else { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = -0x2D8; + field_0xB08 = 0x889; + } + } break; + case CUT_DIR_RU: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) + 0x1C72; + angle.x -= 0x900; + mRotation.y = angle.y + 0x4E39; + s32 ang = relativeAngle.abs(); + if (ang < 0x38E4) { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } else { + field_0xB0A = -0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } + } break; + case CUT_DIR_R: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) + 0x1C72; + angle.x -= 0x900; + if (field_0xB1C == 0) { + s32 ang = relativeAngle.abs(); + if (ang - 0x3C73 <= 0x71Au) { + field_0xB08 = -0x1777; + angle.x = 0; + } else { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } + } else { + field_0xB06 = -0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } + } break; + case CUT_DIR_LD: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) + -0x1C72; + angle.x += 0x700; + mRotation.y = angle.y + 0x1555; + s32 ang = relativeAngle.abs(); + if (ang < 0x471C) { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = -0x222; + field_0xB08 = -0x5B0; + } else { + field_0xB0A = -0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = -0x5B0; + field_0xB08 = -0x5B0; + } + } break; + case CUT_DIR_LU: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) + -0x1C72; + angle.x -= 0x900; + mRotation.y = angle.y + 0x1555; + s32 ang = relativeAngle.abs(); + if (ang < 0x471C) { + field_0xB0A = -0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } else { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } + } break; + case CUT_DIR_L: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f) - 0x1C72; + angle.x -= 0x900; + if (field_0xB1C == 0) { + s32 ang = relativeAngle.abs(); + if (ang - 0x3C73 <= 0x71Au) { + field_0xB08 = 0x1777; + angle.x = 0; + } else { + field_0xB0A = 0x1777; + field_0xB0A *= (0.8f + (0.1f * _weird_zero)); + field_0xB06 = 0x5B0; + } + } else { + field_0xB06 = 0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } + } break; + case CUT_DIR_U: { + angle.y = linkedAngleY + (182 * rndAngle(11.0f)); + angle.x -= 0x1500; + if (field_0xB1C == 1) { + s32 ang = relativeAngle.abs(); + if (ang < 0x31C7) { + field_0xB0A = 0x1777; + } else if (ang < 0x3C72) { + mRotation.y = angle.y + 0x6AAB; + field_0xB06 = 0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } else if (ang < 0x438E) { + field_0xB06 = 0x1777; + } else if (ang < 0x4E39) { + mRotation.y = angle.y + 0x1C72; + field_0xB06 = -0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } else { + field_0xB0A = -0x1777; + } + } else { + field_0xB08 = 0x1777; + field_0xB08 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } + } break; + case CUT_DIR_D: { + angle.y = linkedAngleY + 182 * rndAngle(11.0f); + angle.x += 0x1500; + if (field_0xB1C == 1) { + s32 ang = relativeAngle.abs(); + if (ang < 0x31C7) { + field_0xB0A = -0x1777; + } else if (ang < 0x38E4) { + mRotation.y = angle.y + 0x6AAB; + field_0xB06 = -0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } else if (ang < 0x471C) { + field_0xB06 = -0x1777; + } else if (ang < 0x4E39) { + mRotation.y = angle.y + 0x1C72; + field_0xB06 = 0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } else { + field_0xB0A = 0x1777; + } + } else { + field_0xB08 = 0x1777; + field_0xB08 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } + } break; + default: { + s32 ang = relativeAngle.abs(); + if (ang - 0x38E5 <= 0xE36u) { + angle.y = mAng((s32)angleToPlayer) + 182 * rndAngle(31.0f) - 0x8000; + } else { + angle.y = mAng((s32)angleToPlayer) + 182 * rndAngle(31.0f) - 0x8000; + } + angle.x += 0x1500; + if (field_0xB1C == 1) { + field_0xB06 = -0x1777; + field_0xB06 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } else { + field_0xB08 = -0x1777; + field_0xB08 *= (0.8f + (0.1f * _weird_zero)); + field_0xB0A = 0x222; + } + } break; + } + sSomeAngle = mAng(0x1777); + + mAngle.y = dAcPy_c::GetLink()->mRotation.y; + s32 ang = angDiff.abs(); + if (ang < 0x31C7) { + field_0xB02 = angle.y; + field_0xB00 = angle.x; + } else { + setB00(angle.x, inAngle.y, angle.z); + } + + mAngle.x = field_0xB00; + mAngle.y = field_0xB02; + mAngle.z = field_0xB04; + + field_0xB16 = 20; + field_0xB20 = 2; + mEmitter1.remove(true); + field_0xB27 = 1; + field_0xB26 = 1; +}