diff --git a/config/SOUE01/rels/d_a_obj_girahimu_knifeNP/symbols.txt b/config/SOUE01/rels/d_a_obj_girahimu_knifeNP/symbols.txt index c92cd0b1..67fa59b2 100644 --- a/config/SOUE01/rels/d_a_obj_girahimu_knifeNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_girahimu_knifeNP/symbols.txt @@ -4,19 +4,19 @@ _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 dAcObjGirahimuKnife_c_classInit__Fv = .text:0x000000F0; // type:function size:0x150 -fn_239_240 = .text:0x00000240; // type:function size:0x58 -fn_239_2A0 = .text:0x000002A0; // type:function size:0x90 +__dt__15dShadowCircle_cFv = .text:0x00000240; // type:function size:0x58 +__dt__22dCcD_Linked<8dCcD_Sph>Fv = .text:0x000002A0; // type:function size:0x90 __dt__34sFState_c<21dAcObjGirahimuKnife_c>Fv = .text:0x00000330; // type:function size:0x58 __dt__37sFStateFct_c<21dAcObjGirahimuKnife_c>Fv = .text:0x00000390; // type:function size:0x6C __dt__90sStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000400; // type:function size:0xA0 __dt__60sFStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c>Fv = .text:0x000004A0; // type:function size:0xA4 -AcObjGirahimuKnife__initModels = .text:0x00000550; // type:function size:0x84 -AcObjGirahimuKnife__init = .text:0x000005E0; // type:function size:0x74 +createHeap__21dAcObjGirahimuKnife_cFv = .text:0x00000550; // type:function size:0x84 +create__21dAcObjGirahimuKnife_cFv = .text:0x000005E0; // type:function size:0x74 changeState__90sStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000660; // type:function size:0x10 -AcObjGirahimuKnife__initCollidersAndEffects = .text:0x00000670; // type:function size:0x170 -AcObjGirahimuKnife__update = .text:0x000007E0; // type:function size:0x1C4 +init__21dAcObjGirahimuKnife_cFv = .text:0x00000670; // type:function size:0x170 +actorExecute__21dAcObjGirahimuKnife_cFv = .text:0x000007E0; // type:function size:0x1C4 executeState__90sStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000009B0; // type:function size:0x10 -AcObjGirahimuKnife__draw = .text:0x000009C0; // type:function size:0xC8 +draw__21dAcObjGirahimuKnife_cFv = .text:0x000009C0; // type:function size:0xC8 initializeState_Wait__21dAcObjGirahimuKnife_cFv = .text:0x00000A90; // type:function size:0x64 executeState_Wait__21dAcObjGirahimuKnife_cFv = .text:0x00000B00; // type:function size:0x110 finalizeState_Wait__21dAcObjGirahimuKnife_cFv = .text:0x00000C10; // type:function size:0x48 @@ -28,14 +28,14 @@ executeState_AttackEnd__21dAcObjGirahimuKnife_cFv = .text:0x00000FA0; // type:fu finalizeState_AttackEnd__21dAcObjGirahimuKnife_cFv = .text:0x00001010; // type:function size:0x4 initializeState_Return__21dAcObjGirahimuKnife_cFv = .text:0x00001020; // type:function size:0x148 executeState_Return__21dAcObjGirahimuKnife_cFv = .text:0x00001170; // type:function size:0x13C -fn_239_12B0 = .text:0x000012B0; // type:function size:0x48 +ChkAtHit__8cCcD_ObjFv = .text:0x000012B0; // type:function size:0x48 finalizeState_Return__21dAcObjGirahimuKnife_cFv = .text:0x00001300; // type:function size:0x4 initializeState_Hit__21dAcObjGirahimuKnife_cFv = .text:0x00001310; // type:function size:0x3C executeState_Hit__21dAcObjGirahimuKnife_cFv = .text:0x00001350; // type:function size:0xC8 finalizeState_Hit__21dAcObjGirahimuKnife_cFv = .text:0x00001420; // type:function size:0x4 initializeState_SpinWait__21dAcObjGirahimuKnife_cFv = .text:0x00001430; // type:function size:0x6C executeState_SpinWait__21dAcObjGirahimuKnife_cFv = .text:0x000014A0; // type:function size:0x120 -fn_239_15C0 = .text:0x000015C0; // type:function size:0x4C +ChkTgHit__8cCcD_ObjFv = .text:0x000015C0; // type:function size:0x4C finalizeState_SpinWait__21dAcObjGirahimuKnife_cFv = .text:0x00001610; // type:function size:0x48 initializeState_SpinWaitPreAttack__21dAcObjGirahimuKnife_cFv = .text:0x00001660; // type:function size:0x34 executeState_SpinWaitPreAttack__21dAcObjGirahimuKnife_cFv = .text:0x000016A0; // type:function size:0x104 @@ -49,29 +49,29 @@ finalizeState_FreeWait__21dAcObjGirahimuKnife_cFv = .text:0x00001A60; // type:fu initializeState_CircleWait__21dAcObjGirahimuKnife_cFv = .text:0x00001AB0; // type:function size:0x84 executeState_CircleWait__21dAcObjGirahimuKnife_cFv = .text:0x00001B40; // type:function size:0xAC finalizeState_CircleWait__21dAcObjGirahimuKnife_cFv = .text:0x00001BF0; // type:function size:0x50 -fn_239_1C40 = .text:0x00001C40; // type:function size:0x170 -fn_239_1DB0 = .text:0x00001DB0; // type:function size:0x198 -fn_239_1F50 = .text:0x00001F50; // type:function size:0x1C0 -fn_239_2110 = .text:0x00002110; // type:function size:0x224 -fn_239_2340 = .text:0x00002340; // type:function size:0x1C -fn_239_2360 = .text:0x00002360; // type:function size:0xF4 -fn_239_2460 = .text:0x00002460; // type:function size:0x154 -AcObjGirahimuKnife__isInWaitState = .text:0x000025C0; // type:function size:0x134 +fn_239_1C40__21dAcObjGirahimuKnife_cFv = .text:0x00001C40; // type:function size:0x170 +fn_239_1DB0__21dAcObjGirahimuKnife_cFRC7mVec3_cRC7mVec3_c = .text:0x00001DB0; // type:function size:0x198 +fn_239_1F50__21dAcObjGirahimuKnife_cFRC7mVec3_cf = .text:0x00001F50; // type:function size:0x1C0 +fn_239_2110__21dAcObjGirahimuKnife_cFRC7mVec3_cfs = .text:0x00002110; // type:function size:0x224 +setTarget__21dAcObjGirahimuKnife_cFRC7mVec3_c = .text:0x00002340; // type:function size:0x1C +fn_239_2360__21dAcObjGirahimuKnife_cFbbf = .text:0x00002360; // type:function size:0xF4 +fn_239_2460__21dAcObjGirahimuKnife_cFbbf = .text:0x00002460; // type:function size:0x154 +isWaiting__21dAcObjGirahimuKnife_cFv = .text:0x000025C0; // type:function size:0x134 getStateID__90sStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00002700; // type:function size:0x10 -fn_239_2710 = .text:0x00002710; // type:function size:0x44 -fn_239_2760 = .text:0x00002760; // type:function size:0x198 -fn_239_2900 = .text:0x00002900; // type:function size:0xC8 -fn_239_29D0 = .text:0x000029D0; // type:function size:0x138 -fn_239_2B10 = .text:0x00002B10; // type:function size:0x510 -AcObjGirahimuKnife__playerAttackMatchesDartAlignmentMaybe = .text:0x00003020; // type:function size:0x224 -fn_239_3250 = .text:0x00003250; // type:function size:0x20 -fn_239_3270 = .text:0x00003270; // type:function size:0x18 -fn_239_3290 = .text:0x00003290; // type:function size:0x1CC -fn_239_3460 = .text:0x00003460; // type:function size:0x1AC -fn_239_3610 = .text:0x00003610; // type:function size:0x8 -fn_239_3620 = .text:0x00003620; // type:function size:0x4 -fn_239_3630 = .text:0x00003630; // type:function size:0x4 -AcObjGirahimuKnife__getEnemyLink = .text:0x00003640; // type:function size:0x8 +isCircleWait__21dAcObjGirahimuKnife_cFv = .text:0x00002710; // type:function size:0x44 +lineCheck__21dAcObjGirahimuKnife_cFv = .text:0x00002760; // type:function size:0x198 +updateMdlMatrix__21dAcObjGirahimuKnife_cFv = .text:0x00002900; // type:function size:0xC8 +startEmitters__21dAcObjGirahimuKnife_cFv = .text:0x000029D0; // type:function size:0x138 +fn_239_2B10__21dAcObjGirahimuKnife_cFv = .text:0x00002B10; // type:function size:0x510 +checkCutDir__21dAcObjGirahimuKnife_cFl = .text:0x00003020; // type:function size:0x224 +setWait__21dAcObjGirahimuKnife_cFv = .text:0x00003250; // type:function size:0x20 +setSpinWaitPreAttack__21dAcObjGirahimuKnife_cFv = .text:0x00003270; // type:function size:0x18 +getReflectForce__21dAcObjGirahimuKnife_cFR8cCcD_ObjfR7mVec3_c = .text:0x00003290; // type:function size:0x1CC +adjustVelocity__21dAcObjGirahimuKnife_cFRC7mVec3_cff = .text:0x00003460; // type:function size:0x1AC +vt_0x88__11dAcEnBase_cFi = .text:0x00003610; // type:function size:0x8 +vt_0x84__11dAcEnBase_cFv = .text:0x00003620; // type:function size:0x4 +vt_0x80__11dAcEnBase_cFv = .text:0x00003630; // type:function size:0x4 +getObjectListEntry__11dAcEnBase_cFv = .text:0x00003640; // type:function size:0x8 __dt__21dAcObjGirahimuKnife_cFv = .text:0x00003650; // type:function size:0x188 build__37sFStateFct_c<21dAcObjGirahimuKnife_c>FRC12sStateIDIf_c = .text:0x000037E0; // type:function size:0x60 dispose__37sFStateFct_c<21dAcObjGirahimuKnife_c>FRP10sStateIf_c = .text:0x00003840; // type:function size:0xC @@ -90,7 +90,7 @@ initializeState__36sFStateID_c<21dAcObjGirahimuKnife_c>CFR21dAcObjGirahimuKnife_ __sinit_\d_a_obj_girahimu_knife_cpp = .text:0x000039A0; // type:function size:0x7A0 scope:local __dt__36sFStateID_c<21dAcObjGirahimuKnife_c>Fv = .text:0x00004140; // type:function size:0x58 isSameName__36sFStateID_c<21dAcObjGirahimuKnife_c>CFPCc = .text:0x000041A0; // type:function size:0x88 -fn_239_4230 = .text:0x00004230; // type:function size:0x8 +@272@__dt__22dCcD_Linked<8dCcD_Sph>Fv = .text:0x00004230; // 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 @@ -108,7 +108,7 @@ lbl_239_rodata_50 = .rodata:0x00000050; // type:object size:0x4 align:4 data:flo lbl_239_rodata_54 = .rodata:0x00000054; // type:object size:0xC align:4 data:float lbl_239_rodata_60 = .rodata:0x00000060; // type:object size:0x4 align:4 data:float lbl_239_rodata_64 = .rodata:0x00000064; // type:object size:0x34 align:4 data:float -lbl_239_data_0 = .data:0x00000000; // type:object size:0x30 data:4byte +sSrcSph = .data:0x00000000; // type:object size:0x30 data:4byte g_profile_OBJ_GH_KNIFE = .data:0x00000030; // type:object size:0x10 lbl_239_data_40 = .data:0x00000040; // type:object size:0xD data:string lbl_239_data_50 = .data:0x00000050; // type:object size:0xE data:string @@ -116,22 +116,27 @@ lbl_239_data_60 = .data:0x00000060; // type:object size:0x23 data:string lbl_239_data_84 = .data:0x00000084; // type:object size:0x4 data:4byte lbl_239_data_88 = .data:0x00000088; // type:object size:0xC data:4byte lbl_239_data_94 = .data:0x00000094; // type:object size:0xC data:4byte -AcObjGirahimuKnife__vtable = .data:0x000000A0; // type:object size:0x90 -lbl_239_data_130 = .data:0x00000130; // type:object size:0x30 -lbl_239_data_160 = .data:0x00000160; // type:object size:0x30 -lbl_239_data_190 = .data:0x00000190; // type:object size:0x18 -lbl_239_data_1A8 = .data:0x000001A8; // type:object size:0x18 -lbl_239_data_1C0 = .data:0x000001C0; // type:object size:0x70 -lbl_239_data_230 = .data:0x00000230; // type:object size:0x314 +__vt__21dAcObjGirahimuKnife_c = .data:0x000000A0; // type:object size:0x90 +__vt__60sFStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c> = .data:0x00000130; // type:object size:0x30 +__vt__90sStateMgr_c<21dAcObjGirahimuKnife_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x00000160; // type:object size:0x30 +__vt__37sFStateFct_c<21dAcObjGirahimuKnife_c> = .data:0x00000190; // type:object size:0x18 +__vt__34sFState_c<21dAcObjGirahimuKnife_c> = .data:0x000001A8; // type:object size:0x18 +__vt__22dCcD_Linked<8dCcD_Sph> = .data:0x000001C0; // type:object size:0x70 +__vt__15dShadowCircle_c = .data:0x00000230; // type:object size:0x314 lbl_239_data_544 = .data:0x00000544; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global -lbl_239_bss_8 = .bss:0x00000008; // type:object size:0x8 data:4byte -lbl_239_bss_10 = .bss:0x00000010; // type:object size:0x2 data:2byte -lbl_239_bss_12 = .bss:0x00000012; // type:object size:0xE data:2byte -AcObjGirahimuKnife__STATE_WAIT = .bss:0x00000020; // type:object size:0x80 data:4byte -AcObjGirahimuKnife__STATE_SPIN_WAIT_PRE_ATTACK = .bss:0x000000A0; // type:object size:0xC0 data:4byte -AcObjGirahimuKnife__STATE_ATTACK = .bss:0x00000160; // type:object size:0x40 data:4byte -AcObjGirahimuKnife__STATE_ATTACK_END = .bss:0x000001A0; // type:object size:0xC0 data:4byte -AcObjGirahimuKnife__STATE_CIRCLE_WAIT = .bss:0x00000260; // type:object size:0x30 data:4byte +sSomething0__21dAcObjGirahimuKnife_c = .bss:0x00000008; // type:object size:0x8 data:4byte +sSomething1__21dAcObjGirahimuKnife_c = .bss:0x00000010; // type:object size:0x2 data:2byte +sSomething2__21dAcObjGirahimuKnife_c = .bss:0x00000012; // type:object size:0xE data:2byte +StateID_Wait__21dAcObjGirahimuKnife_c = .bss:0x00000020; // type:object size:0x30 data:4byte +StateID_SpinWait__21dAcObjGirahimuKnife_c = .bss:0x00000060; // type:object size:0x30 data:4byte +StateID_SpinWaitPreAttack__21dAcObjGirahimuKnife_c = .bss:0x000000A0; // type:object size:0x30 data:4byte +StateID_SpinFreeWait__21dAcObjGirahimuKnife_c = .bss:0x000000E0; // type:object size:0x30 data:4byte +StateID_FreeWait__21dAcObjGirahimuKnife_c = .bss:0x00000120; // type:object size:0x30 data:4byte +StateID_Attack__21dAcObjGirahimuKnife_c = .bss:0x00000160; // type:object size:0x30 data:4byte +StateID_AttackEnd__21dAcObjGirahimuKnife_c = .bss:0x000001A0; // type:object size:0x30 data:4byte +StateID_Return__21dAcObjGirahimuKnife_c = .bss:0x000001E0; // type:object size:0x30 data:4byte +StateID_Hit__21dAcObjGirahimuKnife_c = .bss:0x00000220; // type:object size:0x30 data:4byte +StateID_CircleWait__21dAcObjGirahimuKnife_c = .bss:0x00000260; // type:object size:0x30 data:4byte lbl_239_bss_290 = .bss:0x00000290; // type:object size:0x8 data:byte lbl_239_bss_298 = .bss:0x00000298; // type:object size:0x10 align:4 data:float diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3fefff01..9ea5e85b 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1120,10 +1120,10 @@ getObjectListEntry__12dAcObjBase_cFv = .text:0x8002E5B0; // type:function size:0 restorePosRotFromCopy__12dAcObjBase_cFv = .text:0x8002E5C0; // type:function size:0x70 create__12dAcObjBase_cFQ28fProfile14PROFILE_NAME_eUlUlPC7mVec3_cPC7mAng3_cPC7mVec3_cUl = .text:0x8002E630; // type:function size:0x98 create__12dAcObjBase_cFPCcUlUlPC7mVec3_cPC7mAng3_cPC7mVec3_cUlUsSc = .text:0x8002E6D0; // type:function size:0xA0 -ActorObjectBase__findObject = .text:0x8002E770; // type:function size:0x7C +findObject__12dAcObjBase_cFQ28fProfile14PROFILE_NAME_eP9fLiMgBa_cP12dAcObjBase_c = .text:0x8002E770; // type:function size:0x7C getNextObject__12dAcObjBase_cFP9fLiMgBa_cP12dAcObjBase_c = .text:0x8002E7F0; // type:function size:0x58 isPlayer__12dAcObjBase_cFv = .text:0x8002E850; // type:function size:0x14 -ActorObjectBase__calcVelocity = .text:0x8002E870; // type:function size:0x68 +calcVelocity__12dAcObjBase_cFR7mVec3_cf = .text:0x8002E870; // type:function size:0x68 calcVelocity__12dAcObjBase_cFv = .text:0x8002E8E0; // type:function size:0xB8 updateMatrix__12dAcObjBase_cFv = .text:0x8002E9A0; // type:function size:0x58 ActorObjectBase__setDefaultCullDistance = .text:0x8002EA00; // type:function size:0xC diff --git a/include/d/a/b/d_a_b_girahimu2.h b/include/d/a/b/d_a_b_girahimu2.h index 67a39339..a825633c 100644 --- a/include/d/a/b/d_a_b_girahimu2.h +++ b/include/d/a/b/d_a_b_girahimu2.h @@ -9,8 +9,14 @@ public: dAcGirahimu2_c() : mStateMgr(*this) {} virtual ~dAcGirahimu2_c() {} + void setField_0xD52(u16 val) { + field_0xD52 = val; + } + private: /* 0x??? */ STATE_MGR_DECLARE(dAcGirahimu2_c); + + /* 0xD52 */ u16 field_0xD52; }; #endif diff --git a/include/d/a/e/d_a_en_base.h b/include/d/a/e/d_a_en_base.h index ac03f2b2..88f78f97 100644 --- a/include/d/a/e/d_a_en_base.h +++ b/include/d/a/e/d_a_en_base.h @@ -100,6 +100,9 @@ public: static dAcEnBase_c *GetNextEnemy(dAcEnBase_c *pParent) { return static_cast(getNextObject(&sEnemyList, pParent)); } + static dAcEnBase_c *FindEnemy(fProfile::PROFILE_NAME_e profile, dAcEnBase_c *pParent = nullptr) { + return static_cast(findObject(profile, &sEnemyList, pParent)); + } protected: // TODO: Make accessors for this list to auto-convert to dAcEnBase? diff --git a/include/d/a/obj/d_a_obj_base.h b/include/d/a/obj/d_a_obj_base.h index a72d3ea6..7dd7161a 100644 --- a/include/d/a/obj/d_a_obj_base.h +++ b/include/d/a/obj/d_a_obj_base.h @@ -203,7 +203,7 @@ public: const mVec3_c *scale, u32 params2, u32 roomId ); - static dAcObjBase_c *findObject(fProfile::PROFILE_NAME_e actorId, fLiNdBa_c *refList, dAcObjBase_c *parent); + static dAcObjBase_c *findObject(fProfile::PROFILE_NAME_e actorId, fLiMgBa_c *refList, dAcObjBase_c *parent); static dAcObjBase_c *getNextObject(fLiMgBa_c *ref, dAcObjBase_c *parent); bool isPlayer(); void calcVelocity(mVec3_c &pos, f32 speed); diff --git a/include/d/a/obj/d_a_obj_girahimu_knife.h b/include/d/a/obj/d_a_obj_girahimu_knife.h index a94ed7e9..9d6ddf8a 100644 --- a/include/d/a/obj/d_a_obj_girahimu_knife.h +++ b/include/d/a/obj/d_a_obj_girahimu_knife.h @@ -2,13 +2,28 @@ #define D_A_OBJ_GIRAHIMU_KNIFE_H #include "d/a/e/d_a_en_base.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_shadow.h" +#include "m/m3d/m_smdl.h" +#include "m/m_angle.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_vec.h" #include "s/s_State.hpp" +#include "toBeSorted/d_emitter.h" class dAcObjGirahimuKnife_c : public dAcEnBase_c { public: - dAcObjGirahimuKnife_c() : mStateMgr(*this) {} + dAcObjGirahimuKnife_c() : mGlowEmitter(this), mTrailEmitter(this), mStateMgr(*this) {} virtual ~dAcObjGirahimuKnife_c() {} + virtual int create() override; + virtual int draw() override; + virtual bool createHeap() override; + virtual int actorExecute() override; + STATE_FUNC_DECLARE(dAcObjGirahimuKnife_c, Wait); STATE_FUNC_DECLARE(dAcObjGirahimuKnife_c, SpinWait); STATE_FUNC_DECLARE(dAcObjGirahimuKnife_c, SpinWaitPreAttack); @@ -20,8 +35,75 @@ public: STATE_FUNC_DECLARE(dAcObjGirahimuKnife_c, Hit); STATE_FUNC_DECLARE(dAcObjGirahimuKnife_c, CircleWait); + STATE_MGR_DEFINE_UTIL_CHANGESTATE(dAcObjGirahimuKnife_c); + STATE_MGR_DEFINE_UTIL_ISSTATE(dAcObjGirahimuKnife_c); + STATE_MGR_DEFINE_UTIL_EXECUTESTATE(dAcObjGirahimuKnife_c); + STATE_MGR_DEFINE_UTIL_GETSTATEID(dAcObjGirahimuKnife_c); + + void init(); + + void fn_239_1C40(); + void fn_239_1DB0(const mVec3_c &base, const mVec3_c &target); + void fn_239_1F50(const mVec3_c &target, f32 add); + void fn_239_2110(const mVec3_c &target, f32 add, s16 ang); + void setTarget(const mVec3_c &t); + void fn_239_2360(bool, bool, f32 zVel); + void fn_239_2460(bool, bool, f32 velMult); + bool isWaiting(); + bool isCircleWait(); + bool lineCheck(); + void updateMdlMatrix(); + void startEmitters(); + void fn_239_2B10(); + bool checkCutDir(s32 cutDir); + void setWait(); + void setSpinWaitPreAttack(); + void getReflectForce(cCcD_Obj &cc, f32 forceMult, mVec3_c &outforce); + void adjustVelocity(const mVec3_c &force, f32 yVel, f32 forwardVel); + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcObjGirahimuKnife_c); + /* 0x378 */ m3d::smdl_c mMdl; + /* 0x394 */ dShadowCircle_c mShadow; + /* 0x39C */ dEmitter_c mGlowEmitter; + /* 0x3D0 */ dEmitter_c mTrailEmitter; + /* 0x404 */ dCcD_Linked mSph0; + /* 0x564 */ dCcD_Linked mSph1; + /* 0x6C0 */ dColliderLinkedList mCollider; + /* 0x6D0 */ s16 field_0x6D0; + /* 0x6D2 */ u16 mGlowEmitterId; + /* 0x6D4 */ u16 mTrailEmitterId; + /* 0x6D6 */ u16 field_0x6D6; + /* 0x6D8 */ mVec3_c field_0x6D8; + /* 0x6E4 */ mVec3_c field_0x6E4; + /* 0x6F0 */ mAng3_c field_0x6F0; + /* 0x6F6 */ mAng3_c field_0x6F6; + /* 0x7FC */ u8 _0x6FC[0x704 - 0x6FC]; + /* 0x704 */ mQuat_c field_0x704; + /* 0x714 */ mMtx_c field_0x714; + /* 0x744 */ mVec3_c field_0x744; + /* 0x750 */ mVec3_c field_0x750; + /* 0x75C */ mVec3_c field_0x75C; + /* 0x768 */ mVec3_c field_0x768; + /* 0x774 */ f32 field_0x774; + /* 0x778 */ s16 field_0x778; + /* 0x77C */ f32 field_0x77C; + /* 0x780 */ mAng field_0x780; + /* 0x784 */ s32 field_0x784; + /* 0x788 */ s32 mState; + /* 0x78C */ bool field_0x78C; + /* 0x78D */ bool field_0x78D; + /* 0x78E */ bool field_0x78E; + /* 0x78F */ bool field_0x78F; + /* 0x790 */ bool field_0x790; + /* 0x791 */ bool field_0x791; + /* 0x792 */ bool field_0x792; + /* 0x793 */ bool field_0x793; + /* 0x794 */ STATE_MGR_DECLARE(dAcObjGirahimuKnife_c); + + static s32 sSomething0; + static s32 sSomething0_1; + static mAng sSomething1; + static s16 sSomething2; }; #endif diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 6c701aeb..0b82074b 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -572,6 +572,9 @@ public: void SetInfo_0x0(u8 val) { mSrc.mInfo.field_0x0 = val; } + void SetSrc_0xE(u8 val) { + mSrc.field_0xE = val; + } const cCcD_SrcGObjAt &GetSrc() const { return mSrc; @@ -881,6 +884,10 @@ public: void SetAtFlag(u32 flag) { mAt.SetSPrm(flag); } + + void SetAtFlag2(u32 flag) { + mAt.SetAtFlag(flag); + } void SetAtGrp(u32 grp) { mAt.SetAtFlag(GetAtGrp() | grp); } @@ -1037,13 +1044,16 @@ public: void SetAtInfo_0x0(u8 amount) { mAt.SetInfo_0x0(amount); } + void SetAt_0xE(u8 val) { + mAt.SetSrc_0xE(val); + } void SetAtDamage(u8 amount) { mAt.SetAtDamage(amount); } void SetAtModifier(u16 modifier) { mAt.SetSrcModifer(modifier); - } + } // Tg diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 3506940c..55efefc3 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -664,6 +664,12 @@ public: bool isAttackingSpin() const { return isAttackingSpinHorizontal() || isAttackingSpinVertical(); } + bool isAttackingHorizontal() const { + return isAttackingLeft() || isAttackingRight(); + } + bool isAttackingVertical() const { + return isAttackingUp() || isAttackingDown(); + } void setBonkRelatedAnimFlag(bool b); void setPosYRot(const mVec3_c &pos, mAng rot, bool force = false, UNKWORD = 0, UNKWORD = 0); void setTransform(const mMtx_c &mtx, bool force, UNKWORD, UNKWORD); diff --git a/include/m/m_angle.h b/include/m/m_angle.h index 7282ac39..d5e01d4d 100644 --- a/include/m/m_angle.h +++ b/include/m/m_angle.h @@ -112,6 +112,9 @@ public: f32 radian_c() const { return mVal * sAngToRad; } + f32 normal_c() const { + return mVal * sAngToNorm; + } public: static s16 d2s(f32 deg) { diff --git a/src/REL/d/a/obj/d_a_obj_girahimu_knife.cpp b/src/REL/d/a/obj/d_a_obj_girahimu_knife.cpp index f3e930e4..7610a9d8 100644 --- a/src/REL/d/a/obj/d_a_obj_girahimu_knife.cpp +++ b/src/REL/d/a/obj/d_a_obj_girahimu_knife.cpp @@ -1,7 +1,45 @@ #include "d/a/obj/d_a_obj_girahimu_knife.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/b/d_a_b_girahimu2.h" +#include "d/a/d_a_player.h" +#include "d/a/e/d_a_en_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/bg/d_bg_s_lin_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_angle.h" +#include "m/m_color.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_sphere.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/math/math_types.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" + +static dCcD_SrcSph sSrcSph = { + /* mObjInf */ + {/* mObjAt */ {AT_TYPE_DAMAGE, 0xD, {9, 0, 0}, 2, 0, 0, 0, CUT_DIR_NONE, 0}, + /* mObjTg */ {~(AT_TYPE_COMMON0 & ~AT_TYPE_WIND), 0x111, {9, 0x18, 0x40F}, 0, CUT_DIR_NONE}, + /* mObjCo */ {0x25}}, + /* mSphInf */ + {30.0f} +}; + SPECIAL_ACTOR_PROFILE(OBJ_GH_KNIFE, dAcObjGirahimuKnife_c, fProfile::OBJ_GH_KNIFE, 0x115, 0, 2); +s32 dAcObjGirahimuKnife_c::sSomething0; +s32 dAcObjGirahimuKnife_c::sSomething0_1; +mAng dAcObjGirahimuKnife_c::sSomething1; +s16 dAcObjGirahimuKnife_c::sSomething2; + STATE_DEFINE(dAcObjGirahimuKnife_c, Wait); STATE_DEFINE(dAcObjGirahimuKnife_c, SpinWait); STATE_DEFINE(dAcObjGirahimuKnife_c, SpinWaitPreAttack); @@ -13,33 +51,783 @@ STATE_DEFINE(dAcObjGirahimuKnife_c, Return); STATE_DEFINE(dAcObjGirahimuKnife_c, Hit); STATE_DEFINE(dAcObjGirahimuKnife_c, CircleWait); -void dAcObjGirahimuKnife_c::initializeState_Wait() {} -void dAcObjGirahimuKnife_c::executeState_Wait() {} -void dAcObjGirahimuKnife_c::finalizeState_Wait() {} -void dAcObjGirahimuKnife_c::initializeState_SpinWait() {} -void dAcObjGirahimuKnife_c::executeState_SpinWait() {} -void dAcObjGirahimuKnife_c::finalizeState_SpinWait() {} -void dAcObjGirahimuKnife_c::initializeState_SpinWaitPreAttack() {} -void dAcObjGirahimuKnife_c::executeState_SpinWaitPreAttack() {} -void dAcObjGirahimuKnife_c::finalizeState_SpinWaitPreAttack() {} -void dAcObjGirahimuKnife_c::initializeState_SpinFreeWait() {} -void dAcObjGirahimuKnife_c::executeState_SpinFreeWait() {} -void dAcObjGirahimuKnife_c::finalizeState_SpinFreeWait() {} -void dAcObjGirahimuKnife_c::initializeState_FreeWait() {} -void dAcObjGirahimuKnife_c::executeState_FreeWait() {} -void dAcObjGirahimuKnife_c::finalizeState_FreeWait() {} -void dAcObjGirahimuKnife_c::initializeState_Attack() {} -void dAcObjGirahimuKnife_c::executeState_Attack() {} +bool dAcObjGirahimuKnife_c::createHeap() { + nw4r::g3d::ResFile res(nullptr); + res = nw4r::g3d::ResFile(getOarcResFile("GirahimKnife")); + TRY_CREATE(mMdl.create(res.GetResMdl("GirahimKnifeA"), &mAllocator, 0x20, 1, nullptr)); + return true; +} + +int dAcObjGirahimuKnife_c::create() { + CREATE_ALLOCATOR(dAcObjGirahimuKnife_c); + init(); + changeState(StateID_Wait); + return SUCCEEDED; +} + +void dAcObjGirahimuKnife_c::init() { + sSomething2 = 1; + field_0x793 = true; + field_0x750.set(0.0f, 0.0f, 0.0f); + mAcceleration = 0.0f; + field_0x792 = true; + mStts.SetRank(12); + mMaxSpeed = -6000.0f; + mBoundingBox.Set(mVec3_c(-100.0f, -100.0f, -100.0f), mVec3_c(100.0f, 100.0f, 100.0f)); + field_0x75C.set(1.2f, 0.0f, 1.2f); + field_0x774 = 20.0f; + + mCollider.addCc(mSph1, sSrcSph); + mCollider.addCc(mSph0, sSrcSph); + mCollider.SetStts(mStts); + + mSph1.SetR(15.0f); + mSph0.SetR(30.0f); + + mSph1.OnAtSet(); + mSph1.ClrTgSet(); + + mSph0.ClrAtSet(); + mSph0.OnTgSet(); + + mSph0.SetTg_0x50(2); + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_685_, mPosition, nullptr, nullptr, nullptr, nullptr, 0, 0); +} + +int dAcObjGirahimuKnife_c::actorExecute() { + field_0x768.set(field_0x75C); + if (--field_0x6D0 <= 0) { + field_0x6D0 = 0; + } + + executeState(); + + mVelocity.y -= mAcceleration; + mPosition += mVelocity; + + mSph1.SetAtVec(mVelocity); + + mSph1.SetC(mPosition); + mSph0.SetC(mPosition); + mCollider.registerColliders(); + + updateMdlMatrix(); + startEmitters(); + + if (mPosition.y <= -1000.0f) { + deleteRequest(); + } + + mVec3_c compare(1.2f, 1.2f, 1.2f); + if (field_0x768 == compare && field_0x75C != compare) { + startSound(SE_OGhKf_DISAPPEAR); + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_685_, mPosition, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + } + return SUCCEEDED; +} + +int dAcObjGirahimuKnife_c::draw() { + static mSphere_c sph(mVec3_c(0.0f, 60.0f, 0.0f), 100.0f); + f32 f = mPosition.y; + drawModelType1(&mMdl); + fn_8002edb0(mShadow, mMdl, &sph, -1, -1, f); + return SUCCEEDED; +} + +void dAcObjGirahimuKnife_c::initializeState_Wait() { + field_0x6F6.x = cM::rndInt(64000); + field_0x6F6.z = cM::rndInt(64000); + + field_0x778 = cM::rndInt(32000); + field_0x774 = 20.0f; +} +void dAcObjGirahimuKnife_c::executeState_Wait() { + if (!dAcPy_c::GetLink()->isAttacking()) { + mSph0.ClrTgSet(); + } else { + mSph0.OnTgSet(); + } + + if (mState == 4) { + changeState(StateID_SpinWait); + } else if (mState == 5) { + changeState(StateID_SpinFreeWait); + } else if (mState == 6) { + changeState(StateID_CircleWait); + } else if (mState == 8) { + changeState(StateID_FreeWait); + } else { + fn_239_2B10(); + fn_239_1DB0(field_0x6D8, field_0x744); + field_0x778 += 0x500; + fn_239_1C40(); + } +} +void dAcObjGirahimuKnife_c::finalizeState_Wait() { + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); +} + +void dAcObjGirahimuKnife_c::initializeState_Attack() { + mSph1.OnAtSet(); + mSph1.ClrCoSet(); + mSph0.ClrCoSet(); + + mAcceleration = 0.0f; + field_0x78C = true; + + if (mState != 6) { + sSomething2 = 1; + } + + if (sSomething2 == 0 || !field_0x793) { + mSph1.ClrAtSet(); + } +} +void dAcObjGirahimuKnife_c::executeState_Attack() { + holdSound(SE_OGhKf_FLY_LV); + + if (sSomething2 == 0 || !field_0x793) { + mSph1.ClrAtSet(); + } + fn_239_2B10(); + sLib::chase(&field_0x774, 0.0f, 2.0f); + field_0x778 += 0x700; + if (lineCheck()) { + changeState(StateID_AttackEnd); + return; + } + + if (field_0x790) { + mVec3_c v0 = dAcPy_c::GetLink()->mPosition; + if (field_0x791) { + mVec3_c mod(field_0x744.x, field_0x744.y, 0.0f); + mod.rotY(dAcPy_c::GetLink()->mRotation.y + 0x8000); + v0 += mod; + } else { + v0.y += 100.0f; + } + + mVec3_c diff = v0 - mPosition; + if (diff.dot(mVelocity) > 0.0f) { + sLib::chaseAngle(mAngle.y.ref(), diff.atan2sX_Z(), 0x100); + mVec3_c vel(0.0f, mVelocity.y, 60.0f); + vel.rotY(mAngle.y); + mVelocity.set(vel); + } + } + mVec3_c norm = mVelocity; + norm.normalizeRS(); + mQuat_c q; + q.slerp(mVec3_c(0.0f, 0.0f, 1.0f), norm, 1.0f); + field_0x704.slerpTo(q, 0.5f, field_0x704); + field_0x714.fromQuat(field_0x704); +} void dAcObjGirahimuKnife_c::finalizeState_Attack() {} -void dAcObjGirahimuKnife_c::initializeState_AttackEnd() {} -void dAcObjGirahimuKnife_c::executeState_AttackEnd() {} + +void dAcObjGirahimuKnife_c::initializeState_AttackEnd() { + field_0x6D0 = 0x3C; + mSph1.ClrAtSet(); + mSph0.ClrTgSet(); +} +void dAcObjGirahimuKnife_c::executeState_AttackEnd() { + mVelocity.set(0.0f, 0.0f, 0.0f); + mAcceleration = 0.0f; + if (field_0x6D0 <= 0 && sLib::chase(&field_0x75C.y, 0.0f, 0.1f)) { + deleteRequest(); + } +} void dAcObjGirahimuKnife_c::finalizeState_AttackEnd() {} -void dAcObjGirahimuKnife_c::initializeState_Return() {} -void dAcObjGirahimuKnife_c::executeState_Return() {} + +void dAcObjGirahimuKnife_c::initializeState_Return() { + mSph1.SetAt_0xE(0); + mAcceleration = 1.0f; + + mVec3_c v0 = field_0x6D8; + mVec3_c v1 = mPosition - field_0x6D8; + mVec3_c pos(cM::rndFX(50.0f), 100.0f + cM::rndFX(50.0f), -100.0f); + pos.rotY(v1.atan2sX_Z()); + + v0 += pos; + f32 speed = (v1.absXZ() / 500.0f); + speed *= 4.0f; + calcVelocity(v0, speed); + mSph0.ClrTgSet(); +} +void dAcObjGirahimuKnife_c::executeState_Return() { + mSph1.SetAtFlag2(2); + mSph1.OnAtSet(); + mSph0.ClrTgSet(); + mSph1.SetR(50.0f); + if (lineCheck()) { + changeState(StateID_AttackEnd); + } else if (mSph1.ChkAtHit()) { + deleteRequest(); + } else { + mVec3_c norm = mVelocity; + norm.normalizeRS(); + mQuat_c q; + q.slerp(mVec3_c(0.0f, 0.0f, 1.0f), norm, 1.0f); + field_0x704.slerpTo(q, 0.5f, field_0x704); + field_0x714.fromQuat(field_0x704); + } +} void dAcObjGirahimuKnife_c::finalizeState_Return() {} -void dAcObjGirahimuKnife_c::initializeState_Hit() {} -void dAcObjGirahimuKnife_c::executeState_Hit() {} + +void dAcObjGirahimuKnife_c::initializeState_Hit() { + mAcceleration = 1.0f; + mSph1.ClrAtSet(); + if (mState == 8) { + mSph1.ClrAtSet(); + mSph0.ClrTgSet(); + } +} +void dAcObjGirahimuKnife_c::executeState_Hit() { + if (lineCheck()) { + changeState(StateID_AttackEnd); + return; + } + mVec3_c norm = mVelocity; + norm.normalizeRS(); + mQuat_c q; + f32 f = 20.0f; // Forces rodata pool + f = 1.0f; + q.slerp(mVec3_c(0.0f, 0.0f, 1.0f), norm, f); + field_0x704.slerpTo(q, 0.5f, field_0x704); + field_0x714.fromQuat(field_0x704); +} void dAcObjGirahimuKnife_c::finalizeState_Hit() {} -void dAcObjGirahimuKnife_c::initializeState_CircleWait() {} -void dAcObjGirahimuKnife_c::executeState_CircleWait() {} -void dAcObjGirahimuKnife_c::finalizeState_CircleWait() {} + +void dAcObjGirahimuKnife_c::initializeState_SpinWait() { + field_0x6F6.x = cM::rndInt(64000); + field_0x6F6.z = cM::rndInt(64000); + field_0x778 = cM::rndInt(32000); + mSph0.SetTg_0x4C(-1); + field_0x774 = 10.0f; +} +void dAcObjGirahimuKnife_c::executeState_SpinWait() { + mSph1.ClrAtSet(); + mSph0.SetR(50.0f); + field_0x78F = true; + + if (checkCutDir(dAcPy_c::GetLink()->getSpecificAttackDirection())) { + mSph0.OnTgSet(); + } else { + mSph0.ClrTgSet(); + } + + fn_239_2B10(); + if (mSph0.ChkTgHit()) { + dAcEnBase_c *pEn = FindEnemy(fProfile::B_GIRAHIMU2); + if (pEn != nullptr) { + static_cast(pEn)->setField_0xD52(120); + } + } + fn_239_1DB0(field_0x6D8, field_0x744); + field_0x778 += 0x500; + fn_239_1C40(); + if (field_0x792) { + holdSound(SE_OGhKf_SPIN_LV); + } +} +void dAcObjGirahimuKnife_c::finalizeState_SpinWait() { + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); +} + +void dAcObjGirahimuKnife_c::initializeState_SpinWaitPreAttack() { + mSph0.SetTg_0x4C(-1); + field_0x744.x *= 1.5f; + field_0x744.z = 50.0f; + field_0x792 = false; +} +void dAcObjGirahimuKnife_c::executeState_SpinWaitPreAttack() { + if (!dAcPy_c::GetLink()->isAttacking()) { + mSph0.ClrTgSet(); + } else { + mSph0.OnTgSet(); + } + + field_0x778 += 0x500; + if (field_0x78E) { + mSph1.ClrCoSet(); + mSph0.ClrCoSet(); + if (sLib::chase(&field_0x75C.y, 0.0f, 0.1f)) { + deleteRequest(); + } + } else { + sLib::chase(&field_0x75C.y, 1.2f, 0.1f); + } + mSph1.ClrAtSet(); + mSph0.SetR(50.0f); + fn_239_2B10(); + fn_239_1DB0(field_0x6D8, field_0x744); + fn_239_1C40(); +} +void dAcObjGirahimuKnife_c::finalizeState_SpinWaitPreAttack() { + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); +} + +void dAcObjGirahimuKnife_c::initializeState_SpinFreeWait() { + sSomething0++; + field_0x778 = cM::rndInt(32000); + mSph0.SetTg_0x4C(-1); + // NOTE - This is needed to force the rodata pool loading despite not emitting anything + field_0x774 = 20.0f; + field_0x774 = 0.0f; + sSomething1 += mAng(0x1000); + field_0x77C = 120.0f; + field_0x780 = sSomething1; +} +void dAcObjGirahimuKnife_c::executeState_SpinFreeWait() { + mSph1.ClrAtSet(); + mSph0.SetR(50.0f); + field_0x78F = true; + mSph0.ClrTgSet(); + fn_239_2B10(); + fn_239_2110(field_0x6D8, 150.0f, 0x4000); + fn_239_1C40(); +} +void dAcObjGirahimuKnife_c::finalizeState_SpinFreeWait() { + sSomething1 = mAng(0); + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); +} + +void dAcObjGirahimuKnife_c::initializeState_FreeWait() { + field_0x6F6.x = cM::rndInt(64000); + field_0x6F6.z = cM::rndInt(64000); + field_0x778 = cM::rndInt(32000); + field_0x774 = 10.0f; +} +void dAcObjGirahimuKnife_c::executeState_FreeWait() { + mSph1.ClrAtSet(); + mSph0.SetR(50.0f); + field_0x78F = true; + fn_239_2B10(); + fn_239_1DB0(field_0x6D8, field_0x744); + field_0x778 += 0x500; + fn_239_1C40(); +} +void dAcObjGirahimuKnife_c::finalizeState_FreeWait() { + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); +} + +// NONMATCHING +void dAcObjGirahimuKnife_c::initializeState_CircleWait() { + mSph0.SetTg_0x4C(-1); + field_0x774 = 0.0f; + // Dont think about it + mAng som = sSomething1; + mAng newval = som + 0x1000; + if (field_0x784 == 7) { + newval = som - 0x800; + } + sSomething1 = newval; + field_0x77C = 200.0f; + + field_0x780 = sSomething1; + mSph0.OnTgSet(); + field_0x790 = true; + mSph1.ClrCoSet(); + mSph0.ClrCoSet(); +} +void dAcObjGirahimuKnife_c::executeState_CircleWait() { + mSph1.ClrAtSet(); + mSph0.SetR(50.0f); + field_0x78F = true; + fn_239_2B10(); + if (field_0x784 == 7) { + fn_239_1F50(dAcPy_c::GetLink()->mPosition, 50.0f); + } else { + fn_239_2110(dAcPy_c::GetLink()->mPosition, 150.0f, 0); + } + fn_239_1C40(); +} +void dAcObjGirahimuKnife_c::finalizeState_CircleWait() { + mSph0.OnTgSet(); + field_0x714.toQuat(field_0x704); + mSph0.SetTg_0x4C(0); + sSomething1 = mAng(0); +} + +void dAcObjGirahimuKnife_c::fn_239_1C40() { + if (field_0x78E != 0) { + mSph1.ClrCoSet(); + mSph0.ClrCoSet(); + if (sLib::chase(&field_0x75C.y, 0.0f, 0.1f) != false) { + deleteRequest(); + } + } else { + sLib::chase(&field_0x75C.y, 1.2f, 0.1f); + } + + if (field_0x792) { + field_0x6F6.x = field_0x6F6.x + 0x1700; + field_0x6F6.y = field_0x6F0.y + 0x4000; + field_0x6F6.z = field_0x6F6.z + 0x1700; + field_0x714.ZXYrotS(field_0x6F6); + } else { + mVec3_c v = dAcPy_c::GetLink()->mPosition; + v.y += 100.0f; + mVec3_c norm = v - mPosition; + norm.normalizeRS(); + + mQuat_c q; + q.slerp(mVec3_c(0.0f, 0.0f, 1.0f), norm, 1.0f); + field_0x704.slerpTo(q, 0.5f, field_0x704); + field_0x714.fromQuat(field_0x704); + } +} + +// NONMATCHING - UGH +void dAcObjGirahimuKnife_c::fn_239_1DB0(const mVec3_c &i_base, const mVec3_c &i_target) { + mVec3_c base = i_base; + mVec3_c target = i_target; + target.rotY(field_0x6F0.y); + + mVec3_c toGoal = 0.05f * (base + target - mPosition); + toGoal += mVelocity; + toGoal *= 0.9f; + + mVelocity.set(toGoal); + mPosition += mVelocity; +} + +// NONMATCHING - UGH +void dAcObjGirahimuKnife_c::fn_239_1F50(const mVec3_c &i_target, f32 add) { + mVec3_c target = i_target; + mVec3_c front(0.0f, 0.0f, field_0x77C); + + mMtx_c m; + m.YrotS(dAcPy_c::GetLink()->mRotation.y); + m.XrotM(field_0x780); + m.multVec(front, front); + mVec3_c goal = target + front; + goal.y += add; + mPosition += mVelocity = (mVelocity + (goal - mPosition) * 0.05f) * 0.9f; +} + +// NONMATCHING - UGH +void dAcObjGirahimuKnife_c::fn_239_2110(const mVec3_c &i_target, f32 add, s16 ang) { + if (field_0x792) { + field_0x780 += mAng(0x400); + } + mVec3_c target = i_target; + mVec3_c front(0.0f, 0.0f, field_0x77C); + + mMtx_c m; + m.YrotS(field_0x6F0.y + field_0x780); + m.multVec(front, front); + + m.YrotS(field_0x6F0.y); + m.XrotM(ang); + m.YrotM(-field_0x6F0.y); + m.multVec(front, front); + + mVec3_c goal = target + front; + goal.y += add; + mVec3_c v = (mVelocity + (goal - mPosition) * 0.05f) * 0.9f; + mVelocity.set(v); + mPosition += mVelocity; +} + +void dAcObjGirahimuKnife_c::setTarget(const mVec3_c &t) { + field_0x744.set(t); +} + +void dAcObjGirahimuKnife_c::fn_239_2360(bool b0, bool b1, f32 zVel) { + if (b0 && !isWaiting()) { + return; + } + + field_0x790 = b1; + field_0x791 = b1; + + changeState(StateID_Attack); + field_0x78F = true; + mVec3_c diff = dAcPy_c::GetLink()->mPosition - field_0x6D8; + mAng toPlayer = diff.atan2sX_Z(); + mAngle.y = toPlayer; + mVelocity.set(0.0f, 0.0f, zVel); + mVelocity.rotY(toPlayer); + field_0x6D6 = 0xFF; +} + +void dAcObjGirahimuKnife_c::fn_239_2460(bool b0, bool b1, f32 velMult) { + if (b0 && !isWaiting()) { + return; + } + + if (!isCircleWait()) { + field_0x790 = true; + } else { + field_0x790 = false; + } + changeState(StateID_Attack); + + mSph0.SetR(100.f); + + field_0x78F = b1; + mVec3_c playerOffset = dAcPy_c::GetLink()->mPosition; + playerOffset.y += 100.0f; + mVec3_c diff = playerOffset - mPosition; + mAngle.y = diff.atan2sX_Z(); + + diff.normalizeRS(); + diff *= velMult; + mVelocity.set(diff); + field_0x6D6 = 0xFF; +} + +bool dAcObjGirahimuKnife_c::isWaiting() { + if (getStateID().isEqual(StateID_Wait) || getStateID().isEqual(StateID_SpinWait) || + getStateID().isEqual(StateID_SpinFreeWait) || getStateID().isEqual(StateID_FreeWait) || + getStateID().isEqual(StateID_CircleWait)) { + return true; + } + return false; +} + +bool dAcObjGirahimuKnife_c::isCircleWait() { + return getStateID().isEqual(StateID_CircleWait); +} + +bool dAcObjGirahimuKnife_c::lineCheck() { + mVec3_c start, end; + start = mPosition; + mMtx_c m0 = field_0x714; + + mVec3_c offset(0.0f, 0.0f, -72.0f); + m0.multVec(offset, offset); + offset += mPosition; + + start = offset; + end = mPosition; + + dBgS_ObjLinChk linChk; + linChk.Set(&start, &end, nullptr); + if (dBgS::GetInstance()->LineCross(&linChk)) { + mPosition.set(linChk.GetLinEnd()); + mVelocity.set(0.0f, 0.0f, 0.0f); + return true; + } + + return false; +} + +void dAcObjGirahimuKnife_c::updateMdlMatrix() { + mRotation.z = 0x4000; + mWorldMtx.transS(mPosition.x, mPosition.y + field_0x774 * mAng(field_0x778).sin(), mPosition.z); + mWorldMtx.concat(field_0x714); + mWorldMtx.ZXYrotM(mRotation); + mWorldMtx.scaleM(field_0x75C); + mMdl.setLocalMtx(mWorldMtx); +} + +void dAcObjGirahimuKnife_c::startEmitters() { + if (!field_0x792 && cM::isZero(VEC3LenSq(mVelocity))) { + return; + } + mGlowEmitterId = PARTICLE_RESOURCE_ID_MAPPING_686_; + mGlowEmitter.holdEffect(mGlowEmitterId, mWorldMtx, nullptr, nullptr); + if (field_0x78C) { + mTrailEmitterId = PARTICLE_RESOURCE_ID_MAPPING_1_; + mWorldMtx.transM(0.0f, 0.0f, -30.0f); + mColor c0(0, 0, 0, 0xFF); + mColor c1(0, 0, 0, 0xFF); + mTrailEmitter.holdEffect(mTrailEmitterId, mWorldMtx, &c0, &c1); + mWorldMtx.transM(0.0f, 0.0f, 30.0f); + } +} + +void dAcObjGirahimuKnife_c::fn_239_2B10() { + someEnemyDamageCollisionStuffMaybe(mCollider, nullptr); + cCcD_Obj *pTgCc = mCollider.findTgHit(); + if (pTgCc == &mSph0) { + switch (mSph0.GetTgAtHitType()) { + case AT_TYPE_SWORD: + case AT_TYPE_0x800000: { + if (getStateID().isEqual(StateID_CircleWait)) { + if (checkCutDir(mSph0.GetTgAtCutDir())) { + field_0x78D = true; + sSomething2 = 0; + changeState(StateID_Return); + } else if (field_0x792) { + mVec3_c force; + getReflectForce(mSph0, 20.0f, force); + force.rotY(dAcPy_c::GetLink()->mRotation.y); + mVelocity.set(force); + } else { + mVec3_c force; + getReflectForce(mSph0, 100.0f + cM::rndF(20.0f), force); + force.rotY(dAcPy_c::GetLink()->mRotation.y); + mVelocity.set(force); + changeState(StateID_Hit); + } + } else if (isWaiting()) { + mVec3_c force; + getReflectForce(mSph0, 100.0f + cM::rndF(20.0f), force); + force.rotY(dAcPy_c::GetLink()->mRotation.y); + mVelocity.set(force); + changeState(StateID_Hit); + } else if (checkCutDir(mSph0.GetTgAtCutDir())) { + field_0x78D = true; + sSomething2 = 0; + changeState(StateID_Return); + } else { + mVec3_c force; + getReflectForce(mSph0, 100.0f + cM::rndF(20.0f), force); + force.rotY(dAcPy_c::GetLink()->mRotation.y); + mVelocity.set(force); + if (mState == 8) { + field_0x793 = false; + } else { + sSomething2 = 0; + } + changeState(StateID_Hit); + } + } break; + case AT_TYPE_BELLOWS: { + mVec3_c force(0.0f, 0.0f, 100.0f + cM::rndF(20.0f)); + force.rotY(dAcPy_c::GetLink()->mRotation.y); + mVelocity.set(force); + changeState(StateID_Hit); + } break; + } + } + + cCcD_Obj *pAtCc = mCollider.findAtHit(); + if (pAtCc != nullptr) { + if (pAtCc->GetAtFlag0x8()) { + if (mState == 8) { + mVec3_c force = mPosition - dAcPy_c::GetLink()->mPosition; + force.y = 0.0f; + force.normalizeRS(); + adjustVelocity(force, 10.0f, 0.2f); + changeState(StateID_Hit); + } else { + field_0x78D = true; + changeState(StateID_Return); + } + } else if (pAtCc->GetAtFlag0x2()) { + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + s16 angY = cLib::targetAngleY(pPlayer->mPosition, mPosition); + s16 diff = pPlayer->mRotation.y - angY; + mVec3_c force(0.0f, 0.0f, 1.0f); + if (diff >= 0) { + force.rotY(dAcPy_c::GetLink()->mRotation.y + -0x2000); + } else { + force.rotY(dAcPy_c::GetLink()->mRotation.y + 0x2000); + } + adjustVelocity(force, 10.0f, 1.0f); + changeState(StateID_Hit); + } + } +} + +bool dAcObjGirahimuKnife_c::checkCutDir(s32 cutDir) { + if (!field_0x78F) { + return false; + } + if (dAcPy_c::GetLink()->isAttackingSpin() && dAcPy_c::GetLink()->isAttackingHorizontal()) { + if (field_0x784 == 0 || field_0x784 == 6) { + return true; + } + } + if (dAcPy_c::GetLink()->isAttackingSpin() && dAcPy_c::GetLink()->isAttackingVertical()) { + if (field_0x784 == 3 || field_0x784 == 7) { + return true; + } + } + + switch (cutDir) { + case CUT_DIR_U: + case CUT_DIR_D: + if (field_0x784 == 3) { + return true; + } + break; + + case CUT_DIR_RD: + case CUT_DIR_LU: + if (field_0x784 == 2) { + return true; + } + break; + + case CUT_DIR_R: + case CUT_DIR_L: + if (field_0x784 == 0) { + return true; + } + break; + + case CUT_DIR_RU: + case CUT_DIR_LD: + if (field_0x784 == 1) { + return true; + } + break; + + case CUT_DIR_STAB: break; + } + return false; +} + +void dAcObjGirahimuKnife_c::setWait() { + mState = 9; + changeState(StateID_Wait); +} + +void dAcObjGirahimuKnife_c::setSpinWaitPreAttack() { + changeState(StateID_SpinWaitPreAttack); +} +void dAcObjGirahimuKnife_c::getReflectForce(cCcD_Obj &cc, f32 forceMult, mVec3_c &outforce) { + mVec3_c force; + switch (cc.GetTgAtCutDir()) { + case CUT_DIR_U: force.set(0.0f, -0.5f, 0.5f); break; + case CUT_DIR_D: force.set(0.0f, 0.5f, 0.5f); break; + case CUT_DIR_LU: force.set(-0.5f, -0.5f, 0.5f); break; + case CUT_DIR_RD: force.set(0.5f, 0.5f, 0.5f); break; + case CUT_DIR_L: force.set(-0.5f, 0.0f, 0.5f); break; + case CUT_DIR_R: force.set(0.5f, 0.0f, 0.5f); break; + case CUT_DIR_LD: force.set(-0.5f, 0.5f, 0.5f); break; + case CUT_DIR_RU: force.set(0.5f, -0.5f, 0.5f); break; + default: force.set(0.0f, 0.0f, 1.0f); break; + } + force.normalizeRS(); + force *= forceMult; + outforce.set(force); +} + +void dAcObjGirahimuKnife_c::adjustVelocity(const mVec3_c &force, f32 yVel, f32 forwardVel) { + mVec3_c v0(-mVelocity.x, 0.0f, -mVelocity.z); + + s32 dirVel = v0.atan2sX_Z(); + s32 dirForce = force.atan2sX_Z(); + mAng diff = (s32)(dirVel - dirForce); + + f32 norm = nw4r::math::FAbs(diff.normal_c()); + if (norm <= 0.1f) { + norm = 0.1f; + } + if (norm >= 1.0f) { + norm = 1.0f; + } + + f32 mag = 2.0f * v0.dot(force) / force.mag(); + mVelocity = force * mag - v0; + mVelocity.x *= forwardVel + norm; + mVelocity.y = yVel; + mVelocity.z *= forwardVel + norm; +}