diff --git a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt index c7c6c668..cc5828a9 100644 --- a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt +++ b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt @@ -30,8 +30,8 @@ doDelete__14dAcBlastboss_cFv = .text:0x000015A0; // type:function size:0x34 actorExecute__14dAcBlastboss_cFv = .text:0x000015E0; // type:function size:0x17A8 executeState__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00002D90; // type:function size:0x10 getStateID__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00002DA0; // type:function size:0x10 -fn_143_2DB0 = .text:0x00002DB0; // type:function size:0x48 -fn_143_2E00 = .text:0x00002E00; // type:function size:0x4C +ChkAtHit__10dCcD_CheckFv = .text:0x00002DB0; // type:function size:0x48 +ChkTgHit__10dCcD_CheckFv = .text:0x00002E00; // type:function size:0x4C timingB__Q214dAcBlastboss_c10callback_cFUlPQ34nw4r3g3d13WorldMtxManipQ34nw4r3g3d6ResMdl = .text:0x00002E50; // type:function size:0x85C initializeState_Fight__14dAcBlastboss_cFv = .text:0x000036B0; // type:function size:0xBC executeState_Fight__14dAcBlastboss_cFv = .text:0x00003770; // type:function size:0x718 @@ -75,23 +75,23 @@ finalizeState_Stun__14dAcBlastboss_cFv = .text:0x00006490; // type:function size initializeState_ThunderWait__14dAcBlastboss_cFv = .text:0x000064A0; // type:function size:0x54 executeState_ThunderWait__14dAcBlastboss_cFv = .text:0x00006500; // type:function size:0x204 finalizeState_ThunderWait__14dAcBlastboss_cFv = .text:0x00006710; // type:function size:0x4 -fn_143_6720 = .text:0x00006720; // type:function size:0xBB4 +fn_143_6720__14dAcBlastboss_cFv = .text:0x00006720; // type:function size:0xBB4 fn_143_72E0 = .text:0x000072E0; // type:function size:0x1C setAnm__14dAcBlastboss_cFPCcf = .text:0x00007300; // type:function size:0x58 forceSetAnm__14dAcBlastboss_cFPCcf = .text:0x00007360; // type:function size:0x50 setAnmRate__14dAcBlastboss_cFf = .text:0x000073B0; // type:function size:0x10 draw__14dAcBlastboss_cFv = .text:0x000073C0; // type:function size:0x60 -fn_143_7420 = .text:0x00007420; // type:function size:0x17C -fn_143_75A0 = .text:0x000075A0; // type:function size:0x218 -fn_143_77C0 = .text:0x000077C0; // type:function size:0x338 -fn_143_7B00 = .text:0x00007B00; // type:function size:0x478 -fn_143_7F80 = .text:0x00007F80; // type:function size:0x674 +fn_143_7420__14dAcBlastboss_cFv = .text:0x00007420; // type:function size:0x17C +fn_143_75A0__14dAcBlastboss_cFv = .text:0x000075A0; // type:function size:0x218 +fn_143_77C0__14dAcBlastboss_cFv = .text:0x000077C0; // type:function size:0x338 +fn_143_7B00__14dAcBlastboss_cFv = .text:0x00007B00; // type:function size:0x478 +fn_143_7F80__14dAcBlastboss_cFv = .text:0x00007F80; // type:function size:0x674 fn_143_8600 = .text:0x00008600; // type:function size:0x860 fn_143_8E60 = .text:0x00008E60; // type:function size:0x5B4 -fn_143_9420 = .text:0x00009420; // type:function size:0x148 +fn_143_9420__14dAcBlastboss_cFv = .text:0x00009420; // type:function size:0x148 fn_143_9570 = .text:0x00009570; // type:function size:0x9C -fn_143_9610 = .text:0x00009610; // type:function size:0xAF4 -fn_143_A110 = .text:0x0000A110; // type:function size:0xBC +fn_143_9610__14dAcBlastboss_cFv = .text:0x00009610; // type:function size:0xAF4 +fn_143_A110__14dAcBlastboss_cFl = .text:0x0000A110; // type:function size:0xBC vt_0x88__11dAcEnBase_cFi = .text:0x0000A1D0; // type:function size:0x8 vt_0x84__11dAcEnBase_cFv = .text:0x0000A1E0; // type:function size:0x4 vt_0x80__11dAcEnBase_cFv = .text:0x0000A1F0; // type:function size:0x4 @@ -151,10 +151,12 @@ sSrcSph = .data:0x000000F8; // type:object size:0x2C lbl_143_data_124 = .data:0x00000124; // type:object size:0x7C lbl_143_data_1A0 = .data:0x000001A0; // type:object size:0x10 data:string lbl_143_data_1B0 = .data:0x000001B0; // type:object size:0x28 -lbl_143_data_1D8 = .data:0x000001D8; // type:object size:0x70 +lbl_143_data_1D8 = .data:0x000001D8; // type:object size:0xC data:string +lbl_143_data_1E4 = .data:0x000001E4; // type:object size:0x64 lbl_143_data_248 = .data:0x00000248; // type:object size:0xE data:string lbl_143_data_258 = .data:0x00000258; // type:object size:0x4 data:4byte -lbl_143_data_25C = .data:0x0000025C; // type:object size:0x1C +lbl_143_data_25C = .data:0x0000025C; // type:object size:0x7 data:string +lbl_143_data_264 = .data:0x00000264; // type:object size:0x14 lbl_143_data_278 = .data:0x00000278; // type:object size:0x20 lbl_143_data_298 = .data:0x00000298; // type:object size:0x11 data:string lbl_143_data_2AC = .data:0x000002AC; // type:object size:0x4 data:4byte diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9bc3f409..ee6830f9 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1188,7 +1188,7 @@ fn_80030820 = .text:0x80030820; // type:function size:0x14 fn_80030840 = .text:0x80030840; // type:function size:0x13C fn_80030980 = .text:0x80030980; // type:function size:0x188 fn_80030B10 = .text:0x80030B10; // type:function size:0x10C -fn_80030C20 = .text:0x80030C20; // type:function size:0x28 +fn_80030c20__11dAcEnBase_cFUlffff = .text:0x80030C20; // type:function size:0x28 fn_80030C50 = .text:0x80030C50; // type:function size:0x8 fn_80030C60 = .text:0x80030C60; // type:function size:0x4 fn_80030C70 = .text:0x80030C70; // type:function size:0x4 @@ -3052,13 +3052,13 @@ calc__26dSwordSwingEffectProcMgr_cFRC7mVec3_cRC7mVec3_c = .text:0x8006B310; // t entry__26dSwordSwingEffectProcMgr_cFv = .text:0x8006B3B0; // type:function size:0x10 create__16dEnemySwordMdl_cFP12mAllocator_cPvPCcUlRC7mVec3_cRC7mVec3_cR9cCcD_SttsPQ23EGG7ResTIMGiPUl = .text:0x8006B3C0; // type:function size:0x140 create__16dEnemySwordMdl_cFP12mAllocator_cQ34nw4r3g3d7ResFilePCcUlRC7mVec3_cRC7mVec3_cR9cCcD_SttsPQ23EGG7ResTIMGiPUl = .text:0x8006B500; // type:function size:0x13C -fn_8006B640__16dEnemySwordMdl_cFv = .text:0x8006B640; // type:function size:0x20 +enableAttack__16dEnemySwordMdl_cFv = .text:0x8006B640; // type:function size:0x20 fn_8006B660__16dEnemySwordMdl_cFiiiiiiiiif = .text:0x8006B660; // type:function size:0xB4 -fn_8006B720 = .text:0x8006B720; // type:function size:0x10 +setDamageMaybe__16dEnemySwordMdl_cFUc = .text:0x8006B720; // type:function size:0x10 fn_8006B730 = .text:0x8006B730; // type:function size:0x5C fn_8006B790 = .text:0x8006B790; // type:function size:0x10 -fn_8006B7A0 = .text:0x8006B7A0; // type:function size:0x5C -fn_8006B800 = .text:0x8006B800; // type:function size:0x10 +fn_8006B7A0__16dEnemySwordMdl_cFUl = .text:0x8006B7A0; // type:function size:0x5C +fn_8006B800__16dEnemySwordMdl_cFUl = .text:0x8006B800; // type:function size:0x10 fn_8006B810 = .text:0x8006B810; // type:function size:0x5C fn_8006B870 = .text:0x8006B870; // type:function size:0x10 calc__16dEnemySwordMdl_cFRC6mMtx_cRC7mVec3_cb = .text:0x8006B880; // type:function size:0x2A8 @@ -10578,7 +10578,7 @@ isSTIFAreaEldin__11dStageMgr_cCFv = .text:0x80199AA0; // type:function size:0x3C isSTIFAreaLanayru__11dStageMgr_cCFv = .text:0x80199AE0; // type:function size:0x3C getSTIFunk1__11dStageMgr_cCFv = .text:0x80199B20; // type:function size:0x20 getSTIFRoomType__11dStageMgr_cCFv = .text:0x80199B40; // type:function size:0x1C -fn_80199B60 = .text:0x80199B60; // type:function size:0xC +fn_80199B60__11dStageMgr_cFUc = .text:0x80199B60; // type:function size:0xC fn_80199B70 = .text:0x80199B70; // type:function size:0x1C fn_80199B90 = .text:0x80199B90; // type:function size:0x3A8 fn_80199F40 = .text:0x80199F40; // type:function size:0x90 diff --git a/include/d/a/b/d_a_b_lastboss.h b/include/d/a/b/d_a_b_lastboss.h index 0097aeec..e1831a06 100644 --- a/include/d/a/b/d_a_b_lastboss.h +++ b/include/d/a/b/d_a_b_lastboss.h @@ -202,12 +202,18 @@ class dAcBlastboss_c : public dAcEnBase_c { B_LAST_BOSS_NODE_skirtHU1 = 134, }; + // TODO: mFightState probably means different things in + // different states, so maybe we need to either remove + // this again or split this up further. enum FightState_e { - FIGHT_STATE_0, + FIGHT_STATE_0 = 0, FIGHT_STATE_1, FIGHT_STATE_2, FIGHT_STATE_3, FIGHT_STATE_4, + + FIGHT_STATE_10 = 10, + FIGHT_STATE_11, }; public: @@ -246,6 +252,7 @@ private: bool fn_143_77C0(); void fn_143_7B00(); void fn_143_7F80(); + bool fn_143_9420(); void fn_143_9610(); void fn_143_A110(s32); @@ -284,7 +291,7 @@ private: /* 0x1141 */ u8 field_0x1141; /* 0x1142 */ u8 field_0x1142; /* 0x1143 */ u8 field_0x1143; - /* 0x1144 */ u8 field_0x1144; + /* 0x1144 */ s8 field_0x1144; /* 0x1145 */ u8 field_0x1145; /* 0x1146 */ bool mIsSwordEmpowered; /* 0x1147 */ u8 field_0x1147; @@ -297,9 +304,8 @@ private: /* 0x114E */ u8 field_0x114E; /* 0x114F */ u8 field_0x114F; /* 0x1150 */ u8 field_0x1150; - - /* 0x1151 */ u8 _0x1151[0x1156 - 0x1151]; - + /* 0x1152 */ u16 field_0x1152; + /* 0x1154 */ u16 field_0x1154; /* 0x1156 */ u16 field_0x1156[6]; /* 0x1162 */ u8 _0x1162[0x1164 - 0x1162]; @@ -346,7 +352,9 @@ private: /* 0x11B0 */ f32 field_0x11B0; - /* 0x11B4 */ u8 _0x11B4[0x11BC - 0x11B4]; + /* 0x11B4 */ u8 _0x11B4[0x11B8 - 0x11B4]; + + /* 0x11B8 */ f32 field_0x11B8; /* 0x11BC */ f32 field_0x11BC; /* 0x11C0 */ f32 field_0x11C0; diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 69fe1e20..06b81841 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -992,6 +992,9 @@ public: void ClrTg_0x10000() { return mTg.OffSPrm(0x10000); } + void ClrTg_0x8000000() { + return mTg.OffSPrm(0x8000000); + } u32 ChkTgBonk() const { return mTg.MskSPrm(0x200000); } diff --git a/include/d/d_cc.h b/include/d/d_cc.h index ddc9803e..c06a35e5 100644 --- a/include/d/d_cc.h +++ b/include/d/d_cc.h @@ -84,7 +84,8 @@ public: // a ptmf. It's not immediately clear how this works, // does every actor subclass the LinkedCollider___, // or are the functions all added here for the other - // files to implement? + // files to implement? d_a_b_lastboss commits a typing crime here + // to make it work... typedef bool (cCcD_Obj::*ccPtmf)(); cCcD_Obj *find(ccPtmf f) const; diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 2a948aa8..621b3cc2 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -463,6 +463,19 @@ public: ATTACK_FINAL_BLOW = 11, }; + enum SpecificPlayerAttackDirection_e { + /* 0x000 */ ATTACK_DIRECTION_NONE = 0, + /* 0x001 */ ATTACK_DIRECTION_DOWN = 1 << 0, + /* 0x002 */ ATTACK_DIRECTION_DOWNRIGHT = 1 << 1, + /* 0x004 */ ATTACK_DIRECTION_RIGHT = 1 << 2, + /* 0x008 */ ATTACK_DIRECTION_UPRIGHT = 1 << 3, + /* 0x010 */ ATTACK_DIRECTION_UP = 1 << 4, + /* 0x020 */ ATTACK_DIRECTION_UPLEFT = 1 << 5, + /* 0x040 */ ATTACK_DIRECTION_LEFT = 1 << 6, + /* 0x080 */ ATTACK_DIRECTION_DOWNLEFT = 1 << 7, + /* 0x100 */ ATTACK_DIRECTION_STAB = 1 << 8, + }; + enum ModelUpdateFlags_e { UPDATE_MODEL_SWORD = 0x20, UPDATE_MODEL_SHIELD = 0x40, @@ -625,6 +638,14 @@ public: return mAttackDirection != ATTACK_NONE; } + bool isAttackingJumpSlash() const { + return mAttackDirection == ATTACK_JUMP_SLASH; + } + + u16 getSpecificAttackDirection() const { + return mSpecificAttackDirection; + } + inline bool hasvt_0x1C0() const { return vt_0x1C0() != nullptr; } @@ -637,6 +658,9 @@ public: bool isAttackingStab() const; bool isAttackingSpinHorizontal() const; bool isAttackingSpinVertical() const; + bool isAttackingSpin() const { + return isAttackingSpinHorizontal() || isAttackingSpinVertical(); + } 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); @@ -668,7 +692,8 @@ protected: /* 0x334 */ f32 field_0x334; /* 0x338 */ u8 mAttackDirection; /* 0x339 */ u8 mRidingActorType; - /* 0x33A */ u8 unk_0x33A[0x340 - 0x33A]; + /* 0x33A */ u16 mSpecificAttackDirection; + /* 0x33C */ u8 unk_0x33C[0x340 - 0x33C]; /* 0x340 */ u32 someFlags_0x340; /* 0x344 */ u32 mFaceUpdateFlags; /* 0x348 */ u32 mSwordAndMoreStates; diff --git a/include/toBeSorted/d_enemy_sword_mdl.h b/include/toBeSorted/d_enemy_sword_mdl.h index 96989e51..40883513 100644 --- a/include/toBeSorted/d_enemy_sword_mdl.h +++ b/include/toBeSorted/d_enemy_sword_mdl.h @@ -21,8 +21,8 @@ public: /* 0x01C */ dSwordSwingEffectProcMgr_c mProc; private: - /* 0x070 */ bool field_0x070; - /* 0x071 */ bool field_0x071; + /* 0x070 */ bool mIsActive; + /* 0x071 */ bool mFirstFramePassed; /* 0x074 */ mVec3_c field_0x074; /* 0x080 */ mVec3_c field_0x080; /* 0x08C */ mVec3_c field_0x08C; @@ -30,6 +30,8 @@ private: /* 0x0A4 */ f32 field_0x0A4; /* 0x0A8 */ f32 field_0x0A8; /* 0x0AC */ dCcD_Linked_Cps mCcs[3]; + +public: /* 0x52C */ dColliderLinkedList mCcList; public: @@ -53,11 +55,19 @@ public: } bool entry(dAcObjBase_c *obj, dShadowCircle_c *shadow, mQuat_c *quat); - void fn_8006B640(); + void enableAttack(); void fn_8006B660(UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, f32); + void setDamageMaybe(u8 damage); + void fn_8006B7A0(u32); + void fn_8006B800(u32); - void setAttackActive(bool b) { - field_0x070 = b; + void enable() { + enableAttack(); + mProc.setActive(true); + } + + void disable() { + mIsActive = false; mProc.setActive(false); } }; diff --git a/src/REL/d/a/b/d_a_b_lastboss.cpp b/src/REL/d/a/b/d_a_b_lastboss.cpp index 46d595b3..a16ed5e3 100644 --- a/src/REL/d/a/b/d_a_b_lastboss.cpp +++ b/src/REL/d/a/b/d_a_b_lastboss.cpp @@ -5,13 +5,15 @@ #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/col/c/c_cc_d.h" #include "d/col/cc/d_cc_s.h" #include "d/d_base.h" +#include "d/d_cc.h" #include "d/d_light_env.h" +#include "d/d_player_act.h" #include "d/d_rumble.h" #include "d/d_sc_game.h" #include "d/d_stage_mgr.h" -#include "d/d_vec.h" #include "d/flag/sceneflag_manager.h" #include "d/snd/d_snd_wzsound.h" #include "d/t/d_t_sword_battle_game.h" @@ -291,7 +293,7 @@ int dAcBlastboss_c::actorExecute() { mXZDistanceToLink = link->getPosition().absXZTo(mPosition); mYRotationRelativeToLink = mYAngleToLink - mRotation.y; - mSwordMdl.setAttackActive(false); + mSwordMdl.disable(); mCc4.ClrAtSet(); mCc5.ClrAtSet(); @@ -644,7 +646,7 @@ int dAcBlastboss_c::actorExecute() { } else { fn_143_A110(100); } - sLib::addCalcScaledDiff(&field_0x11CC, 1.0f, 1.0f, 0.1f); + sLib::addCalcScaledDiff(&field_0x11CC, 1.0f, 1.0f, 0.01f); } // TODO: inline doesn't work :( @@ -764,6 +766,25 @@ int dAcBlastboss_c::actorExecute() { return SUCCEEDED; } +struct dCcD_Check : public cCcD_Obj { + bool ChkAtHit(); + bool ChkTgHit(); +}; + +bool dCcD_Check::ChkAtHit() { + if (cCcD_Obj::ChkAtHit()) { + return true; + } + return false; +} + +bool dCcD_Check::ChkTgHit() { + if (cCcD_Obj::ChkTgHit()) { + return true; + } + return false; +} + void dAcBlastboss_c::callback_c::timingB(u32 nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl mdl) { u32 baseNodeIdSkirt = 0; u32 baseNodeIdHair = 0; @@ -1054,7 +1075,7 @@ void dAcBlastboss_c::executeState_Fight() { } field_0x1172 = diff / 2; // TODO what is this constant - sLib::addCalcScaledDiff(&mMdlCallback.field_0x30, diff * (1.0f / 409.6f), 0.5f, 1.0f); + sLib::addCalcScaledDiff(&mMdlCallback.field_0x30, diff * (1.0f / 409.59937f), 0.5f, 1.0f); if (field_0x2CEC == 0 && !link->isUsingShield() && link->isUsingSword()) { mMtx_c rotMtx; rotMtx.YrotS(-mYAngleToLink); @@ -1076,8 +1097,8 @@ void dAcBlastboss_c::executeState_Fight() { sLib::addCalcAngle(mMdlCallback.field_0x1A.ref(), mAng(v.y * -40.0f), 2, field_0x118A); } else { field_0x118A = 0; - sLib::addCalcAngle(mMdlCallback.field_0x18.ref(),0, 4, 400); - sLib::addCalcAngle(mMdlCallback.field_0x1A.ref(),0, 4, 400); + sLib::addCalcAngle(mMdlCallback.field_0x18.ref(), 0, 4, 400); + sLib::addCalcAngle(mMdlCallback.field_0x1A.ref(), 0, 4, 400); } field_0x1133 = 1; } @@ -1087,11 +1108,10 @@ void dAcBlastboss_c::executeState_Fight() { fn_143_7420(); fn_143_77C0(); } - // TODO - mCc1.mTg.mSrc.field_0x0E = 0x1FF; + mCc1.SetTgFlag_0xA(0x1FF); } else { // TODO - mCc1.mTg.mSrc.field_0x0E = 0; + mCc1.SetTgFlag_0xA(0); } if (field_0x1156[4] == 1) { @@ -1105,38 +1125,493 @@ void dAcBlastboss_c::executeState_Fight() { } void dAcBlastboss_c::finalizeState_Fight() {} -void dAcBlastboss_c::initializeState_Guard() {} -void dAcBlastboss_c::executeState_Guard() {} +void dAcBlastboss_c::initializeState_Attack() { + f32 rnd = cM::rnd(); + mFightState = FIGHT_STATE_0; + if (rnd < 0.3333f) { + setAnm("AttackU", 5.0f); + } else if (rnd < 0.6666f) { + setAnm("AttackR", 5.0f); + } else { + setAnm("AttackL", 5.0f); + } + + if (mIsSwordEmpowered) { + mSwordMdl.setDamageMaybe(8); + } else { + mSwordMdl.setDamageMaybe(4); + } + mSwordMdl.fn_8006B7A0(0x20000); +} +void dAcBlastboss_c::executeState_Attack() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + field_0x1131 = 1; + f32 speed = 0.0f; + // TODO major typing crime here but I'm not sure how this actually works + cCcD_Obj *atHit = mSwordMdl.mCcList.find((dColliderLinkedList::ccPtmf)&dCcD_Check::ChkAtHit); + + switch (mFightState) { + case FIGHT_STATE_0: { + if (field_0x1152 >= 15 && mMdl.getAnm().checkFrame(7.0f) && cM::rnd() < 0.1f) { + mStateMgr.changeState(StateID_Fight); + field_0x113F = 20; + } else { + if (mMdl.getAnm().getFrame() < 20.0f) { + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x800); + } + + if (mMdl.getAnm().getFrame() >= 25.0f && mMdl.getAnm().getFrame() <= 28.0f) { + mSwordMdl.enable(); + speed = 20.0f; + field_0x11A4 = 20.0f; + field_0x113D = 10; + } + if (atHit != nullptr) { + mFightState = FIGHT_STATE_1; + } else { + if (mMdl.getAnm().getFrame() > 28.0f) { + mFightState = FIGHT_STATE_1; + if (field_0x113E != 0) { + setAnmRate(0.5f); + } + } + } + } + break; + } + case FIGHT_STATE_1: { + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + break; + } + } + + mSpeed = speed; + if (!field_0x1149 && link->checkCurrentAction(/* BACKFLIP */ 0x62)) { + field_0x113E = 20; + } + if (field_0x113E != 0) { + if (field_0x1149) { + mFightState = FIGHT_STATE_0; + mStateMgr.changeState(StateID_CounterAttack); + return; + } + mCc1.SetTgFlag_0xA(0); + } else { + if (mpCurrentAnm == "AttackR") { + mCc1.SetTgFlag_0xA(0xE); + } else if (mpCurrentAnm == "AttackL") { + mCc1.SetTgFlag_0xA(0xE0); + } else { + mCc1.SetTgFlag_0xA(1); + } + } + fn_143_77C0(); +} +void dAcBlastboss_c::finalizeState_Attack() {} + +void dAcBlastboss_c::initializeState_CounterAttack() { + mSwordMdl.fn_8006B7A0(0x20000); + if (mFightState == 0) { + setAnm("Counter", 5.0f); + } else { + f32 rnd = cM::rnd(); + if (rnd < 0.3333f) { + setAnm("AttackU", 5.0f); + } else if (rnd < 0.6666f) { + setAnm("AttackR", 5.0f); + } else { + setAnm("AttackL", 5.0f); + } + mMdl.setFrame(5.0f); + } + + field_0x1136 = 0; + field_0x1135 = 0; + field_0x11D4 = field_0x11D8 = -1; +} +void dAcBlastboss_c::executeState_CounterAttack() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + f32 speed = 0.0f; + bool b = false; + field_0x1131 = 1; + if (mFightState == FIGHT_STATE_0) { + if (mMdl.getAnm().getFrame() < 15.0f) { + speed = -10.0f; + } + if (mMdl.getAnm().getFrame() < 10.0f || + (mMdl.getAnm().getFrame() > 30.0f && mMdl.getAnm().getFrame() < 40.0f)) { + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x800); + } + + if ((mMdl.getAnm().getFrame() >= 20.0f && mMdl.getAnm().getFrame() <= 23.0f) || + (mMdl.getAnm().getFrame() >= 43.0f && mMdl.getAnm().getFrame() <= 47.0f)) { + mSwordMdl.enable(); + speed = 30.0f; + field_0x11A4 = 20.0f; + } + + int targetFrame = 42; + if (mMdl.getAnm().checkFrame(targetFrame) && mXZDistanceToLink > 400.0f) { + mStateMgr.changeState(StateID_Fight); + return; + } + if (mMdl.getAnm().getFrame() >= 52.0f) { + b = true; + } + } else { + if (mMdl.getAnm().getFrame() < 20.0f) { + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x800); + } + if (mMdl.getAnm().getFrame() >= 25.0f && mMdl.getAnm().getFrame() <= 28.0f) { + mSwordMdl.enable(); + speed = 10.0f; + field_0x11A4 = 20.0f; + field_0x113D = 5; + } + if (mMdl.getAnm().getFrame() >= 33.0f) { + b = true; + } + } + + if (link->checkCurrentAction(/* BACKFLIP */ 0x62)) { + field_0x113E = 20; + } + mCc1.SetTgFlag_0xA(0); + if (field_0x113E != 0) { + field_0x1142 = 0; + field_0x1134 = 0; + } else if (b) { + mCc1.SetTgFlag_0xA(0x1FF); + field_0x1142 = 0; + fn_143_77C0(); + } + + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + mSpeed = speed; +} +void dAcBlastboss_c::finalizeState_CounterAttack() {} + +void dAcBlastboss_c::initializeState_PunchAttack() { + setAnm("AttackBreak", 5.0f); + mSwordMdl.fn_8006B7A0(0x20000); + mFightState = 0; +} +void dAcBlastboss_c::executeState_PunchAttack() { + f32 speed = 0.0f; + field_0x1131 = 1; + mCc1.SetTgFlag_0xA(0); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x800); + if (mMdl.getAnm().getFrame() < 15.0f) { + speed = -10.0f; + } + if (mMdl.getAnm().getFrame() >= 15.0f && mMdl.getAnm().getFrame() <= 23.0f) { + speed = 40.0f; + } + if (mMdl.getAnm().checkFrame(15.0f)) { + field_0x1139 = 1; + } + if (mMdl.getAnm().checkFrame(23.0f)) { + field_0x1139 = 0; + } + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + mSpeed = speed; +} +void dAcBlastboss_c::finalizeState_PunchAttack() {} + +void dAcBlastboss_c::initializeState_DashAttack() { + mFightState = 0; + mSwordMdl.setDamageMaybe(8); + mSwordMdl.fn_8006B7A0(0x20000); +} +void dAcBlastboss_c::executeState_DashAttack() { + field_0x1131 = 1; + f32 targetSpeed = 0.0f; + f32 stepSize = 40.0f; // never set differently + mCc1.SetTgFlag_0xA(0x1FF); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x1000); + switch (mFightState) { + case FIGHT_STATE_0: { + if (mXZDistanceToLink < 400.0f) { + mStateMgr.changeState(StateID_CounterAttack); + return; + } + setAnm("AttackJumpStart", 5.0f); + mSwordMdl.fn_8006B7A0(0x20000); + mFightState = FIGHT_STATE_1; + // fall-through + } + case FIGHT_STATE_1: { + if (mMdl.getAnm().getFrame() >= 23.0f) { + field_0x11A4 = 30.0f; + targetSpeed = 40.0f; + } + if (mMdl.getAnm().isStop()) { + setAnm("AttackJumpLoop", 0.0f); + mFightState = FIGHT_STATE_2; + field_0x1156[0] = 200; + } + break; + } + case FIGHT_STATE_2: { + field_0x11A4 = 30.0f; + targetSpeed = 80.0f; + field_0x11B8 = 5.0f; + if (mXZDistanceToLink < 750.0f) { + setAnm("AttackJumpEnd", 0.0f); + mFightState = FIGHT_STATE_3; + } else if (field_0x1156[0] == 0) { + mStateMgr.changeState(StateID_Fight); + } + break; + } + case FIGHT_STATE_3: { + if (mXZDistanceToLink > 300.0f && mMdl.getAnm().getFrame() <= 6.0f) { + targetSpeed = 80.0f; + } else { + stepSize = 40.0f; + } + if (mMdl.getAnm().getFrame() >= 6.0f && mMdl.getAnm().getFrame() <= 9.0f) { + mSwordMdl.enable(); + field_0x113D = 10; + } + + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + break; + } + } + + sLib::addCalcScaledDiff(&mSpeed, targetSpeed, 1.0f, stepSize); + if (mSpeed > 50.0f) { + // @bug: effect rotation never updated due to static... + static mAng3_c sEffRot(0, mRotation.y, 0); + static mVec3_c sEffScale(1.0f, 1.0f, 1.0f); + mVec3_c effPos(mPosition.x, 10.0f, mPosition.z); + mEmitter2.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_858_, effPos, &sEffRot, &sEffScale, nullptr, nullptr); + } +} +void dAcBlastboss_c::finalizeState_DashAttack() {} + +void dAcBlastboss_c::initializeState_SmallAttack() { + setAnm("AttackSwordBreak", 5.0f); + mFightState = FIGHT_STATE_0; +} +void dAcBlastboss_c::executeState_SmallAttack() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + field_0x1131 = 1; + f32 targetSpeed = 0.0f; + + mCc1.SetTgFlag_0xA(0); + switch (mFightState) { + case FIGHT_STATE_0: { + if (mMdl.getAnm().getFrame() >= 31.0f && mMdl.getAnm().getFrame() <= 33.0f) { + field_0x11A4 = 15.0f; + if (fn_143_9420()) { + mVec3_c effPos; + + effPos = link->vt_0x278() + (link->getSwordPos() - link->vt_0x278()) * 0.4f; + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_388_, effPos, &mRotation, nullptr, nullptr, nullptr, 0, 0 + ); + dRumble_c::start(dRumble_c::sRumblePreset4, dRumble_c::FLAG_SLOT0); + startSound(SE_BLasBos_SwordBySword); + link->onForceOrPreventActionFlags(0x80000); + mFightState = FIGHT_STATE_1; + } + } + break; + } + } + + if (mMdl.getAnm().checkFrame(44.0f) && mFightState != FIGHT_STATE_1) { + mStateMgr.changeState(StateID_Fight); + mpCurrentAnm = nullptr; + setAnm("WaitBt", 40.0f); + field_0x113E = 10; + field_0x1134 = 0; + } + + if (mMdl.getAnm().getFrame() >= 55.0f && mMdl.getAnm().getFrame() <= 59.0f) { + mSwordMdl.enable(); + targetSpeed = 40.0f; + field_0x11A4 = 20.0f; + } + + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + + sLib::addCalcScaledDiff(&mSpeed, targetSpeed, 1.0f, 20.0f); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x200); +} +void dAcBlastboss_c::finalizeState_SmallAttack() {} + +void dAcBlastboss_c::initializeState_ThunderAttack() { + setAnm("AttackThunder", 5.0f); + mFightState = FIGHT_STATE_0; +} +void dAcBlastboss_c::executeState_ThunderAttack() { + field_0x1131 = 1; + f32 targetSpeed = 0.0f; + mCc1.SetTgFlag_0xA(0); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x400); + if (mMdl.getAnm().getFrame() >= 21.0f && mMdl.getAnm().getFrame() <= 25.0f) { + mSwordMdl.enable(); + field_0x11A4 = 20.0f; + if (mMdl.getAnm().checkFrame(23.0f)) { + mIsSwordEmpowered = false; + mCc1.ClrTg_0x8000000(); + mSwordMdl.fn_8006B800(0); + field_0x1147 = 1; + field_0x1148 = 60; + field_0x1150 = 0; + field_0x11DC = mRotation; + mVec3_c v(0.0f, 100.0f, 300.0f); + mMtx_c mtx; + mtx.YrotS(mRotation.y); + MTXMultVec(mtx, v, field_0x1220); + field_0x1220 += mPosition; + + v.set(0.0f, 0.0f, 50.0f); + MTXMultVec(mtx, v, field_0x122C); + mCc5.setCenter(field_0x1220); + fn_143_A110(30); + startSound(SE_BLasBos_EmitThunderBeam); + } + } + if (mMdl.getAnm().isStop()) { + mStateMgr.changeState(StateID_Fight); + } + + sLib::addCalcScaledDiff(&mSpeed, targetSpeed, 1.0f, 5.0f); +} +void dAcBlastboss_c::finalizeState_ThunderAttack() {} + +void dAcBlastboss_c::initializeState_Guard() { + mFightState = FIGHT_STATE_0; + mMdlCallback.field_0x30 = 0.0f; + mMdlCallback.field_0x18 = 0; +} +void dAcBlastboss_c::executeState_Guard() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + field_0x1131 = 1; + f32 targetSpeed = 0.0f; + + static const char *sGuardNames[] = { + "GuardR", "GuardRU", "GuardRD", "GuardL", "GuardLU", "GuardLD", "GuardU", "GuardD", "GuardC", "WaitBt", + }; + + static const u32 sGuardFlags[] = {0xE, 0xE, 0x1E, 0xE0, 0xE0, 0xF0, 0x83, 0x38, 0x100, 0x1FF}; + + switch (mFightState) { + case FIGHT_STATE_0: { + if (link->isAttackingJumpSlash()) { + mFightState = FIGHT_STATE_2; + setAnm("WalkBt", 2.0f); + setAnmRate(-2.0f); + field_0x1156[0] = 5; + break; + } else { + if (field_0x1144 == 9) { + setAnm(sGuardNames[field_0x1144], 3.0f); + field_0x1156[0] = 14; + } else { + setAnm(sGuardNames[field_0x1144], 3.0f); + } + mFightState = FIGHT_STATE_1; + // fall-through + } + } + case FIGHT_STATE_1: { + if (link->isAttackingSpin()) { + field_0x1156[0] = 5; + } + + if (field_0x1144 == 9) { + field_0x1133 = 1; + if (field_0x1156[0] == 0) { + mStateMgr.changeState(StateID_Fight); + field_0x1156[4] = 15; + } + } else if (mMdl.getAnm().getFrame() >= 13.0f) { + mStateMgr.changeState(StateID_Fight); + field_0x1156[4] = 15; + } + + if (!link->isAttackingJumpSlash()) { + fn_143_77C0(); + } + break; + } + case FIGHT_STATE_2: { + field_0x11A4 = 20.0f; + targetSpeed = -30.0f; + if (field_0x1156[0] == 0) { + field_0x1144 = 6; + forceSetAnm(sGuardNames[field_0x1144], 3.0); + mFightState = FIGHT_STATE_1; + } + break; + } + case FIGHT_STATE_10: { + if (field_0x1144 == 0) { + setAnm("AttackRGuard", 3.0f); + } else if (field_0x1144 == 3) { + setAnm("AttackLGuard", 3.0f); + } else { + setAnm("GuardU", 3.0f); + } + mFightState = FIGHT_STATE_11; + // fall-through + } + case FIGHT_STATE_11: { + if (mMdl.getAnm().getFrame() >= 13.0f) { + mStateMgr.changeState(StateID_Fight); + field_0x1156[4] = 15; + } + break; + } + } + + sLib::addCalcScaledDiff(&mSpeed, targetSpeed, 1.0f, 5.0f); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, 0x1000); + + if (field_0x113E != 0) { + setAnmRate(0.2f); + } else { + setAnmRate(1.0f); + if (link->isAttacking()) { + switch (dAcPy_c::GetLinkM()->getSpecificAttackDirection()) { + case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: field_0x1144 = 6; break; + case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: field_0x1144 = 3; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: field_0x1144 = 4; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: field_0x1144 = 5; break; + case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: field_0x1144 = 0; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: field_0x1144 = 1; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: field_0x1144 = 2; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UP: field_0x1144 = 7; break; + default: field_0x1144 = 8; break; + } + setAnm(sGuardNames[field_0x1144], 3.0); + } + } + + mCc1.SetTgFlag_0xA(sGuardFlags[field_0x1144]); + fn_143_75A0(); +} void dAcBlastboss_c::finalizeState_Guard() {} void dAcBlastboss_c::initializeState_GuardBreak() {} void dAcBlastboss_c::executeState_GuardBreak() {} void dAcBlastboss_c::finalizeState_GuardBreak() {} -void dAcBlastboss_c::initializeState_Attack() {} -void dAcBlastboss_c::executeState_Attack() {} -void dAcBlastboss_c::finalizeState_Attack() {} - -void dAcBlastboss_c::initializeState_CounterAttack() {} -void dAcBlastboss_c::executeState_CounterAttack() {} -void dAcBlastboss_c::finalizeState_CounterAttack() {} - -void dAcBlastboss_c::initializeState_PunchAttack() {} -void dAcBlastboss_c::executeState_PunchAttack() {} -void dAcBlastboss_c::finalizeState_PunchAttack() {} - -void dAcBlastboss_c::initializeState_DashAttack() {} -void dAcBlastboss_c::executeState_DashAttack() {} -void dAcBlastboss_c::finalizeState_DashAttack() {} - -void dAcBlastboss_c::initializeState_SmallAttack() {} -void dAcBlastboss_c::executeState_SmallAttack() {} -void dAcBlastboss_c::finalizeState_SmallAttack() {} - -void dAcBlastboss_c::initializeState_ThunderAttack() {} -void dAcBlastboss_c::executeState_ThunderAttack() {} -void dAcBlastboss_c::finalizeState_ThunderAttack() {} - void dAcBlastboss_c::initializeState_Damage() {} void dAcBlastboss_c::executeState_Damage() {} void dAcBlastboss_c::finalizeState_Damage() {} diff --git a/src/toBeSorted/d_enemy_sword_mdl.cpp b/src/toBeSorted/d_enemy_sword_mdl.cpp index 563b8131..79856cc4 100644 --- a/src/toBeSorted/d_enemy_sword_mdl.cpp +++ b/src/toBeSorted/d_enemy_sword_mdl.cpp @@ -69,10 +69,10 @@ bool dEnemySwordMdl_c::create( return true; } -void dEnemySwordMdl_c::fn_8006B640() { +void dEnemySwordMdl_c::enableAttack() { mCcs[0].OnAtSet(); - field_0x070 = true; - field_0x071 = false; + mIsActive = true; + mFirstFramePassed = false; } // TODO - ... @@ -83,7 +83,7 @@ void dEnemySwordMdl_c::calc(const mMtx_c &mtx, const mVec3_c &v1, bool mass) { MTXMultVec(mtx, field_0x074, field_0x08C); MTXMultVec(mtx, field_0x080, field_0x098); - if (field_0x070) { + if (mIsActive) { mVec3_c v = field_0x098 - field_0x08C; v.normalize(); @@ -97,11 +97,11 @@ void dEnemySwordMdl_c::calc(const mMtx_c &mtx, const mVec3_c &v1, bool mass) { mCcs[1].SetAtVec(v1); mCcs[2].SetAtVec(v1); - if (field_0x071 && !mCcs[1].ChkAtSet()) { + if (mFirstFramePassed && !mCcs[1].ChkAtSet()) { mCcs[1].OnAtSet(); mCcs[2].OnAtSet(); } else { - field_0x071 = true; + mFirstFramePassed = true; } mCcList.registerColliders(); @@ -109,7 +109,7 @@ void dEnemySwordMdl_c::calc(const mMtx_c &mtx, const mVec3_c &v1, bool mass) { dCcS::GetInstance()->GetMassMng().SetObj(&mCcs[0], 2); } } else { - field_0x071 = false; + mFirstFramePassed = false; if (mCcs[0].ChkAtSet()) { mCcList.ClrAt(); }