summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-12-30 00:42:34 +0100
committerrobojumper <robojumper@gmail.com>2026-01-28 19:14:17 +0100
commit2223fd485674bc3be6d09054b023aae8122f3502 (patch)
tree6f8b703e520e7e6236797daa7ab45f8f573a28fb
parent6dd18a9bce55c3423a851ccf0c7fcb7142736ac5 (diff)
More
-rw-r--r--config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt6
-rw-r--r--include/d/a/b/d_a_b_lastboss.h59
-rw-r--r--src/REL/d/a/b/d_a_b_lastboss.cpp393
3 files changed, 403 insertions, 55 deletions
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];
- /* 0x117C */ s16 field_0x117C;
+ /* 0x1172 */ s16 field_0x1172;
- /* 0x117E */ u8 _0x117E[0x1184 - 0x117E];
+ /* 0x1174 */ u8 _0x1174[0x117C - 0x1174];
+ /* 0x117C */ s16 field_0x117C;
+ /* 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[0x118A - 0x1188];
+
+ /* 0x118A */ mAng field_0x118A;
+ /* 0x118C */ mAng field_0x118C;
- /* 0x1188 */ u8 _0x1188[0x1190 - 0x1188];
+ /* 0x118E */ u8 _0x118E[0x1190 - 0x118E];
- /* 0x1190 */ f32 field_0x1190;
+ /* 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;
+
+ 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;
-void dAcBlastboss_c::initializeState_Fight() {}
-void dAcBlastboss_c::executeState_Fight() {}
+ 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);