diff --git a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt index 71f6c186..c7c6c668 100644 --- a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt +++ b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt @@ -77,9 +77,9 @@ executeState_ThunderWait__14dAcBlastboss_cFv = .text:0x00006500; // type:functio finalizeState_ThunderWait__14dAcBlastboss_cFv = .text:0x00006710; // type:function size:0x4 fn_143_6720 = .text:0x00006720; // type:function size:0xBB4 fn_143_72E0 = .text:0x000072E0; // type:function size:0x1C -fn_143_7300 = .text:0x00007300; // type:function size:0x58 -fn_143_7360 = .text:0x00007360; // type:function size:0x50 -fn_143_73B0 = .text:0x000073B0; // type:function size:0x10 +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 diff --git a/include/d/a/b/d_a_b_lastboss.h b/include/d/a/b/d_a_b_lastboss.h index 8f088a58..e2ea6bbf 100644 --- a/include/d/a/b/d_a_b_lastboss.h +++ b/include/d/a/b/d_a_b_lastboss.h @@ -43,11 +43,26 @@ class dAcBlastboss_c : public dAcEnBase_c { public: virtual void timingB(u32, nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl) override; - /* 0x04 */ s16 field_0x04; - /* 0x06 */ u8 _0x06[0x34 - 0x06]; + /* 0x04 */ mAng field_0x04; + /* 0x06 */ mAng field_0x06; + /* 0x08 */ mAng field_0x08; + /* 0x0A */ mAng field_0x0A; + /* 0x0C */ mAng field_0x0C; + /* 0x0E */ mAng field_0x0E; + /* 0x10 */ mAng field_0x10; + /* 0x12 */ mAng field_0x12; + /* 0x14 */ mAng field_0x14; + /* 0x16 */ mAng field_0x16; + /* 0x18 */ mAng field_0x18; + /* 0x1A */ mAng field_0x1A; + /* 0x1C */ mAng field_0x1C[9]; + /* 0x2E */ mAng field_0x2E; + /* 0x30 */ f32 field_0x30; /* 0x34 */ dAcBlastboss_c *mpOwner; }; + friend class callback_c; + // BLastBoss.arc > g3d > model.brres > 3DModels(NW4R) > LastBoss > Bones > ... enum BLastBossModelNode_e { B_LAST_BOSS_NODE_center = 0, @@ -214,10 +229,13 @@ public: private: void fn_143_6720(); - void fn_143_A110(s32); + void setAnm(const char *anim, f32 blend); + void forceSetAnm(const char *anim, f32 blend); + void setAnmRate(f32 rate); void fn_143_7B00(); void fn_143_7F80(); void fn_143_9610(); + void fn_143_A110(s32); /* 0x0378 */ d3d::AnmMdlWrapper mMdl; /* 0x03E8 */ m3d::anmTexSrt_c mAnmTexSrt; @@ -275,31 +293,42 @@ private: /* 0x1162 */ u8 _0x1162[0x1164 - 0x1162]; /* 0x1164 */ s16 field_0x1164; + /* 0x1166 */ s16 field_0x1166; - /* 0x1166 */ u8 _0x1166[0x116A - 0x1166]; + /* 0x1168 */ u8 _0x1168[0x116A - 0x1168]; - /* 0x116A */ s16 field_0x116A; + /* 0x116A */ s16 mYAngleToLink; - /* 0x116C */ u8 _0x116C[0x117C - 0x116C]; + /* 0x116C */ u8 _0x116C[0x1172 - 0x116C]; + + /* 0x1172 */ s16 field_0x1172; + + /* 0x1174 */ u8 _0x1174[0x117C - 0x1174]; /* 0x117C */ s16 field_0x117C; - - /* 0x117E */ u8 _0x117E[0x1184 - 0x117E]; - + /* 0x117E */ s16 field_0x117E; + /* 0x1180 */ s16 field_0x1180; + /* 0x1180 */ s16 field_0x1182; /* 0x1184 */ s16 field_0x1184; - /* 0x1186 */ s16 field_0x1186; + /* 0x1186 */ s16 mYRotationRelativeToLink; - /* 0x1188 */ u8 _0x1188[0x1190 - 0x1188]; + /* 0x1188 */ u8 _0x1188[0x118A - 0x1188]; - /* 0x1190 */ f32 field_0x1190; + /* 0x118A */ mAng field_0x118A; + /* 0x118C */ mAng field_0x118C; + + /* 0x118E */ u8 _0x118E[0x1190 - 0x118E]; + + /* 0x1190 */ f32 mXZDistanceToLink; /* 0x1194 */ u8 _0x1194[0x119C - 0x1194]; /* 0x119C */ f32 field_0x119C; /* 0x11A0 */ f32 field_0x11A0; /* 0x11A4 */ f32 field_0x11A4; + /* 0x11A8 */ f32 mAnmRate; - /* 0x11A8 */ u8 _0x11A8[0x11B0 - 0x11A8]; + /* 0x11AC */ u8 _0x11AC[0x11B0 - 0x11AC]; /* 0x11B0 */ f32 field_0x11B0; @@ -330,7 +359,7 @@ private: /* 0x1238 */ mVec3_c mToeTranslation[2]; /* 0x1250 */ mVec3_c field_0x1250[2]; - /* 0x1268 */ UnkLastBossCcSph2 field_0x1260[8]; + /* 0x1268 */ UnkLastBossCcSph2 field_0x1268[8]; /* 0x2948 */ UnkLastBossCcSph1 field_0x2948[1]; /* 0x2B64 */ dEmitter_c mWaterEmitter; @@ -341,9 +370,9 @@ private: /* 0x2C68 */ dEmitter_c mEmitter6; /* 0x2C9C */ dEmitter_c mEmitter7; /* 0x2CD0 */ LIGHT_INFLUENCE mLightInfo; - /* 0x2CEC */ u16 field_0x2CEC; + /* 0x2CEC */ s16 field_0x2CEC; /* 0x2CEE */ u8 _0x2CEE[0x2D1C - 0x2CEE]; - /* 0x2D1C */ const char *field_0x2D1C; + /* 0x2D1C */ const char *mpCurrentAnm; /* 0x2D20 */ dTgSwordBattleGame_c *mpSwordBattleGame; }; 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 6d4858b7..7414ba30 100644 --- a/src/REL/d/a/b/d_a_b_lastboss.cpp +++ b/src/REL/d/a/b/d_a_b_lastboss.cpp @@ -170,14 +170,14 @@ int dAcBlastboss_c::create() { mCcList.addCc(mCc2, sSrcCyl2); mCcList.addCc(mCc3, sSrcCyl3); - for (int i = 0; i < (int)ARRAY_LENGTH(field_0x1260); i++) { - field_0x1260[i].field_0x000 = i; - field_0x1260[i].field_0x002 = cM::rndF(65536.0f); - mCcList.addCc(field_0x1260[i].mCc, sSrcSph); - for (int j = 0; j < (int)ARRAY_LENGTH(field_0x1260[j].field_0x014); j++) { - field_0x1260[i].field_0x014[j] = mPosition; + for (int i = 0; i < (int)ARRAY_LENGTH(field_0x1268); i++) { + field_0x1268[i].field_0x000 = i; + field_0x1268[i].field_0x002 = cM::rndF(65536.0f); + mCcList.addCc(field_0x1268[i].mCc, sSrcSph); + for (int j = 0; j < (int)ARRAY_LENGTH(field_0x1268[j].field_0x014); j++) { + field_0x1268[i].field_0x014[j] = mPosition; } - field_0x1260[i].field_0x008 = i * 15000; + field_0x1268[i].field_0x008 = i * 15000; } // TODO loop of length 1 might not exist @@ -265,8 +265,8 @@ int dAcBlastboss_c::actorExecute() { } } - if (mMdlCallback.field_0x04 != 0) { - mMdlCallback.field_0x04--; + if (mMdlCallback.field_0x04.mVal != 0) { + mMdlCallback.field_0x04.mVal--; } if (field_0x117C != 0) { @@ -287,10 +287,10 @@ int dAcBlastboss_c::actorExecute() { mVec3_c vEff; mVec3_c linkPos = link->getPosition(); - field_0x116A = cLib::targetAngleY(mPosition, linkPos); - field_0x1190 = link->getPosition().absXZTo(mPosition); + mYAngleToLink = cLib::targetAngleY(mPosition, linkPos); + mXZDistanceToLink = link->getPosition().absXZTo(mPosition); - field_0x1186 = field_0x116A - mRotation.y; + mYRotationRelativeToLink = mYAngleToLink - mRotation.y; mSwordMdl.setAttackActive(false); mCc4.ClrAtSet(); @@ -346,10 +346,13 @@ int dAcBlastboss_c::actorExecute() { mMdl.getModel().calc(false); nw4r::g3d::ResMdl resMdl = mMdl.getModel().getResMdl(); + // TODO: These very deliberately placed matrices might work better with + // inlines but I haven't found an inline that places rotMtx where it needs + // to be. mMtx_c nodeMtx; - mMdl.getModel().getNodeWorldMtx(resMdl.GetResNode("loc_sword01").GetID(), nodeMtx); mMtx_c rotMtx; mMtx_c scaleMtx; + mMdl.getModel().getNodeWorldMtx(resMdl.GetResNode("loc_sword01").GetID(), nodeMtx); scaleMtx.scaleS(1.05f, 1.05f, 1.05f); MTXConcat(nodeMtx, scaleMtx, nodeMtx); @@ -359,8 +362,8 @@ int dAcBlastboss_c::actorExecute() { // TODO number if ((s32)field_0x1144 == 9) { vEff.y = -80.0f; - if (field_0x1190 > 300.0f) { - vEff.y -= (field_0x1190 - 300.0f); + if (mXZDistanceToLink > 300.0f) { + vEff.y -= (mXZDistanceToLink - 300.0f); if (vEff.y < -280.0f) { vEff.y = -280.0f; } @@ -437,8 +440,8 @@ int dAcBlastboss_c::actorExecute() { tmpCc.x = 0.0f; tmpCc.y = 0.0f; tmpCc.z = 100.0f; - if (field_0x1190 > 300.0f) { - tmpCc.z = (field_0x1190 - 300.0f) + 100.0f; + if (mXZDistanceToLink > 300.0f) { + tmpCc.z = (mXZDistanceToLink - 300.0f) + 100.0f; if (tmpCc.z > 300) { tmpCc.z = 300.0f; } @@ -460,7 +463,7 @@ int dAcBlastboss_c::actorExecute() { MTXMultVec(nodeMtx, tmpCc, tmpCc); tmpCc += mPosition; - if (link->isAttacking() && field_0x1190 < 400.0f) { + if (link->isAttacking() && mXZDistanceToLink < 400.0f) { tmpCc.y += 100.0f; mCc1.SetH(100.0f); } else { @@ -491,7 +494,7 @@ int dAcBlastboss_c::actorExecute() { field_0x1250[0] = mToeTranslation[0] + (mToeTranslation[1] - mToeTranslation[0]) * 0.5f; // UB: this should use string comparison functions for robustness, but // probably works fine in MWCC - if ((field_0x2D1C == "CatchThunderEnd" || field_0x2D1C == "Stan") && mMdl.getAnm().getFrame() <= 3.0f) { + if ((mpCurrentAnm == "CatchThunderEnd" || mpCurrentAnm == "Stan") && mMdl.getAnm().getFrame() <= 3.0f) { field_0x11A4 = 25.0f; } @@ -546,73 +549,73 @@ int dAcBlastboss_c::actorExecute() { bool footSplash[2] = {false, false}; // UB: this should use string comparison functions for robustness, but // probably works fine in MWCC - if (field_0x2D1C == "Walk" || field_0x2D1C == "WalkBt") { + if (mpCurrentAnm == "Walk" || mpCurrentAnm == "WalkBt") { if (mMdl.getAnm().checkFrame(22.0f)) { footSplash[0] = true; } else if (mMdl.getAnm().checkFrame(48.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "TurnR") { + } else if (mpCurrentAnm == "TurnR") { if (mMdl.getAnm().checkFrame(31.0f)) { footSplash[0] = true; } else if (mMdl.getAnm().checkFrame(19.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "TurnL") { + } else if (mpCurrentAnm == "TurnL") { if (mMdl.getAnm().checkFrame(31.0f)) { footSplash[1] = true; } else if (mMdl.getAnm().checkFrame(19.0f)) { footSplash[0] = true; } - } else if (field_0x2D1C == "AttackBreak") { + } else if (mpCurrentAnm == "AttackBreak") { if (mMdl.getAnm().checkFrame(16.0f)) { footSplash[0] = true; } - } else if (field_0x2D1C == "AttackL") { + } else if (mpCurrentAnm == "AttackL") { if (mMdl.getAnm().checkFrame(26.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "AttackR") { + } else if (mpCurrentAnm == "AttackR") { if (mMdl.getAnm().checkFrame(24.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "AttackU") { + } else if (mpCurrentAnm == "AttackU") { if (mMdl.getAnm().checkFrame(10.0f)) { footSplash[1] = true; } else if (mMdl.getAnm().checkFrame(24.0f)) { footSplash[0] = true; } - } else if (field_0x2D1C == "Counter") { + } else if (mpCurrentAnm == "Counter") { if (mMdl.getAnm().checkFrame(21.0f)) { footSplash[0] = true; } else if (mMdl.getAnm().checkFrame(45.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "AttackJumpEnd") { + } else if (mpCurrentAnm == "AttackJumpEnd") { if (mMdl.getAnm().checkFrame(6.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "DownGetUp") { + } else if (mpCurrentAnm == "DownGetUp") { if (mMdl.getAnm().checkFrame(137.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "DownEscapeL") { + } else if (mpCurrentAnm == "DownEscapeL") { if (mMdl.getAnm().checkFrame(15.0f)) { footSplash[0] = true; } else if (mMdl.getAnm().checkFrame(17.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "DownEscapeR") { + } else if (mpCurrentAnm == "DownEscapeR") { if (mMdl.getAnm().checkFrame(15.0f)) { footSplash[1] = true; } else if (mMdl.getAnm().checkFrame(17.0f)) { footSplash[0] = true; } - } else if (field_0x2D1C == "ThunderDemo") { + } else if (mpCurrentAnm == "ThunderDemo") { if (mMdl.getAnm().checkFrame(18.0f)) { footSplash[1] = true; } - } else if (field_0x2D1C == "AttackThunder") { + } else if (mpCurrentAnm == "AttackThunder") { if (mMdl.getAnm().checkFrame(25.0f)) { footSplash[0] = true; } @@ -750,7 +753,7 @@ int dAcBlastboss_c::actorExecute() { } } - if (field_0x1149) { + if (field_0x1149 != 0) { // "Target lock: Demise" (Phase 2) mTargetFiTextID = 0x38; } else { @@ -761,51 +764,367 @@ int dAcBlastboss_c::actorExecute() { return SUCCEEDED; } -void dAcBlastboss_c::callback_c::timingB(u32 nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl mdl) {} +void dAcBlastboss_c::callback_c::timingB(u32 nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl mdl) { + u32 baseNodeIdSkirt = 0; + u32 baseNodeIdHair = 0; + int r27; + int param_4; -void dAcBlastboss_c::initializeState_Fight() {} -void dAcBlastboss_c::executeState_Fight() {} + if (nodeId >= B_LAST_BOSS_NODE_skirtA1 && nodeId < B_LAST_BOSS_NODE_skirtAU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtA1; + param_4 = 0; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtB1 && nodeId < B_LAST_BOSS_NODE_skirtBU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtB1; + param_4 = 1; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtC1 && nodeId < B_LAST_BOSS_NODE_skirtCU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtC1; + param_4 = 2; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtD1 && nodeId < B_LAST_BOSS_NODE_skirtDU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtD1; + param_4 = 3; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtE1 && nodeId < B_LAST_BOSS_NODE_skirtEU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtE1; + param_4 = 4; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtF1 && nodeId < B_LAST_BOSS_NODE_skirtFU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtF1; + param_4 = 5; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtG1 && nodeId < B_LAST_BOSS_NODE_skirtGU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtG1; + param_4 = 6; + } else if (nodeId >= B_LAST_BOSS_NODE_skirtH1 && nodeId < B_LAST_BOSS_NODE_skirtHU1) { + baseNodeIdSkirt = B_LAST_BOSS_NODE_skirtH1; + param_4 = 7; + } + + if (baseNodeIdSkirt != 0) { + u32 nodeOffset = nodeId - baseNodeIdSkirt; + + mMtx_c mtx; + mtx.transS(mpOwner->field_0x1268[param_4].field_0x014[nodeOffset]); + mtx.XrotM(mpOwner->field_0x1268[param_4].field_0x08C[nodeOffset].x); + mtx.YrotM(mpOwner->field_0x1268[param_4].field_0x08C[nodeOffset].y); + mtx.ZrotM(-mpOwner->field_0x1268[param_4].field_0x08C[nodeOffset].z); + mtx.scaleM(0.95f, 0.95f, 1.0f); + mtx.YrotM(-0x4000); + manip->SetMtx(mtx); + } + + if (nodeId >= B_LAST_BOSS_NODE_hairA1 && nodeId < B_LAST_BOSS_NODE_hairBL1) { + baseNodeIdHair = B_LAST_BOSS_NODE_hairA1; + r27 = 0; + } + + if (baseNodeIdHair != 0) { + u32 nodeOffset = nodeId - baseNodeIdHair; + mMtx_c mtx; + mtx.transS(mpOwner->field_0x2948[r27].field_0x008[nodeOffset]); + mtx.YrotM(mpOwner->field_0x2948[r27].field_0x044[nodeOffset].y); + mtx.XrotM(mpOwner->field_0x2948[r27].field_0x044[nodeOffset].x); + mtx.ZrotM(-mpOwner->field_0x2948[r27].field_0x044[nodeOffset].z); + mtx.scaleM(0.95f, 0.95f, 1.0f); + mtx.YrotM(-0x4000); + manip->SetMtx(mtx); + } + + if (nodeId == B_LAST_BOSS_NODE_center) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.XrotM(-field_0x0E.mVal / 2); + mtx.ZrotM(-field_0x10.mVal / 2); + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_backbone1 || nodeId == B_LAST_BOSS_NODE_backbone2) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.YrotM(field_0x0E); + mtx.XrotM(field_0x2E - field_0x0E); + mtx.ZrotM(-field_0x10); + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_head) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.YrotM(field_0x0E * 2 + field_0x08 + field_0x06); + mtx.ZrotM(field_0x0A - field_0x10 * 2); + mtx.XrotM(field_0x0C); + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_chin) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.ZrotM(field_0x12); + manip->SetMtx(mtx); + } else if (nodeId >= B_LAST_BOSS_NODE_hairBL1 && nodeId <= B_LAST_BOSS_NODE_hairC3) { + mMtx_c mtx; + manip->GetMtx(mtx); + + if (nodeId >= B_LAST_BOSS_NODE_hairC1) { + mtx.XrotM(field_0x1C[nodeId - B_LAST_BOSS_NODE_hairBL1]); + mtx.ZrotM(field_0x1C[nodeId - B_LAST_BOSS_NODE_hairBL1]); + } else { + mtx.YrotM(field_0x1C[nodeId - B_LAST_BOSS_NODE_hairBL1]); + mtx.XrotM(field_0x1C[nodeId - B_LAST_BOSS_NODE_hairBL1]); + } + + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_armR1) { + int blah = field_0x04 * mAng(field_0x04 * 0x4300).sin() * 80.0f; + + mMtx_c mtx; + manip->GetMtx(mtx); + + mtx.XrotM(blah + (int)(300.0f * field_0x30)); + mtx.ZrotM(blah + (int)(200.0f * field_0x30)); + + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_armR2) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.ZrotM(field_0x30 * 200.0f); + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_wristR) { + // unused + int blah = field_0x04 * (f32)mAng(field_0x04 * 0x4300).sin(); + + mMtx_c mtx; + manip->GetMtx(mtx); + + int i2 = 0; + if (field_0x30 > 0.0f) { + i2 = field_0x30 * -200.0f; + } + + mtx.XrotM(i2 + field_0x18); + mtx.ZrotM(i2 + field_0x1A); + + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_legR1 || nodeId == B_LAST_BOSS_NODE_legR2) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.XrotM(field_0x14); + if (nodeId == B_LAST_BOSS_NODE_legR2) { + mtx.XrotM(field_0x14); + } + manip->SetMtx(mtx); + } else if (nodeId == B_LAST_BOSS_NODE_legL1 || nodeId == B_LAST_BOSS_NODE_legL2) { + mMtx_c mtx; + manip->GetMtx(mtx); + mtx.XrotM(field_0x16); + if (nodeId == B_LAST_BOSS_NODE_legL2) { + mtx.XrotM(field_0x16); + } + manip->SetMtx(mtx); + } +} + +void dAcBlastboss_c::initializeState_Fight() { + setAnm("WaitBt", 20.0f); + mAnmRate = 1.0f; + field_0x1166 = 0; + field_0x118A = 0; + if (field_0x1149 == 0) { + field_0x1156[2] = cM::rndF(50.0f) + 50.0f; + } else { + field_0x1156[2] = cM::rndF(20.0f) + 10.0f; + } + field_0x1144 = 9; +} +void dAcBlastboss_c::executeState_Fight() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + field_0x1131 = 1; + f32 targetSpeed = 0.0f; + f32 targetAnmRate = 1.5f; + f32 puVar2 = 0.0f; + + s16 diff = mAngle.y - mYAngleToLink; + bool b = false; + + if (field_0x2CEC >= 100 && field_0x2CEC < 300) { + puVar2 = -100.0f; + field_0x1156[2] = cM::rndF(50.0f) + 100.0f; + } + + switch (field_0x1166) { + case 0: { + b = true; + field_0x118C = 0; + targetAnmRate = 1.0f; + field_0x117E = 0; + if (mXZDistanceToLink > puVar2 + 450.0f) { + field_0x1166 = 2; + } else if (mXZDistanceToLink < puVar2 + 250.0f + 100.0f) { + field_0x1166 = 1; + field_0x1156[0] = 8; + mAnmRate = -1.0f; + field_0x1180 = 0; + } else { + setAnm("WaitBt", 20.0f); + mAnmRate = targetAnmRate; + if (diff < -0x1000 || diff > 0x1000) { + field_0x1166 = 4; + if (diff < 0) { + setAnm("TurnL", 10.0f); + } else { + setAnm("TurnR", 10.0f); + } + } + } + break; + } + case 1: { + b = true; + setAnm("WalkBt", 20.0f); + targetSpeed = -5.0f; + targetAnmRate = -2.5f; + if (mXZDistanceToLink < 200.0f) { + field_0x1180++; + if (field_0x1180 > 40) { + mStateMgr.changeState(StateID_PunchAttack); + return; + } + } else if (mXZDistanceToLink >= puVar2 + 200.0f && field_0x1156[0] == 0) { + field_0x1166 = 0; + } + break; + } + case 2: { + b = true; + field_0x117E = 0; + if (mXZDistanceToLink > puVar2 + 850.0f) { + field_0x1166 = 3; + } else { + setAnm("WalkBt", 20.0f); + if (mMdl.getAnm().getFrame() >= 25.0f && mMdl.getAnm().getFrame() <= 50.0f) { + targetSpeed = 5.0f; + } + field_0x11A4 = 5.0f; + targetAnmRate = 1.5f; + } + if (mXZDistanceToLink < puVar2 + 400.0f) { + field_0x1166 = 0; + if (field_0x1149 == 0) { + field_0x1156[2] = cM::rndF(50.0f) + 50.0f; + } else { + field_0x1156[2] = cM::rndF(20.0f) + 10.0f; + } + } + break; + } + case 3: { + setAnm("Walk", 20.0f); + targetSpeed = 7.5f; + field_0x11A4 = 7.5f; + targetAnmRate = 1.0f; + if (mXZDistanceToLink < puVar2 + 750.0f) { + field_0x1166 = 3; + } else if (!link->isRecovering()) { + field_0x117E++; + if (field_0x117E > 70) { + mStateMgr.changeState(StateID_DashAttack); + return; + } + } else { + field_0x117E = 0; + } + break; + } + case 4: { + field_0x117E = 0; + b = true; + if (mMdl.getAnm().isStop()) { + field_0x1166 = 0; + } + break; + } + } + + sLib::addCalcScaledDiff(&mAnmRate, targetAnmRate, 1.0f, 0.5f); + setAnmRate(mAnmRate); + sLib::addCalcScaledDiff(&mSpeed, targetSpeed, 1.0f, 2.0f); + + if (field_0x1166 != 0) { + sLib::addCalcAngle(field_0x118C.ref(), 0x800, 1, 100); + sLib::addCalcAngle(mAngle.y.ref(), mYAngleToLink, 2, field_0x118C); + } + + if (b) { + if (diff > 0x1000) { + diff = 0x1000; + } else if (diff < -0x1000) { + diff = -0x1000; + } + field_0x1172 = diff / 2; + // TODO what is this constant + sLib::addCalcScaledDiff(&mMdlCallback.field_0x30, diff * (1.0f / 409.6f), 0.5f, 1.0f); + } +} void dAcBlastboss_c::finalizeState_Fight() {} + void dAcBlastboss_c::initializeState_Guard() {} void dAcBlastboss_c::executeState_Guard() {} 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() {} + void dAcBlastboss_c::initializeState_SitDamage() {} void dAcBlastboss_c::executeState_SitDamage() {} void dAcBlastboss_c::finalizeState_SitDamage() {} + void dAcBlastboss_c::initializeState_Down() {} void dAcBlastboss_c::executeState_Down() {} void dAcBlastboss_c::finalizeState_Down() {} + void dAcBlastboss_c::initializeState_Stun() {} void dAcBlastboss_c::executeState_Stun() {} void dAcBlastboss_c::finalizeState_Stun() {} + void dAcBlastboss_c::initializeState_ThunderWait() {} void dAcBlastboss_c::executeState_ThunderWait() {} void dAcBlastboss_c::finalizeState_ThunderWait() {} +void dAcBlastboss_c::setAnm(const char *name, f32 blend) { + if (mpCurrentAnm != name) { + mMdl.setAnm(name, m3d::PLAY_MODE_4, blend); + mpCurrentAnm = name; + } +} + +void dAcBlastboss_c::forceSetAnm(const char *name, f32 blend) { + mMdl.setAnm(name, m3d::PLAY_MODE_4, blend); + mpCurrentAnm = name; +} + +void dAcBlastboss_c::setAnmRate(f32 rate) { + mMdl.setRate(rate); +} + int dAcBlastboss_c::draw() { drawModelType1(&mMdl.getModel()); mSwordMdl.entry(this, nullptr, nullptr);