summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorParker Burnett <jpburnett@gwu.edu>2022-07-17 20:19:11 -0700
committerGitHub <noreply@github.com>2022-07-18 04:19:11 +0100
commit356fde30455b272dc27ec2ec2f19e69a66acf73c (patch)
tree0daa662b7eb6c3976f994ecee3e448a249d605f6 /src
parent03a7e00c4b43c195c5f7556109c98007a5f31a87 (diff)
En_Ik OK (#821)
* starting en_ik * updating and more matching funcs * matched more functions and ran format.sh * matched another, started on init * updating things with master, and more matches * another function down * some more progress * some documenting * master merge * maybe some progress? * one more func left * IK OK * inital cleanup passthrough * fixing warnings and formatting * some cleanup * touch up * more docs * doin dat dere docs * actorfixer * finishing function names * initial round of fixes * format * Naming things * namefixer * review comments pt2 * comment updates * PR Feedback * forgot a format * naming enum * more fixes * minor fix * minor fix * format * fixes for daaays * for some reason these keep showing up? * fixing blob * names * fixes * naming things...can't discern the last ones... * updating TLUT and names * formating and fisxes * fixing func name * naming effect variable * name fixer, and renaming variable * Fixing xml * forgot to fix name
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_En_Ik/z_en_ik.c1148
-rw-r--r--src/overlays/actors/ovl_En_Ik/z_en_ik.h42
2 files changed, 1038 insertions, 152 deletions
diff --git a/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/src/overlays/actors/ovl_En_Ik/z_en_ik.c
index 33497bdcd..fcc930b7f 100644
--- a/src/overlays/actors/ovl_En_Ik/z_en_ik.c
+++ b/src/overlays/actors/ovl_En_Ik/z_en_ik.c
@@ -16,7 +16,64 @@ void EnIk_Destroy(Actor* thisx, PlayState* play);
void EnIk_Update(Actor* thisx, PlayState* play);
void EnIk_Draw(Actor* thisx, PlayState* play);
-#if 0
+void EnIk_Thaw(EnIk* this, PlayState* play);
+s32 EnIk_IsChangingAction(EnIk* this, PlayState* play);
+s32 EnIk_ChooseAttack(EnIk* this);
+void EnIk_CheckActions(EnIk* this, PlayState* play);
+void EnIk_SetupIdle(EnIk* this);
+void EnIk_Idle(EnIk* this, PlayState* play);
+void EnIk_SetupWalk(EnIk* this);
+void EnIk_WalkTowardsPlayer(EnIk* this, PlayState* play);
+void EnIk_SetupRun(EnIk* this);
+void EnIk_RunTowardsPlayer(EnIk* this, PlayState* play);
+void EnIk_SetupVerticalAttack(EnIk* this);
+void EnIk_VerticalAttack(EnIk* this, PlayState* play);
+void EnIk_SetupTakeOutAxe(EnIk* this);
+void EnIk_TakeOutAxe(EnIk* this, PlayState* play);
+void EnIk_SetupHorizontalDoubleAttack(EnIk* this);
+void EnIk_HorizontalDoubleAttack(EnIk* this, PlayState* play);
+void EnIk_SetupSingleHorizontalAttack(EnIk* this);
+void EnIk_SingleHorizontalAttack(EnIk* this, PlayState* play);
+void EnIk_SetupEndHorizontalAttack(EnIk* this);
+void EnIk_EndHorizontalAttack(EnIk* this, PlayState* play);
+void EnIk_SetupBlock(EnIk* this);
+void EnIk_Block(EnIk* this, PlayState* play);
+void EnIk_SetupReactToAttack(EnIk* this, s32 arg1);
+void EnIk_ReactToAttack(EnIk* this, PlayState* play);
+void EnIk_SetupDie(EnIk* this);
+void EnIk_Die(EnIk* this, PlayState* play);
+void EnIk_Frozen(EnIk* this, PlayState* play);
+void EnIk_SetupCutscene(EnIk* this);
+void EnIk_PlayCutscene(EnIk* this, PlayState* play);
+void EnIk_UpdateDamage(EnIk* this, PlayState* play);
+void EnIk_UpdateArmor(EnIk* this, PlayState* play);
+
+typedef struct {
+ /* 0x0 */ Gfx* unk00;
+ /* 0x4 */ s16 unk04;
+} EnIkUnkStruct; // size = 0x8
+
+EnIkUnkStruct sIronKnuckleArmorMarkings[] = {
+ { gIronKnuckleHelmetMarkingDL, 0x0000 },
+ { gIronKnuckleFrontTorsoArmorMarkingDL, 0x0000 },
+ { gIronKnuckleRearTorsoArmorMarkingDL, 0x7FFF },
+ { gIronKnuckleRivetsMarking2DL, 0x4000 },
+ { gIronKnuckleRivetsMarking1DL, 0xC000 },
+ { NULL, 0x4000 },
+ { NULL, 0xC000 },
+};
+
+// sIronKnuckleArmorType[PARAM_VALUE][ARMOR_SECTIONS]
+// ARMOR SECTIONS:
+// 1 - Main armor
+// 2 - Armor Accent (Side of armor and boot tips)
+// 3 - Axe Color
+static Gfx* sIronKnuckleArmorType[3][3] = {
+ { gIronKnuckleTanArmorMaterialDL, gIronKnuckleBronzeArmorMaterialDL, gIronKnuckleSilverArmorMaterialDL },
+ { gIronKnuckleBlackArmorMaterialDL, gIronKnuckleBrownArmorMaterialDL, gIronKnuckleBrownArmorMaterialDL },
+ { gIronKnuckleWhiteArmorMaterialDL, gIronKnuckleGoldArmorMaterialDL, gIronKnuckleGoldArmorMaterialDL },
+};
+
const ActorInit En_Ik_InitVars = {
ACTOR_EN_IK,
ACTORCAT_ENEMY,
@@ -29,219 +86,1014 @@ const ActorInit En_Ik_InitVars = {
(ActorFunc)EnIk_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_8092C01C = {
- { COLTYPE_METAL, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_METAL,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK2,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON | BUMP_HOOKABLE,
+ OCELEM_ON,
+ },
{ 25, 80, 0, { 0, 0, 0 } },
};
-// static ColliderTrisElementInit sTrisElementsInit[2] = {
-static ColliderTrisElementInit D_8092C048[2] = {
+static ColliderTrisElementInit sTrisElementsInit[2] = {
{
- { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK2,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { -10.0f, 14.0f, 2.0f }, { -10.0f, -6.0f, 2.0f }, { 9.0f, 14.0f, 2.0f } } },
},
{
- { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK2,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { -10.0f, -6.0f, 2.0f }, { 9.0f, -6.0f, 2.0f }, { 9.0f, 14.0f, 2.0f } } },
},
};
-// static ColliderTrisInit sTrisInit = {
-static ColliderTrisInit D_8092C0C0 = {
- { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_2, COLSHAPE_TRIS, },
- ARRAY_COUNT(sTrisElementsInit), D_8092C048, // sTrisElementsInit,
+static ColliderTrisInit sTrisInit = {
+ {
+ COLTYPE_METAL,
+ AT_NONE,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_2,
+ COLSHAPE_TRIS,
+ },
+ ARRAY_COUNT(sTrisElementsInit),
+ sTrisElementsInit,
};
-// static ColliderQuadInit sQuadInit = {
-static ColliderQuadInit D_8092C0D0 = {
- { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_2, COLSHAPE_QUAD, },
- { ELEMTYPE_UNK0, { 0x20000000, 0x04, 0x40 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, BUMP_NONE, OCELEM_NONE, },
+static ColliderQuadInit sQuadInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE | AT_TYPE_ENEMY,
+ AC_NONE,
+ OC1_NONE,
+ OC2_TYPE_2,
+ COLSHAPE_QUAD,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x20000000, 0x04, 0x40 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7,
+ BUMP_NONE,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
};
-// static DamageTable sDamageTable = {
-static DamageTable D_8092C120 = {
- /* Deku Nut */ DMG_ENTRY(0, 0xF),
- /* Deku Stick */ DMG_ENTRY(0, 0xF),
- /* Horse trample */ DMG_ENTRY(0, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0x0),
- /* Zora boomerang */ DMG_ENTRY(0, 0xF),
- /* Normal arrow */ DMG_ENTRY(0, 0xF),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(0, 0xF),
- /* Goron punch */ DMG_ENTRY(2, 0x0),
- /* Sword */ DMG_ENTRY(1, 0x0),
- /* Goron pound */ DMG_ENTRY(3, 0x0),
- /* Fire arrow */ DMG_ENTRY(0, 0xF),
- /* Ice arrow */ DMG_ENTRY(0, 0xF),
- /* Light arrow */ DMG_ENTRY(1, 0x4),
- /* Goron spikes */ DMG_ENTRY(0, 0xF),
- /* Deku spin */ DMG_ENTRY(0, 0xF),
- /* Deku bubble */ DMG_ENTRY(0, 0xF),
- /* Deku launch */ DMG_ENTRY(0, 0xF),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0xF),
- /* Zora barrier */ DMG_ENTRY(0, 0x0),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0x0),
- /* Zora punch */ DMG_ENTRY(0, 0xF),
- /* Spin attack */ DMG_ENTRY(1, 0x0),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0x0),
+typedef enum {
+ /* 0x0 */ DMG_EFF_NONE,
+ /* 0x4 */ DMG_EFF_FIRE = 0x2,
+ /* 0x0 */ DMG_EFF_ICE,
+ /* 0x4 */ DMG_EFF_LIGHT_SPARKS,
+ /* 0xF */ DMG_EFF_IMMUNE = 0xF,
+
+} EnIkDmgEff;
+
+static DamageTable sDamageTableArmor = {
+ /* Deku Nut */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Deku Stick */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Horse trample */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Explosives */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Normal arrow */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Hookshot */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Goron punch */ DMG_ENTRY(2, DMG_EFF_NONE),
+ /* Sword */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Goron pound */ DMG_ENTRY(3, DMG_EFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Ice arrow */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Light arrow */ DMG_ENTRY(1, DMG_EFF_LIGHT_SPARKS),
+ /* Goron spikes */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Deku spin */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Deku bubble */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Deku launch */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Zora barrier */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Normal shield */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Light ray */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Thrown object */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Zora punch */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Spin attack */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Normal Roll */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Unblockable */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Powder Keg */ DMG_ENTRY(1, DMG_EFF_NONE),
};
-// static DamageTable sDamageTable = {
-static DamageTable D_8092C140 = {
- /* Deku Nut */ DMG_ENTRY(0, 0x0),
- /* Deku Stick */ DMG_ENTRY(1, 0x0),
- /* Horse trample */ DMG_ENTRY(0, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0x0),
- /* Zora boomerang */ DMG_ENTRY(1, 0x0),
- /* Normal arrow */ DMG_ENTRY(1, 0x0),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(0, 0xF),
- /* Goron punch */ DMG_ENTRY(2, 0x0),
- /* Sword */ DMG_ENTRY(1, 0x0),
- /* Goron pound */ DMG_ENTRY(3, 0x0),
- /* Fire arrow */ DMG_ENTRY(2, 0x2),
- /* Ice arrow */ DMG_ENTRY(2, 0x3),
- /* Light arrow */ DMG_ENTRY(2, 0x4),
- /* Goron spikes */ DMG_ENTRY(1, 0x0),
- /* Deku spin */ DMG_ENTRY(0, 0x0),
- /* Deku bubble */ DMG_ENTRY(1, 0x0),
- /* Deku launch */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0),
- /* Zora barrier */ DMG_ENTRY(0, 0x0),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0x0),
- /* Zora punch */ DMG_ENTRY(1, 0x0),
- /* Spin attack */ DMG_ENTRY(1, 0x0),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0x0),
+static DamageTable sDamageTableNoArmor = {
+ /* Deku Nut */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Deku Stick */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Horse trample */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Explosives */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Normal arrow */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Hookshot */ DMG_ENTRY(0, DMG_EFF_IMMUNE),
+ /* Goron punch */ DMG_ENTRY(2, DMG_EFF_NONE),
+ /* Sword */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Goron pound */ DMG_ENTRY(3, DMG_EFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(2, DMG_EFF_FIRE),
+ /* Ice arrow */ DMG_ENTRY(2, DMG_EFF_ICE),
+ /* Light arrow */ DMG_ENTRY(2, DMG_EFF_LIGHT_SPARKS),
+ /* Goron spikes */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Deku spin */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Deku bubble */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Deku launch */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Zora barrier */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Normal shield */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Light ray */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Thrown object */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Zora punch */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Spin attack */ DMG_ENTRY(1, DMG_EFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Normal Roll */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Unblockable */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMG_EFF_NONE),
+ /* Powder Keg */ DMG_ENTRY(1, DMG_EFF_NONE),
};
-// sColChkInfoInit
-static CollisionCheckInfoInit D_8092C160 = { 18, 25, 80, MASS_HEAVY };
+static CollisionCheckInfoInit sColChkInfoInit = { 18, 25, 80, MASS_HEAVY };
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8092C168[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(targetArrowOffset, 2916, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 12, ICHAIN_CONTINUE),
ICHAIN_F32_DIV1000(gravity, -1000, ICHAIN_STOP),
};
-#endif
+static EffectBlureInit2 sBlureInit = {
+ 0, 8, 0, { 255, 255, 150, 200 }, { 255, 255, 255, 64 }, { 255, 255, 150, 0 }, { 255, 255, 255, 0 }, 8,
+ 0, 2, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
+};
+
+void EnIk_Init(Actor* thisx, PlayState* play) {
+ static s32 sDisplayListDesegmented = false;
+ s32 i;
+ EnIk* this = THIS;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_InitFlex(play, &this->skelAnime, &gIronKnuckleSkel, &gIronKnuckleWalkAnim, this->jointTable,
+ this->morphTable, IRON_KNUCKLE_LIMB_MAX);
+ Collider_InitAndSetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder);
+ Collider_InitAndSetTris(play, &this->colliderTris, &this->actor, &sTrisInit, this->shieldColliderItems);
+ Collider_InitAndSetQuad(play, &this->colliderQuad, &this->actor, &sQuadInit);
+ CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTableArmor, &sColChkInfoInit);
+ this->actor.params = IK_GET_ARMOR_TYPE(&this->actor);
+ this->actor.params--;
+
+ Effect_Add(play, &this->effectIndex, EFFECT_BLURE2, 0, 0, &sBlureInit);
+ if (!sDisplayListDesegmented) {
+ for (i = 0; i < ARRAY_COUNT(sIronKnuckleArmorType); i++) {
+ sIronKnuckleArmorType[i][0] = Lib_SegmentedToVirtual(sIronKnuckleArmorType[i][0]);
+ sIronKnuckleArmorType[i][1] = Lib_SegmentedToVirtual(sIronKnuckleArmorType[i][1]);
+ sIronKnuckleArmorType[i][2] = Lib_SegmentedToVirtual(sIronKnuckleArmorType[i][2]);
+ }
+ sDisplayListDesegmented = true;
+ }
+ EnIk_SetupIdle(this);
+}
+
+void EnIk_Destroy(Actor* thisx, PlayState* play) {
+ EnIk* this = THIS;
+
+ Collider_DestroyTris(play, &this->colliderTris);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
+ Collider_DestroyQuad(play, &this->colliderQuad);
+ Effect_Destroy(play, this->effectIndex);
+}
+
+void EnIk_Freeze(EnIk* this) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
+ this->drawDmgEffScale = 0.65f;
+ this->drawDmgEffFrozenSteamScale = 97.5f * 0.01f;
+ this->drawDmgEffAlpha = 1.0f;
+ this->timer = 80;
+ this->actor.flags &= ~ACTOR_FLAG_400;
+ Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80);
+}
+
+void EnIk_Thaw(EnIk* this, PlayState* play) {
+ if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ this->drawDmgEffAlpha = 0.0f;
+ Actor_SpawnIceEffects(play, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f);
+ this->actor.flags |= ACTOR_FLAG_400;
+ }
+}
+
+void EnIk_HitArmor(EnIk* this, PlayState* play) {
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffScale = 0.65f;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->colliderCylinder.info.bumper.hitPos.x,
+ this->colliderCylinder.info.bumper.hitPos.y, this->colliderCylinder.info.bumper.hitPos.z, 0, 0, 0,
+ CLEAR_TAG_LARGE_LIGHT_RAYS);
+}
+
+s32 EnIk_IsChangingAction(EnIk* this, PlayState* play) {
+ if ((this->drawArmorFlags) && (this->actionFunc != EnIk_Block) &&
+ func_800BE184(play, &this->actor, 100.0f, 0x2710, 0x4000, this->actor.shape.rot.y)) {
+ EnIk_SetupBlock(this);
+ return true;
+ }
+ return false;
+}
+
+s32 EnIk_ChooseAttack(EnIk* this) {
+ s32 absYawDiff;
+ s32 detectionThreshold; // angle threshold an Iron Knuckle will use to trigger a horizontal attack
+
+ if ((this->actor.xzDistToPlayer < 100.0f) && (fabsf(this->actor.playerHeightRel) < 150.0f)) {
+
+ detectionThreshold = (this->drawArmorFlags == 0) ? 0xAAA : 0x3FFC;
+ absYawDiff = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y));
+
+ if (detectionThreshold >= absYawDiff) {
+ if (Rand_ZeroOne() < 0.5f) {
+ EnIk_SetupVerticalAttack(this);
+ return true;
+ }
+ EnIk_SetupHorizontalDoubleAttack(this);
+ return true;
+ } else if ((this->drawArmorFlags) || ((absYawDiff > 0x4000) && (Rand_ZeroOne() < 0.1f))) {
+ EnIk_SetupSingleHorizontalAttack(this);
+ return true;
+ }
+ }
+ return false;
+}
+
+void EnIk_CheckActions(EnIk* this, PlayState* play) {
+ if (!EnIk_IsChangingAction(this, play) && !EnIk_ChooseAttack(this)) {
+ if (this->drawArmorFlags) {
+ EnIk_SetupRun(this);
+ } else {
+ EnIk_SetupWalk(this);
+ }
+ }
+}
+
+void EnIk_SetupIdle(EnIk* this) {
+ f32 frameCount = Animation_GetLastFrame(&gIronKnuckleHorizontalAttackAnim);
+
+ if (this->drawArmorFlags) {
+ this->timer = 10;
+ } else {
+ this->timer = 0;
+ }
+ Animation_Change(&this->skelAnime, &gIronKnuckleEndHorizontalAttackAnim, 1.0f, frameCount, frameCount,
+ ANIMMODE_ONCE, this->timer);
+ this->actionFunc = EnIk_Idle;
+ this->actor.speedXZ = 0.0f;
+}
+
+void EnIk_Idle(EnIk* this, PlayState* play) {
+ if (this->timer > 0) {
+ this->timer--;
+ SkelAnime_Update(&this->skelAnime);
+ if (this->timer == 0) {
+ EnIk_CheckActions(this, play);
+ }
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_ARMOR_HIT);
+ func_801A2E54(NA_BGM_MINI_BOSS);
+ this->actor.hintId = 0x35;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ this->invincibilityFrames = 12;
+ EnIk_SetupWalk(this);
+ }
+}
+
+void EnIk_SetupWalk(EnIk* this) {
+ Animation_MorphToLoop(&this->skelAnime, &gIronKnuckleWalkAnim, -4.0f);
+ this->actor.speedXZ = 0.9f;
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ this->actionFunc = EnIk_WalkTowardsPlayer;
+}
+
+void EnIk_WalkTowardsPlayer(EnIk* this, PlayState* play) {
+ s16 yawDiff;
-extern ColliderCylinderInit D_8092C01C;
-extern ColliderTrisElementInit D_8092C048[2];
-extern ColliderTrisInit D_8092C0C0;
-extern ColliderQuadInit D_8092C0D0;
-extern DamageTable D_8092C120;
-extern DamageTable D_8092C140;
-extern CollisionCheckInfoInit D_8092C160;
-extern InitChainEntry D_8092C168[];
+ SkelAnime_Update(&this->skelAnime);
+ if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 16.0f)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_WALK);
+ }
+ yawDiff = this->actor.wallYaw - this->actor.shape.rot.y;
+ if ((this->actor.bgCheckFlags & 8) && (ABS_ALT(yawDiff) >= 0x4000)) {
+ yawDiff = (this->actor.yawTowardsPlayer > 0) ? this->actor.wallYaw - 0x4000 : this->actor.wallYaw + 0x4000;
+ Math_ScaledStepToS(&this->actor.shape.rot.y, yawDiff, 0x320);
+ } else {
+ Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x320);
+ }
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ if (!EnIk_IsChangingAction(this, play)) {
+ EnIk_ChooseAttack(this);
+ }
+}
-extern UNK_TYPE D_06000CE8;
-extern UNK_TYPE D_060015F8;
-extern UNK_TYPE D_06001ABC;
-extern UNK_TYPE D_06002484;
-extern UNK_TYPE D_0600391C;
-extern UNK_TYPE D_06004A04;
-extern UNK_TYPE D_06005254;
-extern UNK_TYPE D_060057F4;
-extern UNK_TYPE D_06006294;
+void EnIk_SetupRun(EnIk* this) {
+ Animation_MorphToLoop(&this->skelAnime, &gIronKnuckleRunAnim, -4.0f);
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TWINROBA_SHOOT_VOICE);
+ this->actor.speedXZ = 2.5f;
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ this->actionFunc = EnIk_RunTowardsPlayer;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/EnIk_Init.s")
+void EnIk_RunTowardsPlayer(EnIk* this, PlayState* play) {
+ s16 yawDiff;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/EnIk_Destroy.s")
+ SkelAnime_Update(&this->skelAnime);
+ if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 9.0f)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_WALK);
+ }
+ yawDiff = this->actor.wallYaw - this->actor.shape.rot.y;
+ if ((this->actor.bgCheckFlags & 8) && (ABS_ALT(yawDiff) >= 0x4000)) {
+ yawDiff = (this->actor.yawTowardsPlayer > 0) ? this->actor.wallYaw - 0x4000 : this->actor.wallYaw + 0x4000;
+ Math_ScaledStepToS(&this->actor.shape.rot.y, yawDiff, 0x4B0);
+ } else {
+ Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x4B0);
+ }
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ if (!EnIk_IsChangingAction(this, play)) {
+ EnIk_ChooseAttack(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929AF8.s")
+void EnIk_SetupVerticalAttack(EnIk* this) {
+ s32 pad;
+ f32 playbackSpeed;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929B6C.s")
+ this->actor.speedXZ = 0.0f;
+ if (this->drawArmorFlags) {
+ playbackSpeed = 1.5f;
+ } else {
+ playbackSpeed = 1.2f;
+ }
+ Animation_Change(&this->skelAnime, &gIronKnuckleVerticalAttackAnim, playbackSpeed, 0.0f,
+ Animation_GetLastFrame(&gIronKnuckleVerticalAttackAnim.common), 3, -4.0f);
+ this->timer = 0;
+ this->blurEffectSpawnLock = -1;
+ this->actionFunc = EnIk_VerticalAttack;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929BEC.s")
+void EnIk_VerticalAttack(EnIk* this, PlayState* play) {
+ Vec3f particlePos;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929C80.s")
+ this->timer++;
+ if (!(this->skelAnime.curFrame < 7.0f) || !EnIk_IsChangingAction(this, play)) {
+ if (Animation_OnFrame(&this->skelAnime, 15.0f)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_SWING_AXE);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929D04.s")
+ } else if (Animation_OnFrame(&this->skelAnime, 21.0f)) {
+ particlePos.x = (Math_SinS((this->actor.shape.rot.y + 0x6A4)) * 70.0f) + this->actor.world.pos.x;
+ particlePos.z = (Math_CosS((this->actor.shape.rot.y + 0x6A4)) * 70.0f) + this->actor.world.pos.z;
+ particlePos.y = this->actor.world.pos.y;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_HIT_GND);
+ Camera_AddQuake(GET_ACTIVE_CAM(play), 2, 25, 5);
+ Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100);
+ CollisionCheck_SpawnShieldParticles(play, &particlePos);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929E2C.s")
+ if ((this->skelAnime.curFrame > 13.0f) && (this->skelAnime.curFrame < 23.0f)) {
+ this->colliderQuad.base.atFlags |= AT_ON;
+ if (this->drawArmorFlags) {
+ this->actor.speedXZ = sin_rad((this->skelAnime.curFrame - 13.0f) * (M_PI / 20)) * 10.0f;
+ }
+ } else {
+ this->colliderQuad.base.atFlags &= ~AT_ON;
+ this->actor.speedXZ = 0.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929E88.s")
+ if ((this->drawArmorFlags) && (this->skelAnime.curFrame < 13.0f)) {
+ Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x5DC);
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929F20.s")
+ if (SkelAnime_Update(&this->skelAnime)) {
+ EnIk_SetupTakeOutAxe(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_80929FC8.s")
+void EnIk_SetupTakeOutAxe(EnIk* this) {
+ Animation_PlayOnce(&this->skelAnime, &gIronKnuckleEndVerticalAttackAnim);
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_PULLOUT);
+ this->actionFunc = EnIk_TakeOutAxe;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A020.s")
+void EnIk_TakeOutAxe(EnIk* this, PlayState* play) {
+ if (SkelAnime_Update(&this->skelAnime)) {
+ if (this->skelAnime.animation == &gIronKnuckleRecoverVerticalAttackAnim) {
+ EnIk_CheckActions(this, play);
+ } else {
+ Animation_Change(
+ &this->skelAnime, &gIronKnuckleRecoverVerticalAttackAnim, (this->drawArmorFlags) ? 1.5f : 1.0f, 0.0f,
+ Animation_GetLastFrame(&gIronKnuckleRecoverVerticalAttackAnim.common), ANIMMODE_ONCE_INTERP, 0.0f);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A124.s")
+void EnIk_SetupHorizontalDoubleAttack(EnIk* this) {
+ this->actor.speedXZ = 0.0f;
+ Animation_Change(&this->skelAnime, &gIronKnuckleHorizontalAttackAnim, (this->drawArmorFlags) ? 1.3f : 1.0f, 0.0f,
+ Animation_GetLastFrame(&gIronKnuckleHorizontalAttackAnim.common), ANIMMODE_ONCE_INTERP,
+ (this->drawArmorFlags) ? 4.0f : 10.0f);
+ this->timer = 0;
+ this->blurEffectSpawnLock = -1;
+ this->actionFunc = EnIk_HorizontalDoubleAttack;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A188.s")
+void EnIk_HorizontalDoubleAttack(EnIk* this, PlayState* play) {
+ f32 phi_f2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A28C.s")
+ this->timer++;
+ if ((Animation_OnFrame(&this->skelAnime, 1.0f)) || (Animation_OnFrame(&this->skelAnime, 13.0f))) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_SWING_AXE);
+ }
+ if (((this->skelAnime.curFrame > 1.0f) && (this->skelAnime.curFrame < 9.0f)) ||
+ ((this->skelAnime.curFrame > 12.0f) && (this->skelAnime.curFrame < 20.0f))) {
+ if (this->drawArmorFlags) {
+ Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x5DC);
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ if (this->skelAnime.curFrame > 12.0f) {
+ phi_f2 = this->skelAnime.curFrame - 12.0f;
+ } else {
+ phi_f2 = this->skelAnime.curFrame - 1.0f;
+ }
+ this->actor.speedXZ = sin_rad((M_PI / 8) * phi_f2) * 4.5f;
+ }
+ this->colliderQuad.base.atFlags |= AT_ON;
+ } else {
+ this->colliderQuad.base.atFlags &= ~AT_ON;
+ this->actor.speedXZ = 0.0f;
+ }
+ if (SkelAnime_Update(&this->skelAnime)) {
+ EnIk_SetupEndHorizontalAttack(this);
+ }
+}
+
+void EnIk_SetupSingleHorizontalAttack(EnIk* this) {
+ f32 playSpeed;
+
+ this->actor.speedXZ = 0.0f;
+ if (this->drawArmorFlags) {
+ this->actor.world.rot.z = 0x1000;
+ playSpeed = 1.3f;
+ } else {
+ this->actor.world.rot.z = 0xB00;
+ playSpeed = 1.0f;
+ }
+ Animation_Change(&this->skelAnime, &gIronKnuckleHorizontalAttackAnim, playSpeed, 12.0f,
+ Animation_GetLastFrame(&gIronKnuckleHorizontalAttackAnim.common), ANIMMODE_ONCE_INTERP, 5.0f);
+ this->timer = 0;
+ this->blurEffectSpawnLock = -1;
+ this->actionFunc = EnIk_SingleHorizontalAttack;
+}
+
+void EnIk_SingleHorizontalAttack(EnIk* this, PlayState* play) {
+ this->timer++;
+ if (Animation_OnFrame(&this->skelAnime, 13.0f)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_SWING_AXE);
+ }
+ if ((this->skelAnime.curFrame > 12.0f) && (this->skelAnime.curFrame < 20.0f)) {
+ this->colliderQuad.base.atFlags |= AT_ON;
+ } else {
+ this->colliderQuad.base.atFlags &= ~AT_ON;
+ }
+ this->actor.shape.rot.y += this->actor.world.rot.z;
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ if (SkelAnime_Update(&this->skelAnime)) {
+ EnIk_SetupEndHorizontalAttack(this);
+ }
+}
+
+void EnIk_SetupEndHorizontalAttack(EnIk* this) {
+ Animation_Change(&this->skelAnime, &gIronKnuckleEndHorizontalAttackAnim, (this->drawArmorFlags) ? 2.0f : 1.0f, 0.0f,
+ Animation_GetLastFrame(&gIronKnuckleHorizontalAttackAnim), ANIMMODE_ONCE_INTERP, -4.0f);
+ this->actionFunc = EnIk_EndHorizontalAttack;
+}
+
+void EnIk_EndHorizontalAttack(EnIk* this, PlayState* play) {
+ if (SkelAnime_Update(&this->skelAnime)) {
+ EnIk_CheckActions(this, play);
+ }
+}
+
+void EnIk_SetupBlock(EnIk* this) {
+ this->actor.speedXZ = 0.0f;
+ Animation_Change(&this->skelAnime, &gIronKnuckleBlockAnim, 2.0f, 0.0f,
+ Animation_GetLastFrame(&gIronKnuckleBlockAnim), ANIMMODE_ONCE, -2.0f);
+ this->timer = 20;
+ this->actionFunc = EnIk_Block;
+}
+
+void EnIk_Block(EnIk* this, PlayState* play) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderTris.base);
+ if (SkelAnime_Update(&this->skelAnime)) {
+ this->timer--;
+ if (this->timer == 0) {
+ EnIk_CheckActions(this, play);
+ }
+ }
+}
+
+void EnIk_SetupReactToAttack(EnIk* this, s32 arg1) {
+ s16 temp_v0;
+
+ if (arg1) {
+ func_800BE504(&this->actor, &this->colliderCylinder);
+ }
+ this->actor.speedXZ = 6.0f;
+ temp_v0 = (this->actor.world.rot.y - this->actor.shape.rot.y) + 0x8000;
+ if (ABS_ALT(temp_v0) <= 0x4000) {
+ Animation_MorphToPlayOnce(&this->skelAnime, &gIronKnuckleFrontHitAnim, -4.0f);
+ } else {
+ Animation_MorphToPlayOnce(&this->skelAnime, &gIronKnuckleBackHitAnim, -4.0f);
+ }
+ this->actionFunc = EnIk_ReactToAttack;
+}
+
+void EnIk_ReactToAttack(EnIk* this, PlayState* play) {
+ Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f);
+ if (this->subCamId != CAM_ID_MAIN) {
+ Play_CameraSetAtEye(play, this->subCamId, &this->actor.focus.pos, &Play_GetCamera(play, this->subCamId)->eye);
+ }
+ if (SkelAnime_Update(&this->skelAnime)) {
+ if (this->subCamId != CAM_ID_MAIN) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ this->subCamId = CAM_ID_MAIN;
+ EnIk_SetupIdle(this);
+ } else {
+ EnIk_CheckActions(this, play);
+ }
+ } else {
+ this->actor.colorFilterTimer = 12;
+ this->invincibilityFrames = 12;
+ }
+}
+
+void EnIk_SetupDie(EnIk* this) {
+ this->actor.speedXZ = 0.0f;
+ Animation_MorphToPlayOnce(&this->skelAnime, &gIronKnuckleDeathAnim, -4.0f);
+ this->timer = 24;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_DEAD);
+ this->actionFunc = EnIk_Die;
+}
+
+void EnIk_Die(EnIk* this, PlayState* play) {
+ static Vec3f sEffectVelAndAccel = { 0.0f, 0.5f, 0.0f };
+ s32 i;
+ Vec3f effectPos;
+
+ this->invincibilityFrames = 12;
+ if (SkelAnime_Update(&this->skelAnime)) {
+ if (this->timer == 24) {
+ SoundSource_PlaySfxEachFrameAtFixedWorldPos(play, &this->actor.world.pos, 35,
+ NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG);
+ }
+
+ if (this->timer != 0) {
+ this->timer--;
+ for (i = 6 - (this->timer >> 2); i >= 0; i--) {
+ effectPos.x = randPlusMinusPoint5Scaled(80.0f) + this->actor.world.pos.x;
+ effectPos.z = randPlusMinusPoint5Scaled(80.0f) + this->actor.world.pos.z;
+ effectPos.y = randPlusMinusPoint5Scaled(50.0f) + (this->actor.world.pos.y + 20.0f);
+ func_800B3030(play, &effectPos, &sEffectVelAndAccel, &sEffectVelAndAccel, 100, 0, 2);
+ }
+ if (this->timer == 0) {
+ Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0);
+ ActorCutscene_Stop(this->actor.cutscene);
+ Actor_MarkForDeath(&this->actor);
+ }
+ }
+ } else if (Animation_OnFrame(&this->skelAnime, 23.0f)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_WALK);
+ }
+}
+
+void EnIk_SetupFrozen(EnIk* this) {
+ this->invincibilityFrames = 0;
+ this->actionFunc = EnIk_Frozen;
+ this->actor.speedXZ = 0.0f;
+}
+
+void EnIk_Frozen(EnIk* this, PlayState* play) {
+ if (this->timer != 0) {
+ this->timer--;
+ }
+ if (this->timer == 0) {
+ EnIk_Thaw(this, play);
+ if (this->actor.colChkInfo.health == 0) {
+ EnIk_SetupCutscene(this);
+ } else {
+ EnIk_CheckActions(this, play);
+ }
+ }
+}
+
+void EnIk_SetupCutscene(EnIk* this) {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ this->actor.speedXZ = 0.0f;
+ if (this->actor.colChkInfo.health != 0) {
+ func_800BE504(&this->actor, &this->colliderCylinder);
+ }
+ this->actionFunc = EnIk_PlayCutscene;
+}
+
+void EnIk_PlayCutscene(EnIk* this, PlayState* play) {
+ Vec3f subCamEye;
+
+ this->invincibilityFrames = 12;
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ if (this->actor.cutscene != -1) {
+ ActorCutscene_StartAndSetFlag(this->actor.cutscene, &this->actor);
+ this->subCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene);
+ subCamEye.x = (Math_SinS((this->actor.shape.rot.y - 0x2000)) * 120.0f) + this->actor.focus.pos.x;
+ subCamEye.y = this->actor.focus.pos.y + 20.0f;
+ subCamEye.z = (Math_CosS((this->actor.shape.rot.y - 0x2000)) * 120.0f) + this->actor.focus.pos.z;
+ Play_CameraSetAtEye(play, this->subCamId, &this->actor.focus.pos, &subCamEye);
+ }
+ if (this->actor.colChkInfo.health != 0) {
+ EnIk_SetupReactToAttack(this, false);
+ } else {
+ EnIk_SetupDie(this);
+ }
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
+
+void EnIk_UpdateDamage(EnIk* this, PlayState* play) {
+ s32 pad;
+
+ if (this->actionFunc == EnIk_Idle) {
+ return;
+ }
+ if (this->colliderTris.base.acFlags & AC_BOUNCED) {
+ f32 frame = Animation_GetLastFrame(&gIronKnuckleBlockAnim) - 2.0f;
+
+ if (this->skelAnime.curFrame < frame) {
+ this->skelAnime.curFrame = frame;
+ }
+ this->colliderTris.base.acFlags &= ~AC_BOUNCED;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ s32 isArmorBroken = false;
+
+ Actor_SetDropFlag(&this->actor, &this->colliderCylinder.info);
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ if ((this->actor.colChkInfo.damageEffect != DMG_EFF_IMMUNE) &&
+ ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) ||
+ (!(this->colliderCylinder.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)))) {
+ Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 12);
+ this->invincibilityFrames = 12;
+ EnIk_Thaw(this, play);
+ this->colliderQuad.base.atFlags &= ~AT_ON;
+ if (Actor_ApplyDamage(&this->actor) == 0) {
+ if (this->drawArmorFlags == 0) {
+ this->actor.colChkInfo.health = 9;
+ isArmorBroken = true;
+ } else {
+ Enemy_StartFinishingBlow(play, &this->actor);
+ func_801A2ED8();
+ }
+ }
+ if (isArmorBroken == true) {
+ this->drawArmorFlags = 1;
+ this->colliderCylinder.base.colType = 3;
+ this->actor.colChkInfo.damageTable = &sDamageTableNoArmor;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_ARMOR_OFF_DEMO);
+ EnIk_SetupCutscene(this);
+ } else if (this->drawArmorFlags) {
+ if (this->actor.colChkInfo.damageEffect == DMG_EFF_ICE) {
+ EnIk_Freeze(this);
+ EnIk_SetupFrozen(this);
+ if (this->actor.colChkInfo.health == 0) {
+ this->timer = 3;
+ this->invincibilityFrames = 12;
+ }
+ } else {
+ if (this->actor.colChkInfo.damageEffect == DMG_EFF_FIRE) {
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffScale = 0.65f;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ } else if (this->actor.colChkInfo.damageEffect == DMG_EFF_LIGHT_SPARKS) {
+ EnIk_HitArmor(this, play);
+ }
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_DAMAGE);
+ if (this->actor.colChkInfo.health != 0) {
+ EnIk_SetupReactToAttack(this, true);
+ } else {
+ EnIk_SetupCutscene(this);
+ }
+ }
+ } else {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_ARMOR_HIT);
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IRONNACK_DAMAGE);
+ if (this->actor.colChkInfo.damageEffect == 4) {
+ EnIk_HitArmor(this, play);
+ }
+ }
+ }
+ }
+}
+
+void EnIk_UpdateArmor(EnIk* this, PlayState* play) {
+ s32 pad;
+ s32 i;
+ IronKnuckleEffect* ikEffect;
+ Vec3f effectPos;
+
+ for (i = 0; i < ARRAY_COUNT(this->effects); i++) {
+ ikEffect = &this->effects[i];
+
+ if (ikEffect->enabled) {
+ Math_Vec3f_Sum(&ikEffect->pos, &ikEffect->vel, &ikEffect->pos);
+ ikEffect->vel.y += -1.5f;
+ if (ikEffect->pos.y < this->actor.floorHeight) {
+ ikEffect->enabled = false;
+ ikEffect->pos.y = this->actor.floorHeight;
+
+ for (i = 0; i < 4; i++) {
+ effectPos.x = randPlusMinusPoint5Scaled(20.0f) + ikEffect->pos.x;
+ effectPos.y = Rand_ZeroFloat(20.0f) + ikEffect->pos.y;
+ effectPos.z = randPlusMinusPoint5Scaled(20.0f) + ikEffect->pos.z;
+ func_800B3030(play, &effectPos, &gZeroVec3f, &gZeroVec3f, 40, 7, 2);
+ }
+
+ SoundSource_PlaySfxAtFixedWorldPos(play, &ikEffect->pos, 11, NA_SE_EN_EXTINCT);
+ }
+ }
+ }
+}
+
+void EnIk_Update(Actor* thisx, PlayState* play2) {
+ PlayState* play = play2;
+ EnIk* this = THIS;
+
+ if (this->actionFunc != EnIk_PlayCutscene) {
+ EnIk_UpdateDamage(this, play);
+ } else {
+ this->colliderTris.base.acFlags &= ~AC_BOUNCED;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ }
+ this->actionFunc(this, play);
+ Actor_MoveWithGravity(&this->actor);
+ Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 30.0f, 30.0f, 0x1D);
+ this->actor.focus.rot.y = this->actor.shape.rot.y;
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base);
+ if (this->invincibilityFrames == 0) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
+ } else {
+ this->invincibilityFrames--;
+ }
+ if (this->colliderQuad.base.atFlags & AT_ON) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderQuad.base);
+ }
+ if (this->actionFunc == EnIk_Block) {
+ f32 cos;
+ f32 sin;
+ Vec3f sp5C;
+ Vec3f sp50;
+ Vec3f sp44;
+
+ cos = Math_CosS(this->actor.shape.rot.y);
+ sin = Math_SinS(this->actor.shape.rot.y);
+
+ sp44.x = (this->actor.world.pos.x - (30.0f * cos)) + (20.0f * sin);
+ sp44.y = this->actor.world.pos.y;
+ sp44.z = this->actor.world.pos.z + (30.0f * sin) + (20.0f * cos);
+
+ sp50.x = this->actor.world.pos.x + (30.0f * cos) + (20.0f * sin);
+ sp50.y = this->actor.world.pos.y + 80.0f;
+ sp50.z = (this->actor.world.pos.z - (30.0f * sin)) + (20.0f * cos);
+
+ sp5C.x = sp44.x;
+ sp5C.y = sp50.y;
+ sp5C.z = sp44.z;
+
+ Collider_SetTrisVertices(&this->colliderTris, 0, &sp44, &sp50, &sp5C);
+ sp5C.x = sp50.x;
+ sp5C.y = sp44.y;
+ sp5C.z = sp50.z;
+ Collider_SetTrisVertices(&this->colliderTris, 1, &sp44, &sp5C, &sp50);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderTris.base);
+ }
+ if (this->drawDmgEffAlpha > 0.0f) {
+ if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f);
+ this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.325f;
+ if ((this->drawDmgEffAlpha + 1.0f) * 0.325f > 0.65f) {
+ this->drawDmgEffScale = 0.65f;
+ } else {
+ this->drawDmgEffScale = this->drawDmgEffScale;
+ }
+ } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.65f, 0.01625f)) {
+ func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+ }
+ EnIk_UpdateArmor(this, play);
+}
+
+s8 D_8092C1A8[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 3, 5, 4, 6, 1, 2, -1, -1, 0, 0,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A33C.s")
+s32 EnIk_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnIk* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A570.s")
+ if (this->drawArmorFlags) {
+ if (D_8092C1A8[limbIndex] > 0) {
+ *dList = NULL;
+ }
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A5BC.s")
+void EnIk_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f D_8092C1C8 = { 2000.0f, -200.0f, -5200.0f };
+ static Vec3f D_8092C1D4 = { 300.0f, -200.0f, 0.0f };
+ static s8 limbPosIndex[] = {
+ -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1, -1, 6, -1, -1, 7,
+ -1, -1, 8, -1, 9, 10, -1, 11, -1, 12, -1, -1, -1, -1, 0, 0,
+ };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A680.s")
+ EnIk* this = THIS;
+ s32 index = D_8092C1A8[limbIndex];
+ Gfx* xlu;
+ IronKnuckleEffect* ikEffect;
+ s16 sp76;
+ Vec3f vtxC;
+ Vec3f vtxD;
+ Vec3f vtxB;
+ Vec3f vtxA;
+ MtxF* mf;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A754.s")
+ if (this->drawArmorFlags == 0x1) {
+ if (index > 0) {
+ ikEffect = &this->effects[index];
+ mf = Matrix_GetCurrent();
+ ikEffect->pos.x = mf->mf[3][0];
+ ikEffect->pos.y = mf->mf[3][1];
+ ikEffect->pos.z = mf->mf[3][2];
+ Matrix_MtxFToYXZRot(mf, &ikEffect->rot, false);
+ ikEffect->enabled = true;
+ sp76 = sIronKnuckleArmorMarkings[index].unk04 + (((s32)Rand_Next() >> 0x13) + this->actor.shape.rot.y);
+ ikEffect->vel.x = Math_SinS(sp76) * 5.0f;
+ ikEffect->vel.y = 6.0f;
+ ikEffect->vel.z = Math_CosS(sp76) * 5.0f;
+ ikEffect->dList = *dList;
+ }
+ if (limbIndex == IRON_KNUCKLE_LIMB_WAIST) {
+ this->drawArmorFlags |= 0x2;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A8D8.s")
+ if (limbIndex == IRON_KNUCKLE_LIMB_ROOT) {
+ Matrix_MultZero(&this->actor.focus.pos);
+ this->colliderCylinder.dim.pos.x = this->actor.focus.pos.x;
+ this->colliderCylinder.dim.pos.y = this->actor.world.pos.y;
+ this->colliderCylinder.dim.pos.z = this->actor.focus.pos.z;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092A994.s")
+ if ((limbIndex == IRON_KNUCKLE_LIMB_AXE) && (this->blurEffectSpawnLock != this->timer) &&
+ ((this->actionFunc == EnIk_VerticalAttack) || (this->actionFunc == EnIk_HorizontalDoubleAttack) ||
+ (this->actionFunc == EnIk_SingleHorizontalAttack))) {
+ Math_Vec3f_Copy(&vtxC, &this->colliderQuad.dim.quad[0]);
+ Math_Vec3f_Copy(&vtxD, &this->colliderQuad.dim.quad[1]);
+ Matrix_MultVec3f(&D_8092C1C8, &vtxB);
+ Matrix_MultVec3f(&D_8092C1D4, &vtxA);
+ Collider_SetQuadVertices(&this->colliderQuad, &vtxA, &vtxB, &vtxC, &vtxD);
+ if (this->colliderQuad.base.atFlags & AT_ON) {
+ EffectBlure_AddVertex(Effect_GetByIndex(this->effectIndex), &vtxB, &vtxA);
+ }
+ this->blurEffectSpawnLock = this->timer;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AA6C.s")
+ if (limbPosIndex[limbIndex] != -1) {
+ Matrix_MultZero(&this->limbPos[limbPosIndex[limbIndex]]);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AB14.s")
+ if ((index == 0) ||
+ ((index != -1) && (this->drawArmorFlags == 0) && (sIronKnuckleArmorMarkings[index].unk00 != 0))) {
+ OPEN_DISPS(play->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AB50.s")
+ xlu = POLY_XLU_DISP;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092ABD8.s")
+ gSPMatrix(&xlu[0], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(&xlu[1], sIronKnuckleArmorMarkings[index].unk00);
+ POLY_XLU_DISP = &xlu[2];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AC4C.s")
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092ACFC.s")
+void EnIk_UpdateArmorDraw(EnIk* this, PlayState* play) {
+ Gfx* gfxOpa;
+ Gfx* gfxXlu;
+ s32 sp54;
+ IronKnuckleEffect* ikEffect;
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092ADB4.s")
+ if (this->drawArmorFlags == (0x1 | 0x2)) {
+ sp54 = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AE14.s")
+ OPEN_DISPS(play->state.gfxCtx);
+ gfxOpa = POLY_OPA_DISP;
+ gfxXlu = POLY_XLU_DISP;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AFB4.s")
+ for (i = 0; i < ARRAY_COUNT(this->effects); i++) {
+ ikEffect = &this->effects[i];
+ if (ikEffect->enabled) {
+ Matrix_SetTranslateRotateYXZ(ikEffect->pos.x, ikEffect->pos.y, ikEffect->pos.z, &ikEffect->rot);
+ Matrix_Scale(0.012f, 0.012f, 0.012f, MTXMODE_APPLY);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092AFD4.s")
+ gSPMatrix(gfxOpa++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfxOpa++, ikEffect->dList);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B03C.s")
+ if (sIronKnuckleArmorMarkings[i].unk00 != NULL) {
+ gSPMatrix(gfxXlu++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfxXlu++, sIronKnuckleArmorMarkings[i].unk00);
+ }
+ } else {
+ sp54++;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B098.s")
+ if (sp54 == ARRAY_COUNT(this->effects)) {
+ this->drawArmorFlags = (0x1 | 0x4);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B1B4.s")
+ POLY_XLU_DISP = gfxXlu;
+ POLY_OPA_DISP = gfxOpa;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B46C.s")
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/EnIk_Update.s")
+void EnIk_Draw(Actor* thisx, PlayState* play) {
+ static Vec3f D_8092C200 = { 0.53f, 0.53f, 0.53f };
+ EnIk* this = THIS;
+ Gfx* gfx;
+ Gfx** gfxArmorType;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B900.s")
+ OPEN_DISPS(play->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092B93C.s")
+ func_800B8050(&this->actor, play, 0);
+ func_800B8118(&this->actor, play, 0);
+ gfx = POLY_XLU_DISP;
+ gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]);
+ POLY_XLU_DISP = &gfx[1];
+ gfx = POLY_OPA_DISP;
+ gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]);
+ gfxArmorType = sIronKnuckleArmorType[this->actor.params];
+ gSPSegment(&gfx[1], 0x08, gfxArmorType[0]);
+ gSPSegment(&gfx[2], 0x09, gfxArmorType[1]);
+ gSPSegment(&gfx[3], 0x0A, gfxArmorType[2]);
+ POLY_OPA_DISP = &gfx[4];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/func_8092BC6C.s")
+ SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ EnIk_OverrideLimbDraw, EnIk_PostLimbDraw, &this->actor);
+ EnIk_UpdateArmorDraw(this, play);
+ if (this->actor.colorFilterTimer != 0) {
+ func_800AE5A0(play);
+ }
+ func_800BC620(&this->actor.focus.pos, &D_8092C200, 255, play);
+ Actor_DrawDamageEffects(play, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale,
+ this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ik/EnIk_Draw.s")
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Ik/z_en_ik.h b/src/overlays/actors/ovl_En_Ik/z_en_ik.h
index 39dfff7b9..a02c4845e 100644
--- a/src/overlays/actors/ovl_En_Ik/z_en_ik.h
+++ b/src/overlays/actors/ovl_En_Ik/z_en_ik.h
@@ -2,16 +2,50 @@
#define Z_EN_IK_H
#include "global.h"
+#include "objects/object_ik/object_ik.h"
struct EnIk;
typedef void (*EnIkActionFunc)(struct EnIk*, PlayState*);
+#define IK_GET_ARMOR_TYPE(thisx) ((thisx)->params & 0xFF)
+
+typedef enum {
+ /* 1 */ IK_TYPE_SILVER = 1,
+ /* 2 */ IK_TYPE_BLACK,
+ /* 3 */ IK_TYPE_WHITE
+} EnIkType;
+
+typedef struct {
+ /* 0x00 */ Gfx* dList;
+ /* 0x04 */ Vec3f pos;
+ /* 0x10 */ Vec3f vel;
+ /* 0x1C */ Vec3s rot;
+ /* 0x24 */ s32 enabled;
+} IronKnuckleEffect; // size = 0x28
+
typedef struct EnIk {
- /* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x1AC];
- /* 0x2F0 */ EnIkActionFunc actionFunc;
- /* 0x2F4 */ char unk_2F4[0x374];
+ /* 0x0000 */ Actor actor;
+ /* 0x0144 */ SkelAnime skelAnime;
+ /* 0x0188 */ Vec3s jointTable[IRON_KNUCKLE_LIMB_MAX];
+ /* 0x023C */ Vec3s morphTable[IRON_KNUCKLE_LIMB_MAX];
+ /* 0x02F0 */ EnIkActionFunc actionFunc;
+ /* 0x02F4 */ u8 drawArmorFlags; // Value is 0 when Iron knuckle has armor, then changes to 5 for when armor is lost
+ /* 0x02F5 */ u8 drawDmgEffType;
+ /* 0x02F6 */ s16 timer;
+ /* 0x02F8 */ s16 blurEffectSpawnLock;
+ /* 0x02FA */ s16 subCamId;
+ /* 0x02FC */ s16 invincibilityFrames;
+ /* 0x0300 */ s32 effectIndex;
+ /* 0x0304 */ f32 drawDmgEffAlpha;
+ /* 0x0308 */ f32 drawDmgEffScale;
+ /* 0x030C */ f32 drawDmgEffFrozenSteamScale;
+ /* 0x0310 */ Vec3f limbPos[13];
+ /* 0x03AC */ ColliderCylinder colliderCylinder;
+ /* 0x03F8 */ ColliderQuad colliderQuad;
+ /* 0x0478 */ ColliderTris colliderTris;
+ /* 0x0498 */ ColliderTrisElement shieldColliderItems[2];
+ /* 0x0550 */ IronKnuckleEffect effects[7];
} EnIk; // size = 0x668
extern const ActorInit En_Ik_InitVars;