From 78eeb3ffe832da80abc75c6976c228398d724e2a Mon Sep 17 00:00:00 2001 From: Thar0 <17233964+Thar0@users.noreply.github.com> Date: Sat, 25 Jun 2022 23:09:57 +0100 Subject: [PATCH] Matched --- assets/xml/objects/object_death.xml | 98 +- spec | 7 +- src/overlays/actors/ovl_En_Death/z_en_death.c | 1859 ++++++++++------- src/overlays/actors/ovl_En_Death/z_en_death.h | 68 +- .../actors/ovl_En_Minideath/z_en_minideath.c | 884 +++++++- .../actors/ovl_En_Minideath/z_en_minideath.h | 39 +- tools/disasm/functions.txt | 4 +- 7 files changed, 2009 insertions(+), 950 deletions(-) diff --git a/assets/xml/objects/object_death.xml b/assets/xml/objects/object_death.xml index 7d3e1e596..00a0bdd49 100644 --- a/assets/xml/objects/object_death.xml +++ b/assets/xml/objects/object_death.xml @@ -1,12 +1,12 @@  - - - - - - - + + + + + + + @@ -39,47 +39,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec b/spec index a2d9a9ef3..f5071e60a 100644 --- a/spec +++ b/spec @@ -1093,17 +1093,14 @@ beginseg name "ovl_En_Death" compress include "build/src/overlays/actors/ovl_En_Death/z_en_death.o" - include "build/data/ovl_En_Death/ovl_En_Death.data.o" - include "build/data/ovl_En_Death/ovl_En_Death.reloc.o" + include "build/src/overlays/actors/ovl_En_Death/ovl_En_Death_reloc.o" endseg beginseg name "ovl_En_Minideath" compress include "build/src/overlays/actors/ovl_En_Minideath/z_en_minideath.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.data.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.bss.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.reloc.o" + include "build/src/overlays/actors/ovl_En_Minideath/ovl_En_Minideath_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Death/z_en_death.c b/src/overlays/actors/ovl_En_Death/z_en_death.c index 5a2d21161..bb3d8e0c3 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.c +++ b/src/overlays/actors/ovl_En_Death/z_en_death.c @@ -5,6 +5,8 @@ */ #include "z_en_death.h" +#include "overlays/actors/ovl_Arrow_Light/z_arrow_light.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_1000) @@ -15,45 +17,45 @@ void EnDeath_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnDeath_Update(Actor* thisx, GlobalContext* globalCtx); void EnDeath_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808C589C(EnDeath* this, GlobalContext* globalCtx); -void func_808C5AB8(EnDeath* this, GlobalContext* globalCtx); -void func_808C5CB4(EnDeath* this, GlobalContext* globalCtx); -void func_808C5E90(EnDeath* this, GlobalContext* globalCtx); -void func_808C6070(EnDeath* this, GlobalContext* globalCtx); -void func_808C64DC(EnDeath* this, GlobalContext* globalCtx); -void func_808C66A8(EnDeath* this, GlobalContext* globalCtx); -void func_808C682C(EnDeath* this, GlobalContext* globalCtx); -void func_808C692C(EnDeath* this, GlobalContext* globalCtx); -void func_808C6AB0(EnDeath* this, GlobalContext* globalCtx); -void func_808C6CDC(EnDeath* this, GlobalContext* globalCtx); -void func_808C6F6C(EnDeath* this, GlobalContext* globalCtx); -void func_808C72AC(EnDeath* this, GlobalContext* globalCtx); -void func_808C74F8(EnDeath* this, GlobalContext* globalCtx); -void func_808C7888(EnDeath* this, GlobalContext* globalCtx); -void func_808C7AAC(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_IntroCutscenePart1(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_IntroCutscenePart2(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_IntroCutscenePart3(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_IntroCutscenePart4(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_IntroCutscenePart5(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_ApproachPlayer(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SwingAttack(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_EndSwingAttack(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_BlockProjectile(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SpinAttack(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_Damaged(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_DeathCutscenePart1(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_DeathCutscenePart2(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_DeathCutscenePart3(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_DeathCutscenePart4(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_Dead(EnDeath* this, GlobalContext* globalCtx); void func_808C7B88(EnDeath* this, GlobalContext* globalCtx); void func_808C7C88(EnDeath* this, GlobalContext* globalCtx); -void func_808C7D34(EnDeath* this, GlobalContext* globalCtx); -void func_808C7DCC(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_PlayCutscene(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_BeginWithoutCutscene(EnDeath* this, GlobalContext* globalCtx); -void func_808C597C(EnDeath* this, GlobalContext* globalCtx); -void func_808C5C0C(EnDeath* this); -void func_808C5D6C(EnDeath* this, GlobalContext* globalCtx); -void func_808C5F58(EnDeath* this, GlobalContext* globalCtx); -void func_808C645C(EnDeath* this); -void func_808C6620(EnDeath* this); -void func_808C67C8(EnDeath* this); -void func_808C68B8(EnDeath* this); -void func_808C6A08(EnDeath* this); -void func_808C70D8(EnDeath* this, GlobalContext* globalCtx); -void func_808C74A4(EnDeath* this); -void func_808C7A30(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SetupIntroCutscenePart2(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SetupIntroCutscenePart3(EnDeath* this); +void EnDeath_SetupIntroCutscenePart4(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SetupIntroCutscenePart5(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SetupApproachPlayer(EnDeath* this); +void EnDeath_SetupSwingAttack(EnDeath* this); +void EnDeath_SetupEndSwingAttack(EnDeath* this); +void EnDeath_SetupBlockProjectile(EnDeath* this); +void EnDeath_SetupSpinAttack(EnDeath* this); +void EnDeath_SetupDeathCutscenePart2(EnDeath* this, GlobalContext* globalCtx); +void EnDeath_SetupDeathCutscenePart3(EnDeath* this); +void EnDeath_SetupDead(EnDeath* this, GlobalContext* globalCtx); void func_808C7AEC(EnDeath* this); void func_808C7C04(EnDeath* this); -void func_808C7CFC(EnDeath* this); -void func_808C7DB8(EnDeath* this); +void EnDeath_SetupPlayCutscene(EnDeath* this); +void EnDeath_SetupBeginWithoutCutscene(EnDeath* this); +void EnDeath_SetupDeathCutscenePart4(EnDeath* this); -#if 0 const ActorInit En_Death_InitVars = { ACTOR_EN_DEATH, ACTORCAT_ENEMY, @@ -68,82 +70,159 @@ const ActorInit En_Death_InitVars = { // static ColliderSphereInit sSphereInit = { static ColliderSphereInit D_808C98E0 = { - { COLTYPE_HIT3, AT_NONE, AC_NONE | AC_TYPE_GET_PLAYER(globalCtx), OC1_NONE, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + COLTYPE_HIT3, + AT_NONE, + AC_NONE | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 1, { { 0, 0, 0 }, 22 }, 100 }, }; // static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_808C990C = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 35, 90, 20, { 0, 0, 0 } }, }; // static ColliderTrisElementInit sTrisElementsInit[2] = { static ColliderTrisElementInit D_808C9938[2] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x04, 0x20 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x04, 0x20 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, }; // static ColliderTrisInit sTrisInit = { static ColliderTrisInit D_808C99B0 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_GET_PLAYER(globalCtx), OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, }, - 2, D_808C9938, // sTrisElementsInit, + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + 2, + D_808C9938, // sTrisElementsInit, }; // static ColliderQuadInit sQuadInit = { static ColliderQuadInit D_808C99C0 = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_2, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x20 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, BUMP_NONE, OCELEM_NONE, }, + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 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 } } }, }; +typedef enum { + DMGEFF_NONE = 0, + DMGEFF_FIRE_ARROW = 2, + DMGEFF_ICE_ARROW = 3, + DMGEFF_LIGHT_ARROW = 4, + DMGEFF_EXPLOSIVES = 15 +} EnDeathDamageEffect; + // static DamageTable sDamageTable = { static DamageTable D_808C9A10 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(1, 0x0), - /* Goron punch */ DMG_ENTRY(1, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 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(2, 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, 0xF), + /* Deku Nut */ DMG_ENTRY(0, DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(1, DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DMGEFF_EXPLOSIVES), + /* Zora boomerang */ DMG_ENTRY(1, DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(0, DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(1, DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal shield */ DMG_ENTRY(0, DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DMGEFF_EXPLOSIVES), }; // sColChkInfoInit static CollisionCheckInfoInit2 D_808C9A30 = { 20, 28, 90, 20, 100 }; +static EffectBlureInit2 D_808C9A3C = { + 0, 8, 0, { 100, 50, 100, 200 }, { 100, 0, 0, 64 }, { 100, 0, 0, 20 }, { 50, 0, 0, 0 }, 8, + 0, 2, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, +}; + // static InitChainEntry sInitChain[] = { static InitChainEntry D_808C9A60[] = { ICHAIN_VEC3F(scale, 0, ICHAIN_CONTINUE), @@ -152,129 +231,86 @@ static InitChainEntry D_808C9A60[] = { ICHAIN_U8(targetMode, 5, ICHAIN_STOP), }; -#endif - -extern ColliderSphereInit D_808C98E0; -extern ColliderCylinderInit D_808C990C; -extern ColliderTrisElementInit D_808C9938[2]; -extern ColliderTrisInit D_808C99B0; -extern ColliderQuadInit D_808C99C0; -extern DamageTable D_808C9A10; -extern CollisionCheckInfoInit2 D_808C9A30; -extern InitChainEntry D_808C9A60[]; -extern UNK_TYPE D_808C9A3C; -extern Vec3f D_808C9AF4; -extern Vec3f D_808C9B00; -extern Vec3f D_808C9B0C[]; -extern s8 D_808C9B48[]; -extern Vec3f D_808C9ABC; -extern Color_RGBA8 D_808C9AC8; -extern Color_RGBA8 D_808C9ACC; - -extern FlexSkeletonHeader D_0600AD08; -extern AnimationHeader D_06003CAC; -extern AnimationHeader D_0600CB2C; -extern AnimationHeader D_0600B284; -extern AnimationHeader D_0600B284; -extern AnimationHeader D_0600B508; -extern AnimationHeader D_06001F80; -extern AnimationHeader D_06000E64; -extern AnimationHeader D_06002DE8; -extern AnimationHeader D_0600352C; -extern AnimationHeader D_06001834; -extern AnimationHeader D_060015B4; -extern AnimatedMaterial D_0600CBC0; -extern AnimatedMaterial D_0600CB84; -extern Gfx D_06009988[]; -extern Gfx D_06009BA0[]; -extern Gfx D_06006F88[]; -extern Gfx D_060073D0[]; - -typedef struct { - Actor actor; - char unk_144[0x18]; - f32 unk_15C; -} UnkActor; - void EnDeath_Init(Actor* thisx, GlobalContext* globalCtx) { EnDeath* this = THIS; GlobalContext* globalCtx2 = globalCtx; - - f32 phi_f20 = 15.0f; - s16 phi_s3 = 0; - + f32 yOffset = 15.0f; + s16 yRot = 0; s32 i; Actor_ProcessInitChain(&this->actor, D_808C9A60); ActorShape_Init(&this->actor.shape, 5500.0f, ActorShadow_DrawCircle, 80.0f); - SkelAnime_InitFlex(globalCtx2, &this->skelAnime, &D_0600AD08, &D_06003CAC, this->unk_1E2, this->unk_266, 22); + SkelAnime_InitFlex(globalCtx2, &this->skelAnime, &gGomessSkel, &gGomessFloatAnim, this->jointTable, + this->morphTable, GOMESS_LIMB_MAX); - Collider_InitAndSetSphere(globalCtx2, &this->unk_808, &this->actor, &D_808C98E0); - Collider_InitAndSetCylinder(globalCtx2, &this->unk_73C, &this->actor, &D_808C990C); + Collider_InitAndSetSphere(globalCtx2, &this->coreCollider, &this->actor, &D_808C98E0); + Collider_InitAndSetCylinder(globalCtx2, &this->bodyCollider, &this->actor, &D_808C990C); Collider_InitAndSetQuad(globalCtx2, &this->unk_788, &this->actor, &D_808C99C0); Collider_InitAndSetTris(globalCtx2, &this->unk_860, &this->actor, &D_808C99B0, this->unk_880); - this->unk_808.dim.worldSphere.radius = this->unk_808.dim.modelSphere.radius; + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius; CollisionCheck_SetInfo2(&this->actor.colChkInfo, &D_808C9A10, &D_808C9A30); - Effect_Add(globalCtx2, &this->unk_300, 2, 0, 0, &D_808C9A3C); + Effect_Add(globalCtx2, &this->effectIndex, EFFECT_BLURE2, 0, 0, &D_808C9A3C); if (!(gSaveContext.eventInf[6] & 8)) { this->actor.world.pos.y += 400.0f; } - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i] = Actor_SpawnAsChild(&globalCtx2->actorCtx, &this->actor, globalCtx2, ACTOR_EN_MINIDEATH, - this->actor.world.pos.x, this->actor.world.pos.y + phi_f20, - this->actor.world.pos.z, 0, phi_s3, 0, i); - if (this->unk_6E4[i] == NULL) { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i] = (EnMinideath*)Actor_SpawnAsChild( + &globalCtx2->actorCtx, &this->actor, globalCtx2, ACTOR_EN_MINIDEATH, this->actor.world.pos.x, + this->actor.world.pos.y + yOffset, this->actor.world.pos.z, 0, yRot, 0, i); + if (this->miniDeaths[i] == NULL) { Actor_MarkForDeath(&this->actor); } - phi_s3 += 0x3A00; - phi_f20 += 4.0f; + yRot += 0x3A00; + yOffset += 4.0f; } - for (i = 0; i < ARRAY_COUNT(this->unk_6E4) - 1; i++) { - this->unk_6E4[i]->child = this->unk_6E4[i + 1]; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths) - 1; i++) { + this->miniDeaths[i]->actor.child = &this->miniDeaths[i + 1]->actor; } - this->unk_734 = Lib_SegmentedToVirtual(&D_0600CBC0); - this->unk_738 = Lib_SegmentedToVirtual(&D_0600CB84); + this->bodyMatAnim = Lib_SegmentedToVirtual(&gGomessBodyMatAnim); + this->coreMatAnim = Lib_SegmentedToVirtual(&gGomessCoreMatAnim); if (gSaveContext.eventInf[6] & 8) { - this->unk_18E = 1; + // Watched intro cutscene + this->unk_18E = true; Actor_SetScale(&this->actor, 0.01f); this->unk_191 = 0x17; - this->actor.params = 0x14; - this->unk_304 = 1.0f; - func_808C7DB8(this); - return; + this->actor.params = 20; + this->scytheScale = 1.0f; + EnDeath_SetupBeginWithoutCutscene(this); + } else { + // Start intro cutscene + this->unk_192 = true; + this->actor.flags &= ~ACTOR_FLAG_1; + EnDeath_SetupPlayCutscene(this); } - this->unk_192 = 1; - this->actor.flags &= ~1; - func_808C7CFC(this); } void EnDeath_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnDeath* this = THIS; - Collider_DestroySphere(globalCtx, &this->unk_808); - Collider_DestroyCylinder(globalCtx, &this->unk_73C); + Collider_DestroySphere(globalCtx, &this->coreCollider); + Collider_DestroyCylinder(globalCtx, &this->bodyCollider); Collider_DestroyQuad(globalCtx, &this->unk_788); Collider_DestroyTris(globalCtx, &this->unk_860); - Audio_StopSfxByPos(&this->unk_338); - Effect_Destroy(globalCtx, this->unk_300); + Audio_StopSfxByPos(&this->scytheScreenPos); + Effect_Destroy(globalCtx, this->effectIndex); } -void func_808C5310(GlobalContext* globalCtx) { +void EnDeath_DimLights(GlobalContext* globalCtx) { LightSettings* lightSettings; s32 i; - globalCtx->envCtx.lightSettingOverride = 0x14; - globalCtx->envCtx.unk_C1 = 0x14; - globalCtx->envCtx.unk_C2 = 0x14; + globalCtx->envCtx.lightSettingOverride = 20; + globalCtx->envCtx.unk_C1 = 20; + globalCtx->envCtx.unk_C2 = 20; globalCtx->envCtx.lightBlend = 1.0f; lightSettings = &globalCtx->envCtx.lightSettingsList[20]; @@ -284,174 +320,179 @@ void func_808C5310(GlobalContext* globalCtx) { } } -void func_808C5394(EnDeath* this) { - func_800B9010(&this->actor, 0x3260); +void EnDeath_Float(EnDeath* this) { + func_800B9010(&this->actor, NA_SE_EN_SHARP_FLOAT - SFX_FLAG); - if (this->unk_2EA == 0) { - this->unk_2EA = 0x28; + if (this->floatTimer == 0) { + this->floatTimer = 40; } - this->unk_2EA--; - this->actor.world.pos.y = (1.0f - Math_CosS(this->unk_2EA * 0x666)) * 7.5f + this->actor.home.pos.y; + this->floatTimer--; + this->actor.world.pos.y = this->actor.home.pos.y + (1.0f - Math_CosS(this->floatTimer * 0x666)) * 7.5f; } -s32 func_808C5428(EnDeath* this, GlobalContext* globalCtx) { - Actor* temp_v0 = func_800BC270(globalCtx, &this->actor, 80.0f, 0x138B0); +s32 EnDeath_ProjectileApproaching(EnDeath* this, GlobalContext* globalCtx) { + Actor* projectileActor = + func_800BC270(globalCtx, &this->actor, 80.0f, 0x10000 | 0x2000 | 0x1000 | 0x800 | 0x80 | 0x20 | 0x10); s16 ret; - if (temp_v0 != NULL && - (ret = Actor_YawBetweenActors(&this->actor, temp_v0) - this->actor.shape.rot.y, ABS_ALT(ret) < 0x2000) && - (ret = Actor_PitchToPoint(temp_v0, &this->actor.focus.pos) - temp_v0->world.rot.x, ABS_ALT(ret) < 0x3000)) { - return 1; + if (projectileActor != NULL && + (ret = Actor_YawBetweenActors(&this->actor, projectileActor) - this->actor.shape.rot.y, + ABS_ALT(ret) < 0x2000) && + (ret = Actor_PitchToPoint(projectileActor, &this->actor.focus.pos) - projectileActor->world.rot.x, + ABS_ALT(ret) < 0x3000)) { + return true; } - return 0; + return false; } -void func_808C54F0(EnDeath* this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C54F0.s") -/* -void func_808C54F0(EnDeath *this) { - f32 sp64 = Math_SinS(this->actor.shape.rot.y); - f32 sp60 = Math_CosS(this->actor.shape.rot.y); +void EnDeath_UpdateSpinAttackTris(EnDeath* this) { + f32 sinRotY = Math_SinS(this->actor.shape.rot.y); + f32 cosRotY = Math_CosS(this->actor.shape.rot.y); Vec3f sp54; Vec3f sp48; Vec3f sp3C; - sp3C.x = this->actor.world.pos.x - (70.0f * sp60) + (75.0f * sp64); + sp3C.x = this->actor.world.pos.x - 70.0f * cosRotY + 75.0f * sinRotY; sp3C.y = this->actor.world.pos.y + -10.0f; - sp3C.z = this->actor.world.pos.z + (70.0f * sp64) + (75.0f * sp60); + sp3C.z = this->actor.world.pos.z + 70.0f * sinRotY + 75.0f * cosRotY; - sp48.x = this->actor.world.pos.x + (70.0f * sp60) + (65.0f * sp64); + sp48.x = this->actor.world.pos.x + 70.0f * cosRotY + 65.0f * sinRotY; sp48.y = sp3C.y + 150.0f; - sp48.z = this->actor.world.pos.z - (70.0f * sp64) + (65.0f * sp60); - - sp54.x = sp3C.x + (-10.0f * sp64); - sp54.y = sp3C.y + 150.0f; - sp54.z = sp3C.z + (-10.0f * sp60); + sp48.z = this->actor.world.pos.z - 70.0f * sinRotY + 65.0f * cosRotY; + sp54.x = sp3C.x; + sp54.x += -10.0f * sinRotY; + sp54.y = sp48.y; + sp54.z = sp3C.z; + sp54.z += -10.0f * cosRotY; Collider_SetTrisVertices(&this->unk_860, 0, &sp3C, &sp48, &sp54); - sp54.x = sp48.x + (10.0f * sp64); + sp54.x = sp48.x; + sp54.x += 10.0f * sinRotY; sp54.y = sp3C.y; - sp54.z = sp48.z + (10.0f * sp60); - + sp54.z = sp48.z; + sp54.z += 10.0f * cosRotY; Collider_SetTrisVertices(&this->unk_860, 1, &sp3C, &sp54, &sp48); } -*/ -#ifdef NON_MATCHING -// regalloc differences -f32 func_808C566C(EnDeath* this) { - this->unk_308 = this->actor.world.pos.y - this->actor.home.pos.y; - this->unk_308 = CLAMP_MIN(this->unk_308, 0.0f); - this->unk_308 *= 0.02f; - this->unk_308 = SQ(this->unk_308) * 3.0f + 80.0f; - this->unk_2F6 += (s16)(65536.0f * (22.5f / (this->unk_308 * (2 * M_PI)))); +f32 EnDeath_UpdateCoreVelocityAndRotation(EnDeath* this) { + f32 tmp; + + this->coreVelocity = this->actor.world.pos.y - this->actor.home.pos.y; + this->coreVelocity = CLAMP_MIN(this->coreVelocity, 0.0f); + this->coreVelocity *= 0.02f; + this->coreVelocity = SQ(this->coreVelocity) * 3.0f + 80.0f; + + tmp = 22.5f / (this->coreVelocity * (2 * M_PI)); + this->coreRotation += (s16)(65536.0f * tmp); } -#else -f32 func_808C566C(EnDeath* this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C566C.s") -#endif -void func_808C571C(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_SetupIntroCutscenePart1(EnDeath* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp30; - Vec3f sp24; + Vec3f eye; + Vec3f at; this->actor.shape.rot.y = this->actor.shape.rot.y - 0x657A; - this->unk_2EE = 0x3C; - sp30.x = (Math_SinS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.x; - sp30.z = (Math_CosS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.z; - sp30.y = this->actor.home.pos.y + 3.0f; - sp24.x = this->actor.world.pos.x; - sp24.z = this->actor.world.pos.z; - sp24.y = this->actor.world.pos.y - 116.0f; + this->actionTimer = 60; + + eye.x = (Math_SinS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.x; + eye.z = (Math_CosS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.z; + eye.y = this->actor.home.pos.y + 3.0f; + + at.x = this->actor.world.pos.x; + at.z = this->actor.world.pos.z; + at.y = this->actor.world.pos.y - 116.0f; + player->actor.world.pos.x = Math_SinS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.x; player->actor.world.pos.z = Math_CosS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.z; player->actor.shape.rot.y = Actor_YawBetweenActors(&player->actor, &this->actor); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &sp24, &sp30); - Play_CameraSetFov(globalCtx, this->unk_2FA, 77.0f); + + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); + Play_CameraSetFov(globalCtx, this->camId, 77.0f); func_800B724C(globalCtx, &this->actor, 0x15); - this->unk_188 = func_808C589C; + + this->actionFunc = EnDeath_IntroCutscenePart1; } -void func_808C589C(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_IntroCutscenePart1(EnDeath* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); player->actor.world.pos.x = Math_SinS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.x; player->actor.world.pos.z = Math_CosS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.z; player->actor.shape.rot.y = Actor_YawBetweenActors(&player->actor, &this->actor); - if (this->unk_2EE == 0x19) { + if (this->actionTimer == 25) { func_800B724C(globalCtx, &this->actor, 0x51); } - if (this->unk_2EE > 0) { - this->unk_2EE--; + if (this->actionTimer > 0) { + this->actionTimer--; } else { - func_808C597C(this, globalCtx); + EnDeath_SetupIntroCutscenePart2(this, globalCtx); } - func_808C566C(this); + EnDeath_UpdateCoreVelocityAndRotation(this); } -void func_808C597C(EnDeath* this, GlobalContext* globalCtx) { - Camera* sp24 = Play_GetCamera(globalCtx, this->unk_2FA); +void EnDeath_SetupIntroCutscenePart2(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); s32 i; - func_808C5310(globalCtx); + EnDeath_DimLights(globalCtx); - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 7; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_7; } - this->unk_2EE = 0x32; - this->unk_344.x = Math_SinS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.x; - this->unk_344.z = Math_CosS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.z; - this->unk_344.y = this->actor.home.pos.y + 20.0f; - this->unk_350.x = this->actor.world.pos.x; - this->unk_350.z = this->actor.world.pos.z; - this->unk_350.y = this->actor.home.pos.y + 50.0f; - this->unk_30C = Math_Vec3f_DistXYZ(&sp24->eye, &this->unk_344) * 0.0225f; - this->unk_310 = Math_Vec3f_DistXYZ(&sp24->at, &this->unk_350) * 0.0225f; - this->unk_188 = func_808C5AB8; + this->actionTimer = 50; + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 20.0f; + this->camAtTarget.x = this->actor.world.pos.x; + this->camAtTarget.z = this->actor.world.pos.z; + this->camAtTarget.y = this->actor.home.pos.y + 50.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * 0.0225f; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * 0.0225f; + this->actionFunc = EnDeath_IntroCutscenePart2; } -void func_808C5AB8(EnDeath* this, GlobalContext* globalCtx) { - Camera* sp2C = Play_GetCamera(globalCtx, this->unk_2FA); +void EnDeath_IntroCutscenePart2(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); - if (this->unk_2EE == 0x2A) { + if (this->actionTimer == 42) { func_800B724C(globalCtx, &this->actor, 4); - } else if (this->unk_2EE == 0x1B) { + } else if (this->actionTimer == 27) { func_800B724C(globalCtx, &this->actor, 0x7B); } - if (this->unk_2EE <= 0) { + if (this->actionTimer <= 0) { if (this->actor.world.pos.y < (this->actor.home.pos.y + 400.0f) - 225.0f) { - globalCtx->envCtx.lightSettingOverride = 0x1A; + globalCtx->envCtx.lightSettingOverride = 26; } - Math_Vec3f_StepTo(&sp2C->eye, &this->unk_344, this->unk_30C); - Math_Vec3f_StepTo(&sp2C->at, &this->unk_350, this->unk_310); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &sp2C->at, &sp2C->eye); + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 9.0f) != 0) { - this->unk_2EE--; - if (this->unk_2EE == -0x14) { - func_808C5C0C(this); + this->actionTimer--; + if (this->actionTimer == -20) { + EnDeath_SetupIntroCutscenePart3(this); } } } else { - this->unk_2EE--; + this->actionTimer--; } - func_808C566C(this); + EnDeath_UpdateCoreVelocityAndRotation(this); } -void func_808C5C0C(EnDeath* this) { +void EnDeath_SetupIntroCutscenePart3(EnDeath* this) { gSaveContext.eventInf[6] |= 8; - Animation_Change(&this->skelAnime, &D_0600B284, 0.0f, 0.0f, Animation_GetLastFrame(&D_0600B284), 2, 0.0f); + Animation_Change(&this->skelAnime, &object_death_Anim_00B284, 0.0f, 0.0f, + Animation_GetLastFrame(&object_death_Anim_00B284), ANIMMODE_ONCE, 0.0f); this->actor.scale.y = 0.01f; this->actor.shape.rot.y += 0x777F; - Actor_PlaySfxAtPos(&this->actor, 0x3AB4); - this->unk_188 = func_808C5CB4; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_APPEAR); + this->actionFunc = EnDeath_IntroCutscenePart3; } -void func_808C5CB4(EnDeath* this, GlobalContext* globalCtx) { - s32 temp_v0 = Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f); +void EnDeath_IntroCutscenePart3(EnDeath* this, GlobalContext* globalCtx) { + s32 stepDone = Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f); f32 temp; this->actor.scale.z = this->actor.scale.x; @@ -460,393 +501,398 @@ void func_808C5CB4(EnDeath* this, GlobalContext* globalCtx) { temp = 0.0025f; } this->actor.shape.rot.y += (s16)(temp * 4505600.0f); - if (temp_v0 != 0) { - this->unk_192 = 0; - func_808C5D6C(this, globalCtx); + if (stepDone) { + this->unk_192 = false; + EnDeath_SetupIntroCutscenePart4(this, globalCtx); } - func_808C566C(this); + EnDeath_UpdateCoreVelocityAndRotation(this); } -void func_808C5D6C(EnDeath* this, GlobalContext* globalCtx) { - Camera* sp24 = Play_GetCamera(globalCtx, this->unk_2FA); - f32 sp20 = 1.0f / Animation_GetLastFrame(&D_0600B284); +void EnDeath_SetupIntroCutscenePart4(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); + f32 invAnimDuration = 1.0f / Animation_GetLastFrame(&object_death_Anim_00B284); - this->unk_2EE = 0xA; + this->actionTimer = 10; this->skelAnime.playSpeed = 1.0f; this->actor.shape.rot.y = this->actor.home.rot.y; - this->unk_344.x = Math_SinS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.x; - this->unk_344.z = Math_CosS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.z; - this->unk_344.y = this->actor.home.pos.y + 95.0f; - this->unk_350.x = this->actor.world.pos.x; - this->unk_350.z = this->actor.world.pos.z; - this->unk_350.y = this->actor.world.pos.y + 100.0f; - this->unk_30C = Math_Vec3f_DistXYZ(&sp24->eye, &this->unk_344) * sp20; - this->unk_310 = Math_Vec3f_DistXYZ(&sp24->at, &this->unk_350) * sp20; + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 95.0f; + this->camAtTarget.x = this->actor.world.pos.x; + this->camAtTarget.z = this->actor.world.pos.z; + this->camAtTarget.y = this->actor.world.pos.y + 100.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * invAnimDuration; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * invAnimDuration; - this->unk_188 = func_808C5E90; + this->actionFunc = EnDeath_IntroCutscenePart4; } -void func_808C5E90(EnDeath* this, GlobalContext* globalCtx) { - Camera* temp_v1 = Play_GetCamera(globalCtx, this->unk_2FA); +void EnDeath_IntroCutscenePart4(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); if (this->unk_191 < 23) { this->unk_191++; } - Math_Vec3f_StepTo(&temp_v1->eye, &this->unk_344, this->unk_30C); - Math_Vec3f_StepTo(&temp_v1->at, &this->unk_350, this->unk_310); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &temp_v1->at, &temp_v1->eye); + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_2EE > 0) { - this->unk_2EE--; + if (this->actionTimer > 0) { + this->actionTimer--; } else { - func_808C5F58(this, globalCtx); + EnDeath_SetupIntroCutscenePart5(this, globalCtx); } } - func_808C566C(this); + EnDeath_UpdateCoreVelocityAndRotation(this); } -void func_808C5F58(EnDeath* this, GlobalContext* globalCtx) { - Camera* sp24 = Play_GetCamera(globalCtx, this->unk_2FA); +void EnDeath_SetupIntroCutscenePart5(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); - Animation_PlayOnce(&this->skelAnime, &D_0600CB2C); + Animation_PlayOnce(&this->skelAnime, &object_death_Anim_00CB2C); this->unk_191 = 0x17; - func_801A2E54(0x38); - this->unk_344.x = Math_SinS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.x; - this->unk_344.z = Math_CosS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.z; - this->unk_344.y = this->actor.home.pos.y + 40.0f; - this->unk_350.y = this->actor.world.pos.y + 85.0f; - this->unk_30C = Math_Vec3f_DistXYZ(&sp24->eye, &this->unk_344) * 0.14285715f; - this->unk_310 = Math_Vec3f_DistXYZ(&sp24->at, &this->unk_350) * 0.14285715f; - Audio_PlaySfxAtPos(&this->unk_338, 0x3AB0); - this->unk_188 = func_808C6070; + func_801A2E54(NA_BGM_MINI_BOSS); + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 40.0f; + this->camAtTarget.y = this->actor.world.pos.y + 85.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * 0.14285715f; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * 0.14285715f; + Audio_PlaySfxAtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_VOICE); + this->actionFunc = EnDeath_IntroCutscenePart5; } -void func_808C6070(EnDeath* this, GlobalContext* globalCtx) { - Camera* sp44 = Play_GetCamera(globalCtx, this->unk_2FA); - f32 phi_f2; +void EnDeath_IntroCutscenePart5(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); + f32 scale; if (Animation_OnFrame(&this->skelAnime, 12.0f)) { - globalCtx->envCtx.lightSettingOverride = 0x1B; + globalCtx->envCtx.lightSettingOverride = 27; } else if (Animation_OnFrame(&this->skelAnime, 25.0f)) { - globalCtx->envCtx.lightSettingOverride = 0x1A; + globalCtx->envCtx.lightSettingOverride = 26; } else if (Animation_OnFrame(&this->skelAnime, 38.0f)) { s32 i; - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 9; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_9; } } else if (Animation_OnFrame(&this->skelAnime, 14.0f)) { s32 i; - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 8; - this->unk_6E4[i]->world.pos.x = - (this->unk_6E4[i]->world.pos.x - this->actor.world.pos.x) * 1.8f + this->actor.world.pos.x; - this->unk_6E4[i]->world.pos.z = - (this->unk_6E4[i]->world.pos.z - this->actor.world.pos.z) * 1.8f + this->actor.world.pos.z; - this->unk_6E4[i]->world.pos.y = - (this->unk_6E4[i]->world.pos.y - this->actor.world.pos.y) * 1.7f + this->actor.world.pos.y; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_8; + this->miniDeaths[i]->actor.world.pos.x = + (this->miniDeaths[i]->actor.world.pos.x - this->actor.world.pos.x) * 1.8f + this->actor.world.pos.x; + this->miniDeaths[i]->actor.world.pos.z = + (this->miniDeaths[i]->actor.world.pos.z - this->actor.world.pos.z) * 1.8f + this->actor.world.pos.z; + this->miniDeaths[i]->actor.world.pos.y = + (this->miniDeaths[i]->actor.world.pos.y - this->actor.world.pos.y) * 1.7f + this->actor.world.pos.y; } - this->unk_18E = 1; - this->unk_304 = 1.0f; + this->unk_18E = true; + this->scytheScale = 1.0f; } - Math_Vec3f_StepTo(&sp44->eye, &this->unk_344, this->unk_30C); - Math_Vec3f_StepTo(&sp44->at, &this->unk_350, this->unk_310); - Math_StepToF(&sp44->fov, 60.0f, 2.4285715f); - Play_CameraSetFov(globalCtx, this->unk_2FA, sp44->fov); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &sp44->at, &sp44->eye); + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Math_StepToF(&camera->fov, 60.0f, 2.4285715f); + Play_CameraSetFov(globalCtx, this->camId, camera->fov); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); - phi_f2 = CLAMP(this->skelAnime.curFrame, 10.0f, 14.0f) - 10.0f; - this->unk_304 = phi_f2 * 0.25f; - if (phi_f2 < 14.0f) { - func_808C566C(this); + scale = CLAMP(this->skelAnime.curFrame, 10.0f, 14.0f) - 10.0f; + this->scytheScale = scale * 0.25f; + if (scale < 14.0f) { + EnDeath_UpdateCoreVelocityAndRotation(this); } if (SkelAnime_Update(&this->skelAnime)) { ActorCutscene_Stop(this->actor.cutscene); func_800B724C(globalCtx, &this->actor, 6); - this->actor.flags |= 1; - this->unk_808.base.acFlags |= 1; - func_808C645C(this); + this->actor.flags |= ACTOR_FLAG_1; + this->coreCollider.base.acFlags |= AC_ON; + EnDeath_SetupApproachPlayer(this); } } -void func_808C645C(EnDeath* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06003CAC, 10.0f); +void EnDeath_SetupApproachPlayer(EnDeath* this) { + Animation_MorphToLoop(&this->skelAnime, &gGomessFloatAnim, 10.0f); this->actor.speedXZ = 1.5f; - if (this->unk_188 == func_808C682C || this->unk_188 == func_808C6AB0) { - this->unk_2EE = 0x8C; + if (this->actionFunc == EnDeath_EndSwingAttack || this->actionFunc == EnDeath_SpinAttack) { + this->actionTimer = 140; } else { - this->unk_2EE = 0x64; + this->actionTimer = 100; } - this->unk_188 = func_808C64DC; + this->actionFunc = EnDeath_ApproachPlayer; } -void func_808C64DC(EnDeath* this, GlobalContext* globalCtx) { - if (globalCtx->envCtx.lightSettingOverride == 0x14) { - globalCtx->envCtx.lightSettingOverride = 0x1A; +void EnDeath_ApproachPlayer(EnDeath* this, GlobalContext* globalCtx) { + if (globalCtx->envCtx.lightSettingOverride == 20) { + globalCtx->envCtx.lightSettingOverride = 26; } - func_808C5394(this); + EnDeath_Float(this); SkelAnime_Update(&this->skelAnime); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); - if (this->unk_2EE > 0) { - this->unk_2EE--; + if (this->actionTimer > 0) { + this->actionTimer--; } - if (this->actor.params < 5 && Rand_ZeroOne() < 0.4f && func_808C5428(this, globalCtx)) { - func_808C68B8(this); - return; - } - if (this->unk_2EE < 0x64 && this->actor.xzDistToPlayer < 200.0f) { - func_808C6620(this); - return; - } - if (this->unk_2EE == 0) { + if (this->actor.params < 5 && Rand_ZeroOne() < 0.4f && EnDeath_ProjectileApproaching(this, globalCtx)) { + EnDeath_SetupBlockProjectile(this); + } else if (this->actionTimer < 100 && this->actor.xzDistToPlayer < 200.0f) { + EnDeath_SetupSwingAttack(this); + } else if (this->actionTimer == 0) { if (this->actor.params >= 5) { func_808C7AEC(this); - return; + } else { + EnDeath_SetupSpinAttack(this); } - func_808C6A08(this); } } -void func_808C6620(EnDeath* this) { - Animation_Change(&this->skelAnime, &D_06000E64, 1.0f, 0.0f, 10.0f, 2, -3.0f); - this->unk_2EE = 0; - this->unk_2EA = 0; +void EnDeath_SetupSwingAttack(EnDeath* this) { + Animation_Change(&this->skelAnime, &gGomessScytheSwingAnim, 1.0f, 0.0f, 10.0f, ANIMMODE_ONCE, -3.0f); + this->actionTimer = 0; + this->floatTimer = 0; this->actor.speedXZ = 8.0f; Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_ATTACK); - this->unk_188 = func_808C66A8; + this->actionFunc = EnDeath_SwingAttack; } -void func_808C66A8(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_SwingAttack(EnDeath* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0x1000, 0x200); Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 3.0f); - this->actor.shape.rot.x = (s16)((100.0f - this->actor.xzDistToPlayer) * 0.01f * 1024.0f); + this->actor.shape.rot.x = (s16)((100.0f - this->actor.xzDistToPlayer) * 0.01f * 0x400); this->actor.shape.rot.x = CLAMP_MIN(this->actor.shape.rot.x, 0); - if (this->unk_2EE > 0) { - this->unk_2EE++; - if (this->unk_2EE == 3) { - func_808C67C8(this); - return; + if (this->actionTimer > 0) { + this->actionTimer++; + if (this->actionTimer == 3) { + EnDeath_SetupEndSwingAttack(this); } } else if (SkelAnime_Update(&this->skelAnime) && this->actor.xzDistToPlayer < 100.0f) { - Audio_PlaySfxAtPos(&this->unk_338, 0x3AAC); - this->unk_2EE++; + Audio_PlaySfxAtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE); + this->actionTimer++; this->actor.speedXZ = 0.0f; } } -void func_808C67C8(EnDeath* this) { - this->skelAnime.endFrame = Animation_GetLastFrame(&D_06000E64); - this->unk_2EE = 0; +void EnDeath_SetupEndSwingAttack(EnDeath* this) { + this->skelAnime.endFrame = Animation_GetLastFrame(&gGomessScytheSwingAnim); + this->actionTimer = 0; this->unk_2EC = -1; - this->unk_18C = 1; - this->unk_188 = func_808C682C; + this->unk_18C = true; + this->actionFunc = EnDeath_EndSwingAttack; this->actor.speedXZ = 0.0f; } -void func_808C682C(EnDeath* this, GlobalContext* globalCtx) { - this->unk_2EE++; +void EnDeath_EndSwingAttack(EnDeath* this, GlobalContext* globalCtx) { + this->actionTimer++; if (this->skelAnime.curFrame > 20.0f) { - this->unk_18C = 0; - this->unk_788.base.atFlags &= 0xFFFE; + this->unk_18C = false; + this->unk_788.base.atFlags &= ~AT_ON; Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x200); } if (SkelAnime_Update(&this->skelAnime)) { this->actor.shape.rot.x = 0; - func_808C645C(this); + EnDeath_SetupApproachPlayer(this); } } -void func_808C68B8(EnDeath* this) { - Animation_MorphToLoop(&this->skelAnime, &D_0600B508, -3.0f); - this->unk_2EC = 0x1F; - this->unk_2EE = 0x1E; +void EnDeath_SetupBlockProjectile(EnDeath* this) { + Animation_MorphToLoop(&this->skelAnime, &gGomessScytheSpinAnim, -3.0f); + this->unk_2EC = 31; + this->actionTimer = 30; this->actor.speedXZ = 0.0f; - func_808C54F0(this); - this->unk_18C = 1; - this->unk_190 = -3; - this->unk_188 = func_808C692C; + EnDeath_UpdateSpinAttackTris(this); + this->unk_18C = true; + this->numScytheAfterImages = -3; + this->actionFunc = EnDeath_BlockProjectile; } -void func_808C692C(EnDeath* this, GlobalContext* globalCtx) { - func_808C5394(this); +void EnDeath_BlockProjectile(EnDeath* this, GlobalContext* globalCtx) { + EnDeath_Float(this); - this->unk_2EE--; - if (this->unk_190 < 7) { - this->unk_190++; + this->actionTimer--; + if (this->numScytheAfterImages < 7) { + this->numScytheAfterImages++; } SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - Audio_PlaySfxAtPos(&this->unk_338, 0x3AAD); + Audio_PlaySfxAtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_ROLL); } Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); - func_808C54F0(this); - if (this->unk_2EE == 0) { + EnDeath_UpdateSpinAttackTris(this); + if (this->actionTimer == 0) { if (this->actor.xzDistToPlayer > 200.0f) { - func_808C6A08(this); - return; + EnDeath_SetupSpinAttack(this); + } else { + EnDeath_SetupApproachPlayer(this); } - func_808C645C(this); } } -void func_808C6A08(EnDeath* this) { - if (this->unk_188 != func_808C692C) { - Animation_MorphToLoop(&this->skelAnime, &D_0600B508, -3.0f); - this->unk_190 = -3; - this->unk_2EE = 0; +void EnDeath_SetupSpinAttack(EnDeath* this) { + if (this->actionFunc != EnDeath_BlockProjectile) { + Animation_MorphToLoop(&this->skelAnime, &gGomessScytheSpinAnim, -3.0f); + this->numScytheAfterImages = -3; + this->actionTimer = 0; this->unk_2EC = -1; - this->unk_18C = 1; + this->unk_18C = true; this->actor.speedXZ = 0.0f; } else { - this->unk_2EE = 0xA; + // Starting straight out of blocking a projectile, already spinning so start moving immediately + this->actionTimer = 10; this->unk_2EC = 9; this->actor.speedXZ = 10.0f; } - func_808C54F0(this); - this->unk_188 = func_808C6AB0; + EnDeath_UpdateSpinAttackTris(this); + this->actionFunc = EnDeath_SpinAttack; } -void func_808C6AB0(EnDeath* this, GlobalContext* globalCtx) { - func_808C5394(this); +void EnDeath_SpinAttack(EnDeath* this, GlobalContext* globalCtx) { + EnDeath_Float(this); + SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - Audio_PlaySfxAtPos(&this->unk_338, 0x3AAD); + Audio_PlaySfxAtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_ROLL); } - if (this->unk_190 < 7) { - this->unk_190++; + + if (this->numScytheAfterImages < 7) { + this->numScytheAfterImages++; } - this->unk_2EE++; - if (this->unk_2EE < 10) { + + this->actionTimer++; + if (this->actionTimer < 10) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); - } else if (this->unk_2EE == 10) { + } else if (this->actionTimer == 10) { this->actor.speedXZ = 10.0f; } - func_808C54F0(this); - Math_ScaledStepToS(&this->unk_2F2, (s32)(Math_SinS(this->unk_2EE * 0x2000) * 2048.0f) + 0x3000, 0x1000); - Math_ScaledStepToS(&this->unk_2F4, (s32)(Math_SinS(this->unk_2EE * 0x2000 - 0x8000) * 2048.0f), 0x1000); - if ((this->actor.bgCheckFlags & 8) || (this->unk_788.base.atFlags & 2) || (this->unk_860.base.atFlags & 2)) { - this->unk_18C = 0; - this->unk_788.base.atFlags &= 0xFFFC; - this->unk_860.base.atFlags &= 0xFFFD; - func_808C645C(this); + + EnDeath_UpdateSpinAttackTris(this); + + Math_ScaledStepToS(&this->unk_2F2, (s32)(Math_SinS(this->actionTimer * 0x2000) * 0x800) + 0x3000, 0x1000); + Math_ScaledStepToS(&this->unk_2F4, (s32)(Math_SinS(this->actionTimer * 0x2000 - 0x8000) * 0x800), 0x1000); + + if ((this->actor.bgCheckFlags & 8) || (this->unk_788.base.atFlags & AT_HIT) || + (this->unk_860.base.atFlags & AT_HIT)) { + this->unk_18C = false; + this->unk_788.base.atFlags &= ~(AT_ON | AT_HIT); + this->unk_860.base.atFlags &= ~AT_HIT; + EnDeath_SetupApproachPlayer(this); } } -void func_808C6C5C(EnDeath* this) { - Animation_PlayOnce(&this->skelAnime, &D_06001F80); +void EnDeath_SetupDamaged(EnDeath* this) { + Animation_PlayOnce(&this->skelAnime, &gGomessDamagedAnim); this->actor.speedXZ = 10.0f; - func_800BE568(&this->actor, &this->unk_808); - Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 0xF); - Actor_PlaySfxAtPos(&this->actor, 0x3AB1); - this->unk_188 = func_808C6CDC; + func_800BE568(&this->actor, &this->coreCollider); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 15); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_DAMAGE); + this->actionFunc = EnDeath_Damaged; } -void func_808C6CDC(EnDeath* this, GlobalContext* globalCtx) { - func_808C5394(this); +void EnDeath_Damaged(EnDeath* this, GlobalContext* globalCtx) { + EnDeath_Float(this); Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); if (SkelAnime_Update(&this->skelAnime)) { - this->unk_808.base.acFlags |= 1; - func_808C6A08(this); + this->coreCollider.base.acFlags |= AC_ON; + EnDeath_SetupSpinAttack(this); } } -void func_808C6D40(EnDeath* this, GlobalContext* globalCtx) { - Vec3f sp3C; - Vec3f sp30; +void EnDeath_SetupDeathCutscenePart1(EnDeath* this, GlobalContext* globalCtx) { + Vec3f eye; + Vec3f at; s32 i; - this->actor.flags &= ~0x1001; - Animation_PlayOnce(&this->skelAnime, &D_06002DE8); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_1000); + Animation_PlayOnce(&this->skelAnime, &gGomessBeginDeathAnim); - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 6; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_6; } - this->unk_18D = 0; - this->unk_808.base.acFlags &= 0xFFFE; - Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 0x1E); - this->unk_2EE = 0x23; + this->unk_18D = false; + this->coreCollider.base.acFlags &= ~AC_ON; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 30); + this->actionTimer = 35; this->actor.world.pos.y = this->actor.home.pos.y; this->actor.speedXZ = 0.0f; - this->unk_344.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.x; - this->unk_344.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.z; - this->unk_344.y = this->actor.home.pos.y + 63.0f; - sp30.x = this->actor.world.pos.x; - sp30.y = this->actor.world.pos.y + 100.0f; - sp30.z = this->actor.world.pos.z; - sp3C.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.x; - sp3C.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.z; - sp3C.y = this->actor.home.pos.y + 30.0f; - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &sp30, &sp3C); - this->unk_30C = Math_Vec3f_DistXYZ(&sp3C, &this->unk_344) * 0.05f; + this->camEyeTarget.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 63.0f; + at.x = this->actor.world.pos.x; + at.y = this->actor.world.pos.y + 100.0f; + at.z = this->actor.world.pos.z; + eye.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.x; + eye.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.z; + eye.y = this->actor.home.pos.y + 30.0f; + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); + this->camEyeSpeed = Math_Vec3f_DistXYZ(&eye, &this->camEyeTarget) * 0.05f; this->actor.shape.rot.y += 0x2000; func_800B724C(globalCtx, &this->actor, 7); - Actor_PlaySfxAtPos(&this->actor, 0x3AB2); - this->unk_188 = func_808C6F6C; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_DEAD); + this->actionFunc = EnDeath_DeathCutscenePart1; } -void func_808C6F6C(EnDeath* this, GlobalContext* globalCtx) { - Camera* camera = Play_GetCamera(globalCtx, this->unk_2FA); - f32 sp28 = Math_Vec3f_StepTo(&camera->eye, &this->unk_344, this->unk_30C); +void EnDeath_DeathCutscenePart1(EnDeath* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); + f32 distToTarget = Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &camera->at, &camera->eye); if (SkelAnime_Update(&this->skelAnime)) { this->actor.shape.rot.y += 0x2000; - Animation_PlayLoop(&this->skelAnime, &D_0600352C); - } else if (this->skelAnime.animation == &D_06002DE8) { + Animation_PlayLoop(&this->skelAnime, &gGomessDeathAnim); + } else if (this->skelAnime.animation == &gGomessBeginDeathAnim) { this->actor.shape.rot.y += 0x2000; if (this->skelAnime.curFrame > 3.0f) { Matrix_SetCurrentState(&this->unk_6A4); - Matrix_InsertXRotation_s(-0x1000, 1); + Matrix_InsertXRotation_s(-0x1000, MTXMODE_APPLY); Matrix_CopyCurrentState(&this->unk_6A4); - this->unk_18E = 0; + this->unk_18E = false; this->unk_6A4.wy += 18.0f; - Actor_PlaySfxAtPos(&this->actor, 0x3AAC); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_SCYTHE); } } - if (sp28 < 0.1f) { - if (this->unk_2EE == 35) { - func_801A479C(&this->unk_338, 0x3AAE, 0x41); // TODO sfx id + + if (distToTarget < 0.1f) { + if (this->actionTimer == 35) { + func_801A479C(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_LEV, 0x41); } - if (this->unk_2EE > 0) { - this->unk_2EE--; + if (this->actionTimer > 0) { + this->actionTimer--; } - if (this->unk_2EE == 0) { - func_808C70D8(this, globalCtx); + if (this->actionTimer == 0) { + EnDeath_SetupDeathCutscenePart2(this, globalCtx); } } } -void func_808C70D8(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_SetupDeathCutscenePart2(EnDeath* this, GlobalContext* globalCtx) { LightSettings* lightSettings1; LightSettings* lightSettings2; Player* player = GET_PLAYER(globalCtx); - Vec3f sp40; - Vec3f sp34; - f32 sp30; - f32 sp2C; + Vec3f eye; + Vec3f at; + f32 sinRotY; + f32 cosRotY; s32 i; - Animation_PlayLoop(&this->skelAnime, &D_0600352C); - this->unk_2EE = 0x1E; + Animation_PlayLoop(&this->skelAnime, &gGomessDeathAnim); + this->actionTimer = 30; player->actor.shape.rot.y = Actor_YawToPoint(&player->actor, &this->actor.home.pos) + 0x1000; this->actor.shape.rot.y = player->actor.shape.rot.y + 0x6000; - sp30 = Math_SinS(player->actor.shape.rot.y); - sp2C = Math_CosS(player->actor.shape.rot.y); - this->actor.world.pos.x = player->actor.world.pos.x + (260.0f * sp30); - this->actor.world.pos.z = player->actor.world.pos.z + (260.0f * sp2C); + sinRotY = Math_SinS(player->actor.shape.rot.y); + cosRotY = Math_CosS(player->actor.shape.rot.y); + this->actor.world.pos.x = player->actor.world.pos.x + (260.0f * sinRotY); + this->actor.world.pos.z = player->actor.world.pos.z + (260.0f * cosRotY); this->actor.world.pos.y = this->actor.home.pos.y + 15.0f; - sp40.x = (Math_SinS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.x; - sp40.z = (Math_CosS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.z; - sp40.y = this->actor.world.pos.y - 13.0f; - sp34.x = player->actor.world.pos.x + (120.0f * sp30); - sp34.y = player->actor.world.pos.y + 90.0f; - sp34.z = player->actor.world.pos.z + (120.0f * sp2C); - Play_CameraSetAtEye(globalCtx, this->unk_2FA, &sp34, &sp40); + eye.x = (Math_SinS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.x; + eye.z = (Math_CosS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.z; + eye.y = this->actor.world.pos.y - 13.0f; + at.x = player->actor.world.pos.x + (120.0f * sinRotY); + at.y = player->actor.world.pos.y + 90.0f; + at.z = player->actor.world.pos.z + (120.0f * cosRotY); + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); lightSettings1 = &globalCtx->envCtx.lightSettingsList[20]; lightSettings2 = &globalCtx->envCtx.lightSettingsList[21]; @@ -856,56 +902,119 @@ void func_808C70D8(EnDeath* this, GlobalContext* globalCtx) { lightSettings1->diffusePos2[i] = lightSettings2->diffusePos2[i]; } - this->unk_188 = func_808C72AC; + this->actionFunc = EnDeath_DeathCutscenePart2; } -void func_808C72AC(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_DeathCutscenePart2(EnDeath* this, GlobalContext* globalCtx) { f32 sin; f32 cos; - s16 temp_v1; + s16 camYaw; SkelAnime_Update(&this->skelAnime); - this->unk_2EE--; - if (this->unk_2EE >= 0 && this->unk_2EE < 3) { - temp_v1 = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000; - sin = Math_SinS(temp_v1); - cos = Math_CosS(temp_v1); + this->actionTimer--; + if (this->actionTimer >= 0 && this->actionTimer < 3) { + camYaw = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000; + sin = Math_SinS(camYaw); + cos = Math_CosS(camYaw); Matrix_InsertTranslation(this->actor.world.pos.x + (83.0f * sin) + (-38.0f * cos), - this->actor.world.pos.y + 53.0f + 15.0f * this->unk_2EE, - this->actor.world.pos.z + (83.0f * cos) - (-38.0f * sin), 0); - Matrix_RotateY(temp_v1 - 0x3300, 1); - Matrix_InsertXRotation_s(0x1100 - this->unk_2EE * 0x1800, 1); - Matrix_InsertZRotation_s(-0xA00, 1); - Matrix_Scale(0.01f, 0.01f, 0.01f, 1); + this->actor.world.pos.y + 53.0f + 15.0f * this->actionTimer, + this->actor.world.pos.z + (83.0f * cos) - (-38.0f * sin), MTXMODE_NEW); + Matrix_RotateY(camYaw - 0x3300, MTXMODE_APPLY); + Matrix_InsertXRotation_s(0x1100 - this->actionTimer * 0x1800, MTXMODE_APPLY); + Matrix_InsertZRotation_s(-0xA00, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); Matrix_CopyCurrentState(&this->unk_6A4); - if (this->unk_2EE == 0) { + if (this->actionTimer == 0) { func_800DFD04(GET_ACTIVE_CAM(globalCtx), 2, 4, 6); - func_8013ECE0(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); - func_801A7328(&this->unk_338, 0x3AAE); - Audio_PlaySfxAtPos(&this->unk_338, 0x3AAF); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 180, 20, 100); + func_801A7328(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_LEV); + Audio_PlaySfxAtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_ONGND); } } - if (this->unk_2EE < -0x19) { - globalCtx->envCtx.lightSettingOverride = 0x14; - func_808C74A4(this); + if (this->actionTimer < -25) { + globalCtx->envCtx.lightSettingOverride = 20; + EnDeath_SetupDeathCutscenePart3(this); } } -void func_808C74A4(EnDeath* this) { +void EnDeath_SetupDeathCutscenePart3(EnDeath* this) { s32 i; - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 5; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_DIE; } - this->unk_2EE = 0; - this->unk_188 = func_808C74F8; + this->actionTimer = 0; + this->actionFunc = EnDeath_DeathCutscenePart3; } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C74F8.s") +void EnDeath_DeathCutscenePart3(EnDeath* this, GlobalContext* globalCtx) { + static Vec3f sparkleVel = { 0.0f, -1.5f, 0.0f }; + static Vec3f sparkleAccel = { 0.0f, -0.2f, 0.0f }; + static Color_RGBA8 sparklePrimColor = { 0, 0, 0, 0 }; + static Color_RGBA8 sparkleEnvColor = { 40, 40, 40, 0 }; + static s16 D_808C9A90[GOMESS_LIMB_MAX] = { 30, 30, 10, 2, 12, 17, 17, 17, 17, 17, 17, + 17, 14, 10, 12, 9, 9, 12, 9, 9, 30, 30 }; + s32 phi_v0; + s32 phi_s0; + u8* temp1A9; + Vec3f* sparklePos; + s32 pad; + s32 pad1; + f32 sin; + f32 cos; + f32 temp_fs0; + s32 temp_v1; -void func_808C7800(EnDeath* this) { + sparklePos = this->unk_404; + temp1A9 = this->unk_1A9; + for (phi_v0 = 0; (phi_v0 ^ 0) < ARRAY_COUNT(this->unk_404); phi_v0++) { + sparklePos->y += 1.7f; + temp_v1 = *temp1A9 - 30; + *temp1A9 = CLAMP_MIN(temp_v1, 0); + sparklePos++; + temp1A9++; + } + + temp_v1 = (-this->actionTimer * 14) + 252; + this->actor.shape.shadowAlpha = CLAMP_MIN(temp_v1, 0); + + if (this->actionTimer < 18) { + sparklePos = &this->unk_404[(this->actionTimer * 7) % ARRAY_COUNT(this->unk_404)]; + temp1A9 = &this->unk_1A9[(this->actionTimer * 7) % ARRAY_COUNT(this->unk_1A9)]; + + sin = Math_SinS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000); + cos = Math_CosS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000); + + for (phi_s0 = 0; phi_s0 < 7; phi_s0++) { + temp_fs0 = randPlusMinusPoint5Scaled(100.0f) - 20.0f; + sparklePos->x = this->actor.world.pos.x + (30.0f * sin) + (temp_fs0 * cos); + sparklePos->y = (Rand_ZeroFloat(20.0f) + this->actor.world.pos.y + 4.0f * this->actionTimer) - 30.0f; + sparklePos->z = (this->actor.world.pos.z + 30.0f * cos) - (temp_fs0 * sin); + *temp1A9 = 255 - phi_s0 * 4; + EffectSsKiraKira_SpawnSmall(globalCtx, sparklePos, &sparkleVel, &sparkleAccel, &sparklePrimColor, + &sparkleEnvColor); + sparklePos++; + temp1A9++; + } + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + + this->actionTimer++; + + for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(this->unk_193); phi_v0++) { + if (this->actionTimer == D_808C9A90[phi_v0]) { + this->unk_193[phi_v0] = 1; + } + } + + if (this->actionTimer == 26) { + EnDeath_SetupDeathCutscenePart4(this); + } +} + +void EnDeath_SetupDeathCutscenePart4(EnDeath* this) { s32 i; for (i = 0; i < ARRAY_COUNT(this->unk_1A9); i++) { @@ -913,59 +1022,57 @@ void func_808C7800(EnDeath* this) { } Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.focus.pos); - this->actor.bgCheckFlags &= 0xFFFE; - this->unk_2EE = 0; - this->unk_188 = func_808C7888; + this->actor.bgCheckFlags &= ~1; + this->actionTimer = 0; + this->actionFunc = EnDeath_DeathCutscenePart4; this->actor.gravity = -1.0f; this->actor.shape.yOffset = 0.0f; } -#ifdef NON_MATCHING -// needs in-function static D_808C9ABC -void func_808C7888(EnDeath* this, GlobalContext* globalCtx) { - Vec3f sp74; +void EnDeath_DeathCutscenePart4(EnDeath* this, GlobalContext* globalCtx) { + static Vec3f sparkleAccel = { 0.0f, -1.0f, 0.0f }; + static Color_RGBA8 sparklePrimColor = { 0, 200, 100, 0 }; + static Color_RGBA8 sparkleEnvColor = { 0, 100, 0, 0 }; + Vec3f sparkleVel; s32 i; - if (this->unk_2EE == 0) { + if (this->actionTimer == 0) { if ((this->actor.bgCheckFlags & 1) || this->actor.floorHeight == -32000.0f) { Actor_SetScale(&this->actor, 0.0f); - this->unk_2EE++; + this->actionTimer++; for (i = 0; i < 40; i++) { - D_808C9ABC.y = -0.2f; - sp74.x = randPlusMinusPoint5Scaled(4.0f); - sp74.y = randPlusMinusPoint5Scaled(4.0f); - sp74.z = Rand_ZeroFloat(2.0f) + 3.0f; - EffectSsKiraKira_SpawnSmall(globalCtx, &this->actor.world.pos, &sp74, &D_808C9ABC, &D_808C9AC8, - &D_808C9ACC); + sparkleAccel.y = -0.2f; + sparkleVel.x = randPlusMinusPoint5Scaled(4.0f); + sparkleVel.z = randPlusMinusPoint5Scaled(4.0f); + sparkleVel.y = Rand_ZeroFloat(2.0f) + 3.0f; + EffectSsKiraKira_SpawnSmall(globalCtx, &this->actor.world.pos, &sparkleVel, &sparkleAccel, + &sparklePrimColor, &sparkleEnvColor); } - Actor_PlaySfxAtPos(&this->actor, 0x3AB5); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_HEARTBREAK); } } else { - this->unk_2EE++; - if (this->unk_2EE == 20) { - func_808C7A30(this, globalCtx); + this->actionTimer++; + if (this->actionTimer == 20) { + EnDeath_SetupDead(this, globalCtx); } } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7888.s") -#endif -void func_808C7A30(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_SetupDead(EnDeath* this, GlobalContext* globalCtx) { ActorCutscene_Stop(this->actor.cutscene); func_800B724C(globalCtx, &this->actor, 6); Flags_SetClearTemp(globalCtx, globalCtx->roomCtx.currRoom.num); - this->unk_2EE = 0xFF; - globalCtx->envCtx.lightSettingOverride = 0xFF; - this->unk_188 = func_808C7AAC; + this->actionTimer = 255; + globalCtx->envCtx.lightSettingOverride = 255; + this->actionFunc = EnDeath_Dead; } -void func_808C7AAC(EnDeath* this, GlobalContext* globalCtx) { - if (this->unk_2EE > 0) { - this->unk_2EE -= 5; - if (this->unk_2EE <= 0) { - this->unk_2EE = 0; +void EnDeath_Dead(EnDeath* this, GlobalContext* globalCtx) { + if (this->actionTimer > 0) { + this->actionTimer -= 5; + if (this->actionTimer <= 0) { + this->actionTimer = 0; Actor_MarkForDeath(&this->actor); } } @@ -974,23 +1081,24 @@ void func_808C7AAC(EnDeath* this, GlobalContext* globalCtx) { void func_808C7AEC(EnDeath* this) { s32 i; - Actor_PlaySfxAtPos(&this->actor, 0x3AB0); - Animation_MorphToPlayOnce(&this->skelAnime, &D_060015B4, 5.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEATH_VOICE); + Animation_MorphToPlayOnce(&this->skelAnime, &object_death_Anim_0015B4, 5.0f); this->actor.speedXZ = 0.0f; - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 3; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_3; } - this->unk_2EA = 0; - this->unk_188 = func_808C7B88; + this->floatTimer = 0; + this->actionFunc = func_808C7B88; } void func_808C7B88(EnDeath* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 5.0f); + if (SkelAnime_Update(&this->skelAnime)) { - globalCtx->envCtx.lightSettingOverride = 0x1B; + globalCtx->envCtx.lightSettingOverride = 27; func_808C7C04(this); } } @@ -998,127 +1106,134 @@ void func_808C7B88(EnDeath* this, GlobalContext* globalCtx) { void func_808C7C04(EnDeath* this) { s32 i; - Animation_PlayLoop(&this->skelAnime, &D_06001834); + Animation_PlayLoop(&this->skelAnime, &object_death_Anim_001834); - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 4; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_4; } - this->unk_188 = func_808C7C88; + this->actionFunc = func_808C7C88; this->actor.speedXZ = 0.0f; } void func_808C7C88(EnDeath* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); SkelAnime_Update(&this->skelAnime); + if (this->actor.params >= 5) { - globalCtx->envCtx.lightSettingOverride = 0x1A; - func_808C645C(this); + globalCtx->envCtx.lightSettingOverride = 26; + EnDeath_SetupApproachPlayer(this); } } -void func_808C7CFC(EnDeath* this) { +void EnDeath_SetupPlayCutscene(EnDeath* this) { ActorCutscene_SetIntentToPlay(this->actor.cutscene); - this->unk_188 = func_808C7D34; + this->actionFunc = EnDeath_PlayCutscene; } -void func_808C7D34(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_PlayCutscene(EnDeath* this, GlobalContext* globalCtx) { + // Wait for it's turn to play if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + // Start playing ActorCutscene_Start(this->actor.cutscene, &this->actor); - this->unk_2FA = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + this->camId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); if (this->actor.colChkInfo.health == 0) { - func_808C6D40(this, globalCtx); + // Death cutscene + EnDeath_SetupDeathCutscenePart1(this, globalCtx); } else { - func_808C571C(this, globalCtx); + // Intro cutscene + EnDeath_SetupIntroCutscenePart1(this, globalCtx); } } else { ActorCutscene_SetIntentToPlay(this->actor.cutscene); } } -void func_808C7DB8(EnDeath* this) { - this->unk_188 = func_808C7DCC; +void EnDeath_SetupBeginWithoutCutscene(EnDeath* this) { + this->actionFunc = EnDeath_BeginWithoutCutscene; } -void func_808C7DCC(EnDeath* this, GlobalContext* globalCtx) { - if (Play_InCsMode(globalCtx) == 0) { - func_808C5310(globalCtx); - this->unk_808.base.acFlags |= 1; - func_801A2E54(0x38); - func_808C645C(this); +void EnDeath_BeginWithoutCutscene(EnDeath* this, GlobalContext* globalCtx) { + if (!Play_InCsMode(globalCtx)) { + EnDeath_DimLights(globalCtx); + this->coreCollider.base.acFlags |= AC_ON; + func_801A2E54(NA_BGM_MINI_BOSS); + EnDeath_SetupApproachPlayer(this); } } -void func_808C7E24(EnDeath* this, GlobalContext* globalCtx) { - if (this->unk_18D != 0) { - this->unk_320.y += this->unk_308; - this->unk_308 -= 1.0f; - this->unk_2F6 += 0x1800; - if (this->unk_320.y < this->actor.floorHeight) { - this->unk_320.y = this->actor.floorHeight; - func_800B3030(globalCtx, &this->unk_320, &gZeroVec3f, &gZeroVec3f, 0x64, 0, 0); - SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->unk_320, 0xB, 0x3878); - this->unk_18D = 0; +void EnDeath_UpdateCore(EnDeath* this, GlobalContext* globalCtx) { + if (this->unk_18D) { + // Core falling to the ground + this->corePos.y += this->coreVelocity; + this->coreVelocity -= 1.0f; + this->coreRotation += 0x1800; + if (this->corePos.y < this->actor.floorHeight) { + // Hit the floor + this->corePos.y = this->actor.floorHeight; + func_800B3030(globalCtx, &this->corePos, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->corePos, 11, NA_SE_EN_EXTINCT); + this->unk_18D = false; } } } -void func_808C7EDC(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_UpdateDamage(EnDeath* this, GlobalContext* globalCtx) { s32 i; if (this->unk_2F8 > 0) { this->unk_2F8--; } - if (this->unk_808.base.acFlags & 2) { - this->unk_808.base.acFlags &= 0xFFFD; + if (this->coreCollider.base.acFlags & AC_HIT) { + this->coreCollider.base.acFlags &= ~AC_HIT; if (this->actor.params >= 5) { - this->unk_18D = 1; - this->unk_308 = -1.0f; - this->unk_2F6 = this->actor.shape.rot.y; - Math_Vec3s_ToVec3f(&this->unk_320, &this->unk_808.dim.worldSphere.center); - SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->unk_320, 0x1E, 0x3842); + this->unk_18D = true; + this->coreVelocity = -1.0f; + this->coreRotation = this->actor.shape.rot.y; + Math_Vec3s_ToVec3f(&this->corePos, &this->coreCollider.dim.worldSphere.center); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->corePos, 30, NA_SE_EN_FFLY_DEAD); - if (this->actor.colChkInfo.damageEffect == 4 && this->unk_188 != func_808C7B88) { - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 1; + if (this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW && this->actionFunc != func_808C7B88) { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_1; } - globalCtx->envCtx.lightSettingOverride = 0x1C; + globalCtx->envCtx.lightSettingOverride = 28; - this->unk_2FC = 0x14; - if (this->unk_188 == func_808C64DC) { - this->unk_2EE = 0x64; + this->unk_2FC = 20; + if (this->actionFunc == EnDeath_ApproachPlayer) { + this->actionTimer = 100; } - } else if (this->actor.colChkInfo.damageEffect == 0xF) { + } else if (this->actor.colChkInfo.damageEffect == DMGEFF_EXPLOSIVES) { this->unk_2F8 = 0xA; } - } else if (this->actor.colChkInfo.damageEffect != 0xF || this->unk_2F8 == 0) { - this->unk_18C = 0; - this->unk_788.base.atFlags &= 0xFFFE; - this->unk_808.base.acFlags &= 0xFFFE; + } else if (this->actor.colChkInfo.damageEffect != DMGEFF_EXPLOSIVES || this->unk_2F8 == 0) { + this->unk_18C = false; + this->unk_788.base.atFlags &= ~AT_ON; + this->coreCollider.base.acFlags &= ~AC_ON; - if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_31C = 3.0f; - this->unk_314 = 0.8f; - this->unk_18F = 0x14; - Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->unk_808.info.bumper.hitPos.x, - this->unk_808.info.bumper.hitPos.y, this->unk_808.info.bumper.hitPos.z, 0, 0, 0, 4); + if (this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW) { + this->dmgEffectAlpha = 3.0f; + this->dmgEffectScale = 0.8f; + this->dmgEffect = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->coreCollider.info.bumper.hitPos.x, this->coreCollider.info.bumper.hitPos.y, + this->coreCollider.info.bumper.hitPos.z, 0, 0, 0, 4); } - if (globalCtx->envCtx.lightSettingOverride == 0x1B) { - globalCtx->envCtx.lightSettingOverride = 0x1A; + if (globalCtx->envCtx.lightSettingOverride == 27) { + globalCtx->envCtx.lightSettingOverride = 26; } this->actor.shape.rot.x = 0; if (Actor_ApplyDamage(&this->actor) == 0) { Enemy_StartFinishingBlow(globalCtx, &this->actor); - func_801A2ED8(); - func_808C7CFC(this); + func_801A2ED8(); // Stop miniboss BGM + EnDeath_SetupPlayCutscene(this); } else { - for (i = 0; i < ARRAY_COUNT(this->unk_6E4); i++) { - this->unk_6E4[i]->params = 2; + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_2; } - - func_808C6C5C(this); + EnDeath_SetupDamaged(this); } } } @@ -1126,150 +1241,142 @@ void func_808C7EDC(EnDeath* this, GlobalContext* globalCtx) { void EnDeath_Update(Actor* thisx, GlobalContext* globalCtx) { EnDeath* this = THIS; - UnkActor* unkActor; + ArrowLight* lightArrow; s32 pad; if (this->unk_2FC > 0) { this->unk_2FC--; - unkActor = (UnkActor*)SubS_FindActor(globalCtx, NULL, 7, 0x7F); - if (unkActor != NULL) { - unkActor->unk_15C = -100.0f; + + lightArrow = (ArrowLight*)SubS_FindActor(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_ARROW_LIGHT); + if (lightArrow != NULL) { + lightArrow->screenFillIntensity = -100.0f; } + if (this->unk_2FC == 0) { - globalCtx->envCtx.lightSettingOverride = 0x1A; + globalCtx->envCtx.lightSettingOverride = 26; } } - func_808C7EDC(this, globalCtx); - func_808C7E24(this, globalCtx); - if (this->unk_188 != func_808C6AB0) { + + EnDeath_UpdateDamage(this, globalCtx); + EnDeath_UpdateCore(this, globalCtx); + if (this->actionFunc != EnDeath_SpinAttack) { Math_ScaledStepToS(&this->unk_2F2, 0, 0x800); Math_ScaledStepToS(&this->unk_2F4, 0, 0x800); } - this->unk_188(this, globalCtx); - if (this->unk_188 != func_808C6CDC) { + this->actionFunc(this, globalCtx); + + if (this->actionFunc != EnDeath_Damaged) { this->actor.world.rot.y = this->actor.shape.rot.y; } Actor_MoveWithGravity(&this->actor); - Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, (this->unk_188 == func_808C6AB0) ? 50.0f : 100.0f, 40.0f, - 7); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, (this->actionFunc == EnDeath_SpinAttack) ? 50.0f : 100.0f, + 40.0f, 4 | 2 | 1); - this->unk_73C.dim.pos.x = this->actor.world.pos.x + Math_SinS(this->actor.shape.rot.y) * 3.0f; - this->unk_73C.dim.pos.z = this->actor.world.pos.z + Math_CosS(this->actor.shape.rot.y) * 3.0f; - this->unk_73C.dim.pos.y = this->actor.world.pos.y; + this->bodyCollider.dim.pos.x = this->actor.world.pos.x + Math_SinS(this->actor.shape.rot.y) * 3.0f; + this->bodyCollider.dim.pos.z = this->actor.world.pos.z + Math_CosS(this->actor.shape.rot.y) * 3.0f; + this->bodyCollider.dim.pos.y = this->actor.world.pos.y; if (this->actor.params < 5) { - this->unk_808.dim.worldSphere.radius = this->unk_808.dim.modelSphere.radius + 5; + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius + 5; } else { - this->unk_808.dim.worldSphere.radius = this->unk_808.dim.modelSphere.radius; + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius; } - if (this->unk_188 != func_808C7AAC) { - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->unk_73C.base); + if (this->actionFunc != EnDeath_Dead) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); } - if (this->unk_808.base.acFlags & 1) { - CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_808.base); + if (this->coreCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->coreCollider.base); } - if (this->unk_788.base.atFlags & 1) { + if (this->unk_788.base.atFlags & AT_ON) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->unk_788.base); } - if (this->unk_188 == func_808C692C || this->unk_188 == func_808C6AB0) { + if (this->actionFunc == EnDeath_BlockProjectile || this->actionFunc == EnDeath_SpinAttack) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->unk_860.base); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_860.base); } - if (this->unk_31C > 0.0f) { - if (this->unk_18F != 0xA) { - Math_StepToF(&this->unk_31C, 0.0f, 0.05f); - this->unk_314 = (this->unk_31C + 1.0f) * 0.4f; + if (this->dmgEffectAlpha > 0.0f) { + if (this->dmgEffect != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->dmgEffectAlpha, 0.0f, 0.05f); + this->dmgEffectScale = (this->dmgEffectAlpha + 1.0f) * 0.4f; - this->unk_314 = CLAMP_MAX(this->unk_314, 0.8f); - - return; - } - if (Math_StepToF(&this->unk_318, 0.8f, 0.02f) == 0) { - func_800B9010(&this->actor, 0x20B2); + this->dmgEffectScale = CLAMP_MAX(this->dmgEffectScale, 0.8f); + } else if (Math_StepToF(&this->dmgEffectSteamScale, 0.8f, 0.02f) == 0) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } } -#ifdef NON_MATCHING -// single reodering, stack -void func_808C84A4(EnDeath* this, GlobalContext* globalCtx) { - Gfx* phi_s0; - s32 phi_s2; - s32 phi_s3; - s32 phi_s4; +void EnDeath_DrawScytheSpinning(EnDeath* this, GlobalContext* globalCtx) { + s32 i; + Gfx* dl; + s32 pad; func_800B8118(&this->actor, globalCtx, 0); Scene_SetRenderModeXlu(globalCtx, 1, 2); OPEN_DISPS(globalCtx->state.gfxCtx); + dl = POLY_XLU_DISP; - phi_s0 = POLY_XLU_DISP; - - for (phi_s2 = 1, phi_s3 = 0xDC, phi_s4 = 0x2100; phi_s2 < this->unk_190; - phi_s2++, phi_s3 -= 0x23, phi_s4 += 0x2100) { - gDPPipeSync(phi_s0++); - gDPSetEnvColor(phi_s0++, 30, 30, 0, phi_s3); + for (i = 1; i < this->numScytheAfterImages; i++) { + gDPPipeSync(dl++); + gDPSetEnvColor(dl++, 30, 30, 0, 255 - i * 35); Matrix_SetCurrentState(&this->unk_6A4); - Matrix_InsertXRotation_s(phi_s4, 1); + Matrix_InsertXRotation_s(i * 0x2100, MTXMODE_APPLY); - gSPMatrix(phi_s0++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(phi_s0++, D_06006F88); + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_death_DL_006F88); // scythe handle - Matrix_InsertTranslation(0.0f, -1084.0f, 7012.0f, 1); - Matrix_InsertRotation(-0x4000, 0, -0x4000, 1); + Matrix_InsertTranslation(0.0f, -1084.0f, 7012.0f, MTXMODE_APPLY); + Matrix_InsertRotation(-0x4000, 0, -0x4000, MTXMODE_APPLY); - gSPMatrix(phi_s0++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(phi_s0++, D_060073D0); + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_death_DL_0073D0); // scythe blade } - POLY_XLU_DISP = phi_s0; + POLY_XLU_DISP = dl; CLOSE_DISPS(globalCtx->state.gfxCtx); } -#else -void func_808C84A4(EnDeath* this, GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C84A4.s") -#endif -void func_808C8690(EnDeath* this, GlobalContext* globalCtx) { +void EnDeath_DrawScythe(EnDeath* this, GlobalContext* globalCtx) { Gfx* dl; s32 pad; - if (this->unk_188 == func_808C7AAC) { + if (this->actionFunc == EnDeath_Dead) { func_800B8118(&this->actor, globalCtx, 0); Scene_SetRenderModeXlu(globalCtx, 1, 2); } OPEN_DISPS(globalCtx->state.gfxCtx); - if (this->unk_188 == func_808C7AAC) { + if (this->actionFunc == EnDeath_Dead) { dl = POLY_XLU_DISP; gDPPipeSync(dl++); - gDPSetEnvColor(dl++, 30, 30, 0, this->unk_2EE); + gDPSetEnvColor(dl++, 30, 30, 0, this->actionTimer); } else { dl = POLY_OPA_DISP; } Matrix_SetCurrentState(&this->unk_6A4); - Matrix_Scale(this->unk_304, this->unk_304, this->unk_304, 1); + Matrix_Scale(this->scytheScale, this->scytheScale, this->scytheScale, MTXMODE_APPLY); gSPMatrix(&dl[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&dl[1], D_06006F88); + gSPDisplayList(&dl[1], object_death_DL_006F88); // scythe handle - Matrix_InsertTranslation(0.0f, -1084.0f, 7012.0f, 1); - Matrix_InsertRotation(-0x4000, 0, -0x4000, 1); + Matrix_InsertTranslation(0.0f, -1084.0f, 7012.0f, MTXMODE_APPLY); + Matrix_InsertRotation(-0x4000, 0, -0x4000, MTXMODE_APPLY); gSPMatrix(&dl[2], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&dl[3], D_060073D0); + gSPDisplayList(&dl[3], object_death_DL_0073D0); // scythe blade - Matrix_GetStateTranslation(&this->unk_32C); + Matrix_GetStateTranslation(&this->scytheWorldPos); - if (this->unk_188 == func_808C7AAC) { + if (this->actionFunc == EnDeath_Dead) { POLY_XLU_DISP = &dl[4]; } else { POLY_OPA_DISP = &dl[4]; @@ -1278,143 +1385,338 @@ void func_808C8690(EnDeath* this, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_808C882C(EnDeath* this, GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C882C.s") - -void func_808C8D18(EnDeath* this, GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C8D18.s") - -void func_808C9160(EnDeath* this, GlobalContext* globalCtx) { - s32 pad; +void EnDeath_DrawBats(EnDeath* this, GlobalContext* globalCtx) { + // Each bat is animated by cycling through these display lists + static Gfx* sMinideathDLs[MINIDEATH_ANIM_LENGTH] = { + gGomessBatFrame1DL, gGomessBatFrame2DL, gGomessBatFrame3DL, gGomessBatFrame4DL, gGomessBatFrame5DL, + gGomessBatFrame6DL, gGomessBatFrame7DL, gGomessBatFrame8DL, gGomessBatFrame9DL, + }; + EnMinideath* miniDeath; + MtxF* cmf; + f32 phi_fs2; + MiniDeathStruct* phi_s0; + s32 j; + f32 scale; Gfx* dl; + s32 i; + Vec3f sp9C; + + OPEN_DISPS(globalCtx->state.gfxCtx); + dl = POLY_OPA_DISP; + + gSPDisplayList(dl++, &sSetupDL[0x19 * 6]); + gSPDisplayList(dl++, gGomessBatMaterialDL); + + cmf = Matrix_GetCurrentState(); + + if (this->actionFunc == EnDeath_Dead) { + phi_fs2 = this->actionTimer * 0.000035f; + scale = 0.007f; + if (phi_fs2 > 0.007f) { + phi_fs2 = 0.007f; + scale = 0.007f; + } + } else { + phi_fs2 = 0.007f; + scale = 0.007f; + } + + if (this->actor.flags & ACTOR_FLAG_1000) { + Math_Vec3f_Copy(&sp9C, &globalCtx->mainCamera.skyboxOffset); + } else { + Math_Vec3f_Copy(&sp9C, &gZeroVec3f); + } + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + if (this->actionFunc == EnDeath_BeginWithoutCutscene || + (this->miniDeaths[i]->actor.flags & ACTOR_FLAG_40) == ACTOR_FLAG_40) { + miniDeath = this->miniDeaths[i]; + + Matrix_InsertRotation(miniDeath->actor.shape.rot.x, miniDeath->actor.shape.rot.y, 0, MTXMODE_NEW); + Matrix_Scale(phi_fs2, phi_fs2, phi_fs2, MTXMODE_APPLY); + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + if (phi_s0->unk_1 == 0) { + cmf->mf[3][0] = phi_s0->unk_4.x + sp9C.x; + cmf->mf[3][1] = phi_s0->unk_4.y + sp9C.y; + cmf->mf[3][2] = phi_s0->unk_4.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + if (phi_s0->unk_1 == 1) { + Matrix_InsertRotation(0x4000, phi_s0->unk_1E, 0, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + cmf->mf[3][0] = phi_s0->unk_4.x + sp9C.x; + cmf->mf[3][1] = phi_s0->unk_4.y + sp9C.y; + cmf->mf[3][2] = phi_s0->unk_4.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + } + } + + if (this->unk_192) { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + miniDeath = this->miniDeaths[i]; + + Matrix_InsertRotation(miniDeath->actor.shape.rot.x, miniDeath->actor.shape.rot.y, 0, MTXMODE_NEW); + Matrix_Scale(phi_fs2, phi_fs2, phi_fs2, MTXMODE_APPLY); + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + cmf->mf[3][0] = miniDeath->actor.world.pos.x - phi_s0->unk_10.x; + cmf->mf[3][1] = miniDeath->actor.world.pos.y + (20.0f - phi_s0->unk_10.y); + cmf->mf[3][2] = miniDeath->actor.world.pos.z - phi_s0->unk_10.z; + + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + } + + if (this->unk_18D) { + Matrix_InsertRotation(0x4000, this->coreRotation, 0, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + cmf->mf[3][0] = this->corePos.x + sp9C.x; + cmf->mf[3][1] = this->corePos.y + sp9C.y; + cmf->mf[3][2] = this->corePos.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[0]); + } + + POLY_OPA_DISP = dl; + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnDeath_DrawFlames(EnDeath* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 phi_t1; + MtxF* cmf; + s32 phi_s7; + u8* phi_s3; + Vec3f* phi_s1; + MiniDeathStruct* phi_s1_2; + u8 alpha; + s32 phi_s3_2; + + phi_s7 = this->actionTimer * 7; + if (phi_s7 > ARRAY_COUNT(this->unk_1A9)) { + phi_s7 = ARRAY_COUNT(this->unk_1A9); + } OPEN_DISPS(globalCtx->state.gfxCtx); - dl = POLY_OPA_DISP; - Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + gDPSetEnvColor(POLY_XLU_DISP++, 230, 135, 25, 0); - gSPMatrix(&dl[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&dl[1], D_06009988); + Matrix_SetCurrentState(&globalCtx->billboardMtxF); + Matrix_Scale(0.00405f, 0.003f, 0.00405f, MTXMODE_APPLY); - if (this->actor.params >= 5) { - gSPDisplayList(&dl[2], D_06009BA0); - POLY_OPA_DISP = dl + 3; + cmf = Matrix_GetCurrentState(); + + phi_s1 = this->unk_404; + phi_s3 = this->unk_1A9; + for (phi_t1 = 0; phi_t1 < phi_s7; phi_t1++) { + if (*phi_s3 > 0) { + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 165, 255, 215, *phi_s3); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((globalCtx->gameplayFrames + (phi_t1 * 10)) * -20) & 0x1FF, 32, 128)); + + cmf->mf[3][0] = phi_s1->x; + cmf->mf[3][1] = phi_s1->y; + cmf->mf[3][2] = phi_s1->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + phi_s1++; + phi_s3++; + } + + Matrix_SetCurrentState(&globalCtx->billboardMtxF); + Matrix_Scale(0.00405f, 0.003f, 0.00405f, MTXMODE_APPLY); + + if (this->actionFunc == EnDeath_Dead) { + alpha = this->actionTimer; } else { - POLY_OPA_DISP = dl + 2; + alpha = 255; + } + + for (phi_t1 = 0; phi_t1 < ARRAY_COUNT(this->miniDeaths); phi_t1++) { + if ((this->miniDeaths[phi_t1]->actor.flags & ACTOR_FLAG_40) == ACTOR_FLAG_40) { + phi_s1_2 = this->miniDeaths[phi_t1]->unk_160; + + for (phi_s3_2 = 0; phi_s3_2 < ARRAY_COUNT(this->miniDeaths[phi_t1]->unk_160); phi_s3_2++, phi_s1_2++) { + cmf->mf[3][0] = phi_s1_2->unk_4.x; + cmf->mf[3][1] = phi_s1_2->unk_4.y - 12.0f; + cmf->mf[3][2] = phi_s1_2->unk_4.z; + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 165, 255, 215, alpha); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((globalCtx->gameplayFrames + ((phi_s3_2 + phi_t1) * 10)) * -20) & 511, 32, + 128)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + } } CLOSE_DISPS(globalCtx->state.gfxCtx); } -s32 func_808C9220(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +void EnDeath_DrawCore(EnDeath* this, GlobalContext* globalCtx) { + s32 pad; + Gfx* dl; + + OPEN_DISPS(globalCtx->state.gfxCtx); + dl = POLY_OPA_DISP; + + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(&dl[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[1], gGomessCoreDL); + + if (this->actor.params >= 5) { + // bats in front of the core + gSPDisplayList(&dl[2], gGomessBatsGuardingCoreDL); + POLY_OPA_DISP = &dl[3]; + } else { + POLY_OPA_DISP = &dl[2]; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 EnDeath_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnDeath* this = THIS; f32 temp_f12; s32 temp_v0; if (this->unk_193[limbIndex] == 1) { *dList = NULL; - } else if (limbIndex == 0xD && this->unk_188 == func_808C74F8) { - temp_v0 = this->unk_2EE - 5; + } else if (limbIndex == GOMESS_LIMB_CLOAK_LOWER && this->actionFunc == EnDeath_DeathCutscenePart3) { + temp_v0 = this->actionTimer - 5; if (temp_v0 > 0) { temp_f12 = 1.0f - (temp_v0 * 0.1f); - Matrix_Scale(temp_f12, temp_f12, temp_f12, 1); + Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY); } } - if (limbIndex == 0x14 || limbIndex == 0x15) { - if (this->unk_18E == 0) { + if (limbIndex == GOMESS_LIMB_SCYTHE_HANDLE || limbIndex == GOMESS_LIMB_SCYTHE_BLADE) { + if (!this->unk_18E) { *dList = NULL; } - } else if (limbIndex == 0xC) { + } else if (limbIndex == GOMESS_LIMB_CLOAK_UPPER) { rot->z = rot->z + this->unk_2F2; - } else if (limbIndex == 0xD) { + } else if (limbIndex == GOMESS_LIMB_CLOAK_LOWER) { rot->z = rot->z + this->unk_2F4; } return 0; } -#ifdef NON_MATCHING -// A lot towards the bottom, original wants to mult but mine optimizes to shifts -void func_808C9340(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDeath_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_808C9AF4 = { -1000.0f, 12000.0f, 0.0f }; + static Vec3f D_808C9B00 = { -2000.0f, -2500.0f, 0.0f }; + static Vec3f D_808C9B0C[5] = { + { 1000.0f, 2000.0f, 0.0f }, { 1500.0f, 1000.0f, 4000.0f }, { 1500.0f, 1000.0f, -4000.0f }, + { 4000.0f, 4000.0f, 2000.0f }, { 4000.0f, 4000.0f, -2000.0f }, + }; + static s8 D_808C9B48[GOMESS_LIMB_MAX] = { -1, -1, -1, 12, -1, 0, -1, -1, -1, -1, -1, + -1, -1, 7, 1, 2, 3, 4, 5, 6, -1, -1 }; EnDeath* this = THIS; - Vec3f sp6C; - Vec3f sp60; - Vec3f sp54; - Vec3f sp48; - s32 sp44; - f32 temp_f0; - s32 temp_s0; - s32 temp_v0_2; - s8 temp_v1; - s32 phi_v0; - Vec3f* phi_s1; - Vec3f* phi_s0; + s8 index; - if (limbIndex == 0x15) { - Matrix_GetStateTranslation(&this->unk_32C); - if ((this->unk_788.base.atFlags & 1) && this->unk_2EC != this->unk_2EE) { - Math_Vec3f_Copy(&sp6C, &this->unk_788.dim.quad[0]); - Math_Vec3f_Copy(&sp60, &this->unk_788.dim.quad[1]); - if (this->unk_188 == func_808C682C) { - Matrix_GetStateTranslationAndScaledX(6000.0f, &sp54); - Matrix_MultiplyVector3fByState(&D_808C9AF4, &sp48); + if (limbIndex == GOMESS_LIMB_SCYTHE_BLADE) { + Matrix_GetStateTranslation(&this->scytheWorldPos); + + if ((this->unk_788.base.atFlags & AT_ON) && this->unk_2EC != this->actionTimer) { + Vec3f quad0; + Vec3f quad1; + Vec3f pos1; + Vec3f pos2; + + Math_Vec3f_Copy(&quad0, &this->unk_788.dim.quad[0]); + Math_Vec3f_Copy(&quad1, &this->unk_788.dim.quad[1]); + + if (this->actionFunc == EnDeath_EndSwingAttack) { + Matrix_GetStateTranslationAndScaledX(6000.0f, &pos1); + Matrix_MultiplyVector3fByState(&D_808C9AF4, &pos2); } else { - Matrix_GetStateTranslationAndScaledY(5000.0f, &sp48); - Matrix_MultiplyVector3fByState(&D_808C9B00, &sp54); + Matrix_GetStateTranslationAndScaledY(5000.0f, &pos2); + Matrix_MultiplyVector3fByState(&D_808C9B00, &pos1); } - Collider_SetQuadVertices(&this->unk_788, &sp48, &sp54, &sp6C, &sp60); - EffectBlure_AddVertex(Effect_GetByIndex(this->unk_300), &sp54, &sp48); - this->unk_2EC = this->unk_2EE; - } else if (this->unk_18C != 0) { - if (this->unk_188 == func_808C682C) { + + Collider_SetQuadVertices(&this->unk_788, &pos2, &pos1, &quad0, &quad1); + EffectBlure_AddVertex(Effect_GetByIndex(this->effectIndex), &pos1, &pos2); + + this->unk_2EC = this->actionTimer; + } else if (this->unk_18C) { + if (this->actionFunc == EnDeath_EndSwingAttack) { Matrix_GetStateTranslationAndScaledX(6000.0f, &this->unk_788.dim.quad[1]); Matrix_MultiplyVector3fByState(&D_808C9AF4, &this->unk_788.dim.quad[0]); } else { Matrix_GetStateTranslationAndScaledY(5000.0f, &this->unk_788.dim.quad[0]); Matrix_MultiplyVector3fByState(&D_808C9B00, &this->unk_788.dim.quad[1]); } - this->unk_18C = 0; - this->unk_788.base.atFlags |= 1; - this->unk_2EC = this->unk_2EE; + this->unk_18C = false; + this->unk_788.base.atFlags |= AT_ON; + this->unk_2EC = this->actionTimer; } - } else if (limbIndex == 2 && this->unk_188 != func_808C7AAC) { + } else if (limbIndex == GOMESS_LIMB_CORE_POS && this->actionFunc != EnDeath_Dead) { Matrix_StatePush(); - func_808C9160(this, globalCtx); + EnDeath_DrawCore(this, globalCtx); Matrix_StatePop(); Matrix_GetStateTranslation(&this->actor.focus.pos); - this->unk_808.dim.worldSphere.center.x = this->actor.focus.pos.x; - this->unk_808.dim.worldSphere.center.y = this->actor.focus.pos.y; - this->unk_808.dim.worldSphere.center.z = this->actor.focus.pos.z; + + this->coreCollider.dim.worldSphere.center.x = this->actor.focus.pos.x; + this->coreCollider.dim.worldSphere.center.y = this->actor.focus.pos.y; + this->coreCollider.dim.worldSphere.center.z = this->actor.focus.pos.z; + if (this->actor.params < 5) { - this->unk_808.dim.worldSphere.center.y = this->actor.focus.pos.y + 5.0f; + this->coreCollider.dim.worldSphere.center.y = this->actor.focus.pos.y + 5.0f; } - } else if (limbIndex == 0x14) { - if (!(this->unk_188 != func_808C6AB0 && this->unk_188 != func_808C692C && this->unk_188 != func_808C6070) || - (this->unk_188 == func_808C6F6C && this->unk_18E == 1)) { + } else if (limbIndex == GOMESS_LIMB_SCYTHE_HANDLE) { + if (!(this->actionFunc != EnDeath_SpinAttack && this->actionFunc != EnDeath_BlockProjectile && + this->actionFunc != EnDeath_IntroCutscenePart5) || + (this->actionFunc == EnDeath_DeathCutscenePart1 && this->unk_18E == true)) { Matrix_CopyCurrentState(&this->unk_6A4); } } - temp_v1 = D_808C9B48[limbIndex]; - if (temp_v1 != -1) { - if (temp_v1 < 7) { - Matrix_GetStateTranslation(&this->unk_35C[temp_v1]); - return; - } - if (temp_v1 == 7) { - for (phi_v0 = 0; phi_v0 != 5; phi_v0++) { - Matrix_MultiplyVector3fByState(&D_808C9B0C[phi_v0], &this->unk_35C[phi_v0 + temp_v1]); + + index = D_808C9B48[limbIndex]; + if (index != -1) { + if (index < 7) { + // get matrix translation as-is, occupies slots 0, 1, 2, 3, 4, 5, 6 + Matrix_GetStateTranslation(&this->dmgEffectPositions[index]); + } else if (index == 7) { + // 5 points using 5 offsets, occupies slots 7, 8, 9, 10, 11 + s32 i; + Vec3f* offset; + Vec3f* effPos; + + for (effPos = &this->dmgEffectPositions[index], offset = &D_808C9B0C[0], i = 0; + i != ARRAY_COUNT(D_808C9B0C); i++, offset++, effPos++) { + Matrix_MultiplyVector3fByState(offset, effPos); } - return; - } - if (temp_v1 == 0xC) { - Matrix_GetStateTranslation(&this->unk_35C[temp_v1]); - Matrix_GetStateTranslationAndScaledY(-2000.0f, &this->unk_35C[temp_v1 + 1]); + } else if (index == 12) { + // get matrix translation as-is and a point offset by -2000 from it, occupies slots 12, 13 + Matrix_GetStateTranslation(&this->dmgEffectPositions[index]); + Matrix_GetStateTranslationAndScaledY(-2000.0f, &this->dmgEffectPositions[index + 1]); } } } -#else -void func_808C9340(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C9340.s") -#endif void EnDeath_Draw(Actor* thisx, GlobalContext* globalCtx) { EnDeath* this = THIS; @@ -1424,35 +1726,36 @@ void EnDeath_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_800B8050(&this->actor, globalCtx, 0); - AnimatedMat_DrawStepOpa(globalCtx, this->unk_734, this->unk_191); - AnimatedMat_DrawOpa(globalCtx, this->unk_738); + AnimatedMat_DrawStepOpa(globalCtx, this->bodyMatAnim, this->unk_191); + AnimatedMat_DrawOpa(globalCtx, this->coreMatAnim); Scene_SetRenderModeXlu(globalCtx, 0, 1); gDPSetEnvColor(POLY_OPA_DISP++, 30, 30, 0, 255); - if (this->unk_188 != func_808C7AAC && this->unk_188 != func_808C7888) { - SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_808C9220, func_808C9340, &this->actor); + if (this->actionFunc != EnDeath_Dead && this->actionFunc != EnDeath_DeathCutscenePart4) { + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDeath_OverrideLimbDraw, EnDeath_PostLimbDraw, &this->actor); } - if (this->unk_188 == func_808C7888) { - func_808C9160(this, globalCtx); + if (this->actionFunc == EnDeath_DeathCutscenePart4) { + EnDeath_DrawCore(this, globalCtx); } - if (this->unk_18E == 0) { - func_808C8690(this, globalCtx); + if (!this->unk_18E) { + EnDeath_DrawScythe(this, globalCtx); } if (this->actor.colorFilterTimer != 0) { func_800AE5A0(globalCtx); } - Actor_DrawDamageEffects(globalCtx, &this->actor, this->unk_35C, 0xE, this->unk_314, this->unk_318, this->unk_31C, this->unk_18F); - if (this->unk_188 == func_808C6AB0 || this->unk_188 == func_808C692C) { - func_808C84A4(this, globalCtx); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->dmgEffectPositions, ARRAY_COUNT(this->dmgEffectPositions), + this->dmgEffectScale, this->dmgEffectSteamScale, this->dmgEffectAlpha, this->dmgEffect); + if (this->actionFunc == EnDeath_SpinAttack || this->actionFunc == EnDeath_BlockProjectile) { + EnDeath_DrawScytheSpinning(this, globalCtx); } - func_808C882C(this, globalCtx); - if (this->unk_188 == func_808C7AAC || this->unk_188 == func_808C7888 || - (this->unk_188 == func_808C74F8 && this->unk_2EE > 0)) { - func_808C8D18(this, globalCtx); + EnDeath_DrawBats(this, globalCtx); + if (this->actionFunc == EnDeath_Dead || this->actionFunc == EnDeath_DeathCutscenePart4 || + (this->actionFunc == EnDeath_DeathCutscenePart3 && this->actionTimer > 0)) { + EnDeath_DrawFlames(this, globalCtx); } - SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &this->unk_32C, &this->unk_338); + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &this->scytheWorldPos, &this->scytheScreenPos); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Death/z_en_death.h b/src/overlays/actors/ovl_En_Death/z_en_death.h index e75ae777a..c074b5917 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.h +++ b/src/overlays/actors/ovl_En_Death/z_en_death.h @@ -2,6 +2,8 @@ #define Z_EN_DEATH_H #include "global.h" +#include "overlays/actors/ovl_En_Minideath/z_en_minideath.h" +#include "objects/object_death/object_death.h" struct EnDeath; @@ -10,52 +12,50 @@ typedef void (*EnDeathActionFunc)(struct EnDeath*, GlobalContext*); typedef struct EnDeath { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; - /* 0x188 */ EnDeathActionFunc unk_188; + /* 0x188 */ EnDeathActionFunc actionFunc; /* 0x18C */ u8 unk_18C; /* 0x18D */ u8 unk_18D; /* 0x18E */ u8 unk_18E; - /* 0x18F */ u8 unk_18F; - /* 0x190 */ s8 unk_190; - /* 0x191 */ u8 unk_191; + /* 0x18F */ u8 dmgEffect; + /* 0x190 */ s8 numScytheAfterImages; + /* 0x191 */ u8 unk_191; // animated material color step? /* 0x192 */ u8 unk_192; - /* 0x193 */ char unk_193[0x16]; + /* 0x193 */ u8 unk_193[GOMESS_LIMB_MAX]; /* 0x1A9 */ u8 unk_1A9[56]; - /* 0x1E1 */ char unk_1E1[1]; // likely padding - /* 0x1E2 */ Vec3s unk_1E2[22]; - /* 0x266 */ Vec3s unk_266[22]; - /* 0x2EA */ s16 unk_2EA; + /* 0x1E2 */ Vec3s jointTable[GOMESS_LIMB_MAX]; + /* 0x266 */ Vec3s morphTable[GOMESS_LIMB_MAX]; + /* 0x2EA */ s16 floatTimer; /* 0x2EC */ s16 unk_2EC; - /* 0x2EE */ s16 unk_2EE; + /* 0x2EE */ s16 actionTimer; /* 0x2F0 */ char unk_2F0[0x2]; /* 0x2F2 */ s16 unk_2F2; /* 0x2F4 */ s16 unk_2F4; - /* 0x2F6 */ s16 unk_2F6; + /* 0x2F6 */ s16 coreRotation; /* 0x2F8 */ s16 unk_2F8; - /* 0x2FA */ s16 unk_2FA; + /* 0x2FA */ s16 camId; /* 0x2FC */ s16 unk_2FC; - /* 0x2FE */ char unk_2FE[0x2]; - /* 0x300 */ s32 unk_300; // effectIdx - /* 0x304 */ f32 unk_304; - /* 0x308 */ f32 unk_308; - /* 0x30C */ f32 unk_30C; - /* 0x310 */ f32 unk_310; - /* 0x314 */ f32 unk_314; - /* 0x318 */ f32 unk_318; - /* 0x31C */ f32 unk_31C; - /* 0x320 */ Vec3f unk_320; - /* 0x32C */ Vec3f unk_32C; - /* 0x338 */ Vec3f unk_338; - /* 0x344 */ Vec3f unk_344; - /* 0x350 */ Vec3f unk_350; - /* 0x35C */ Vec3f unk_35C[2]; // TODO size - /* 0x374 */ char unk_374[0x330]; + /* 0x300 */ s32 effectIndex; + /* 0x304 */ f32 scytheScale; + /* 0x308 */ f32 coreVelocity; + /* 0x30C */ f32 camEyeSpeed; + /* 0x310 */ f32 camAtSpeed; + /* 0x314 */ f32 dmgEffectScale; + /* 0x318 */ f32 dmgEffectSteamScale; + /* 0x31C */ f32 dmgEffectAlpha; + /* 0x320 */ Vec3f corePos; + /* 0x32C */ Vec3f scytheWorldPos; + /* 0x338 */ Vec3f scytheScreenPos; + /* 0x344 */ Vec3f camEyeTarget; + /* 0x350 */ Vec3f camAtTarget; + /* 0x35C */ Vec3f dmgEffectPositions[14]; + /* 0x404 */ Vec3f unk_404[56]; /* 0x6A4 */ MtxF unk_6A4; - /* 0x6E4 */ Actor* unk_6E4[20]; - /* 0x734 */ AnimatedMaterial* unk_734; - /* 0x738 */ AnimatedMaterial* unk_738; - /* 0x73C */ ColliderCylinder unk_73C; - /* 0x788 */ ColliderQuad unk_788; - /* 0x808 */ ColliderSphere unk_808; + /* 0x6E4 */ EnMinideath* miniDeaths[20]; + /* 0x734 */ AnimatedMaterial* bodyMatAnim; + /* 0x738 */ AnimatedMaterial* coreMatAnim; + /* 0x73C */ ColliderCylinder bodyCollider; + /* 0x788 */ ColliderQuad unk_788; // weapon? + /* 0x808 */ ColliderSphere coreCollider; /* 0x860 */ ColliderTris unk_860; /* 0x880 */ ColliderTrisElement unk_880[2]; } EnDeath; // size = 0x938 diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c index d5e15c04d..4723c9f61 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c @@ -5,6 +5,8 @@ */ #include "z_en_minideath.h" +#include "overlays/actors/ovl_En_Death/z_en_death.h" +#include "objects/object_death/object_death.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) @@ -25,10 +27,18 @@ void func_808CB094(EnMinideath* this, GlobalContext* globalCtx); void func_808CB22C(EnMinideath* this, GlobalContext* globalCtx); void func_808CB454(EnMinideath* this, GlobalContext* globalCtx); void func_808CB59C(EnMinideath* this, GlobalContext* globalCtx); -void func_808CB6D4(EnMinideath* this, GlobalContext* globalCtx); -void func_808CB7CC(EnMinideath* this, GlobalContext* globalCtx); +void EnMinideath_Die(EnMinideath* this, GlobalContext* globalCtx); +void EnMinideath_Dead(EnMinideath* this, GlobalContext* globalCtx); + +void func_808CA34C(EnMinideath* this); +void func_808CA7D4(EnMinideath* this); +void func_808CA8E0(EnMinideath* this); +void func_808CAAC8(EnMinideath* this); +void func_808CAB90(EnMinideath* this); +void func_808CAE00(EnMinideath* this); +void func_808CAF08(EnMinideath* this); +void EnMinideath_SetupDead(EnMinideath* this); -#if 0 const ActorInit En_Minideath_InitVars = { ACTOR_EN_MINIDEATH, ACTORCAT_ENEMY, @@ -44,59 +54,97 @@ const ActorInit En_Minideath_InitVars = { // static ColliderJntSphElementInit sJntSphElementsInit[3] = { static ColliderJntSphElementInit D_808CBF50[3] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_808CBFBC = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 3, D_808CBF50, // sJntSphElementsInit, + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_808CBF50), + D_808CBF50, // sJntSphElementsInit, }; +typedef enum { + DMGEFF_NONE = 0, + DMGEFF_STUN = 1, + DMGEFF_FIRE_ARROW = 2, + DMGEFF_ICE_ARROW = 3, + DMGEFF_LIGHT_ARROW = 4, + DMGEFF_ZORA_BARRIER = 5 +} EnMinideathDamageEffect; + // static DamageTable sDamageTable = { static DamageTable D_808CBFCC = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(1, 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(1, 0x0), - /* Goron punch */ DMG_ENTRY(1, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(1, 0x0), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(1, 0x5), - /* 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), + /* Deku Nut */ DMG_ENTRY(0, DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(0, DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(1, DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(1, DMGEFF_ZORA_BARRIER), + /* Normal shield */ DMG_ENTRY(0, DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DMGEFF_NONE), }; // sColChkInfoInit @@ -108,80 +156,754 @@ static InitChainEntry D_808CBFF4[] = { ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), }; -#endif +static s32 sItemDropTimer; +s32 D_808CC254; +s32 D_808CC258; +s32 D_808CC25C; -extern ColliderJntSphElementInit D_808CBF50[3]; -extern ColliderJntSphInit D_808CBFBC; -extern DamageTable D_808CBFCC; -extern CollisionCheckInfoInit D_808CBFEC; -extern InitChainEntry D_808CBFF4[]; +void EnMinideath_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMinideath* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Init.s") + Actor_ProcessInitChain(thisx, D_808CBFF4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Destroy.s") + this->unk_158 = thisx->world.pos.y - thisx->parent->world.pos.y; + this->spawnShapeRot = thisx->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA268.s") + thisx->shape.rot.y = thisx->parent->shape.rot.y; + thisx->world.rot.y = thisx->parent->shape.rot.y; + thisx->flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA308.s") + Collider_InitAndSetJntSph(globalCtx, &this->collider, thisx, &D_808CBFBC, this->colliderElements); + CollisionCheck_SetInfo(&thisx->colChkInfo, &D_808CBFCC, &D_808CBFEC); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA34C.s") + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA458.s") + func_808CA34C(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA7D4.s") + this->number = thisx->params; + thisx->params = 0; + this->unk_149 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA860.s") + if (gSaveContext.eventInf[6] & 8) { + this->collider.base.atFlags |= AT_ON; + this->unk_149 = true; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA8E0.s") + func_808CABB0(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA8F4.s") + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + Math_Vec3f_Sum(&thisx->world.pos, &this->unk_160[i].unk_10, &this->unk_160[i].unk_4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAAC8.s") + func_808CAB90(this); + } else { + func_808CA7D4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAAEC.s") +void EnMinideath_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMinideath* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAB90.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CABB0.s") +void EnMinideath_DropCollectible(Vec3f* spawnPos, GlobalContext* globalCtx) { + if (sItemDropTimer == 0 && Rand_ZeroOne() < 0.3f) { + if (Rand_ZeroOne() < 0.5f) { + Item_DropCollectible(globalCtx, spawnPos, ITEM00_ARROWS_10); + } else { + Item_DropCollectible(globalCtx, spawnPos, ITEM00_MAGIC_LARGE); + } + sItemDropTimer = 800; // wait 40 seconds before next drop + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAC54.s") +void func_808CA308(EnMinideath* this, s32 arg1) { + if (this->unk_149 != arg1) { + this->unk_149 = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CACD8.s") + if (arg1 == true) { + this->actor.parent->params++; + } else { + this->actor.parent->params--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAE00.s") +void func_808CA34C(EnMinideath* this) { + MiniDeathStruct* phi_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAE18.s") + for (phi_s0 = this->unk_160, i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + phi_s0->unk_10.x = randPlusMinusPoint5Scaled(80.0f); + phi_s0->unk_10.y = Rand_ZeroFloat(40.0f); + phi_s0->unk_10.z = randPlusMinusPoint5Scaled(80.0f); + phi_s0->animFrame = (s32)Rand_ZeroFloat(9.0f) % MINIDEATH_ANIM_LENGTH; + phi_s0->unk_1C = (Rand_Next() >> 17); + phi_s0->unk_1E = (Rand_Next() >> 16); + phi_s0->unk_1 = 0; + phi_s0->unk_22 = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAF08.s") +void func_808CA458(EnMinideath* this, GlobalContext* globalCtx) { + s16 temp_s1; + MiniDeathStruct* phi_s0; + f32 phi_fv0; + f32 phi_fa0; + s32 i; + s32 phi_s7; + s32 phi_s3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAF68.s") + phi_s3 = 0; + phi_s7 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB07C.s") + phi_s0 = this->unk_160; + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + if (phi_s0->unk_1 == 0) { + phi_s0->unk_10.x += 3.0f * Math_CosS(phi_s0->unk_1C) * Math_SinS(phi_s0->unk_1E); + phi_s0->unk_10.y += 3.0f * Math_SinS(phi_s0->unk_1C); + phi_s0->unk_10.z += 3.0f * Math_CosS(phi_s0->unk_1C) * Math_CosS(phi_s0->unk_1E); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB094.s") + if (this->actionFunc == func_808CA860) { + phi_fv0 = 100.0f; + phi_fa0 = SQ(phi_fv0); + } else if (this->actionFunc == func_808CB094 || this->actionFunc == func_808CB454) { + phi_fv0 = 20.0f; + phi_fa0 = SQ(20.0f); + } else { + phi_fv0 = 40.0f; + phi_fa0 = SQ(40.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB0C8.s") + if (phi_s0->unk_10.y < 0.0f || phi_fv0 < phi_s0->unk_10.y || + phi_fa0 < SQ(phi_s0->unk_10.x) + SQ(phi_s0->unk_10.z)) { + temp_s1 = Math_FAtan2F(sqrtf(SQ(phi_s0->unk_10.x) + SQ(phi_s0->unk_10.z)), phi_s0->unk_10.y); + phi_s0->unk_1C = -1 * temp_s1 + (Rand_Next() >> 19); + temp_s1 = Math_FAtan2F(phi_s0->unk_10.z, phi_s0->unk_10.x); + phi_s0->unk_1E = temp_s1 + (Rand_Next() >> 19) + 0x8000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB22C.s") + phi_s3++; + } else if (phi_s0->unk_1 == 1) { + phi_s0->unk_4.y += phi_s0->unk_10.y; + phi_s0->unk_1E += 0x1800; + phi_s0->unk_10.y -= 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB418.s") + if (phi_s0->unk_4.y < this->actor.parent->home.pos.y) { + phi_s0->unk_4.y = this->actor.parent->home.pos.y; + func_800B3030(globalCtx, &phi_s0->unk_4, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &phi_s0->unk_4, 11, NA_SE_EN_EXTINCT); + EnMinideath_DropCollectible(&phi_s0->unk_4, globalCtx); + phi_s0->unk_1 = 2; + } + } else if (phi_s0->unk_1 == 2) { + if (phi_s0->unk_22 > 0) { + phi_s0->unk_22--; + } else if (this->actionFunc == func_808CABB0) { + Math_Vec3f_Diff(&this->actor.parent->focus.pos, &this->actor.world.pos, &phi_s0->unk_10); + phi_s0->unk_1 = 0; + this->collider.elements[i].info.bumperFlags |= BUMP_ON; + this->collider.elements[i].info.toucherFlags |= TOUCH_ON; + phi_s7 = 1; + phi_s3++; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB454.s") + if (phi_s7 && phi_s3 > 1) { + func_808CA308(this, true); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB524.s") +void func_808CA7D4(EnMinideath* this) { + this->actor.speedXZ = 6.0f; + this->actor.world.pos.x = randPlusMinusPoint5Scaled(600.0f) + this->actor.parent->world.pos.x; + this->actor.world.pos.z = randPlusMinusPoint5Scaled(600.0f) + this->actor.parent->world.pos.z; + this->actor.shape.rot.y = Rand_Next() >> 16; + this->actor.shape.rot.x = 0; + this->unk_150.y = this->actor.shape.rot.y; + this->actionFunc = func_808CA860; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB59C.s") +void func_808CA860(EnMinideath* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = (Rand_Next() >> 18) + this->actor.wallYaw; + } + if (this->actor.params == MINIDEATH_ACTION_7) { + func_808CA8E0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB6A8.s") +void func_808CA8E0(EnMinideath* this) { + this->actionFunc = func_808CA8F4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB6D4.s") +void func_808CA8F4(EnMinideath* this, GlobalContext* globalCtx) { + EnDeath* parent; + Vec3f sp38; + s32 phi_v0; + s16 angle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB7B8.s") + Math_StepToF(&this->actor.speedXZ, 15.0f, 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB7CC.s") + if (this->actor.child == NULL) { + phi_v0 = 0; + angle = 0; + } else { + angle = 0x5555; + if (this->number == 6) { + phi_v0 = 1; + } else if (this->number == 12) { + phi_v0 = 2; + angle = -0x5556; + } else { + phi_v0 = -1; + Math_Vec3f_Copy(&sp38, &this->actor.child->world.pos); + angle = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB810.s") + if (phi_v0 != -1) { + parent = (EnDeath*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB8F4.s") + angle += parent->coreRotation; + sp38.x = this->actor.parent->world.pos.x + Math_SinS(angle) * parent->coreVelocity; + sp38.z = this->actor.parent->world.pos.z + Math_CosS(angle) * parent->coreVelocity; + sp38.y = this->actor.parent->world.pos.y + phi_v0 * 20; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &sp38), 2, 0x1000, 0x100); + if (this->actor.parent->scale.z > 0.0f) { + sp38.y = this->actor.parent->world.pos.y + this->unk_158; + } + Math_SmoothStepToS(&this->actor.shape.rot.x, Actor_PitchToPoint(&this->actor, &sp38), 2, 0x1000, 0x100); + if (this->actor.params == MINIDEATH_ACTION_8) { + func_808CAAC8(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Update.s") +void func_808CAAC8(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CAAEC; + this->actor.speedXZ = 5.0f; +} + +void func_808CAAEC(EnMinideath* this, GlobalContext* globalCtx) { + Actor_DistanceToPoint(&this->actor, &this->actor.parent->focus.pos); + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.parent->focus.pos), 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, Actor_PitchToPoint(&this->actor, &this->actor.parent->focus.pos), + 0x800); + if (this->actor.params == MINIDEATH_ACTION_9) { + this->collider.base.atFlags |= AT_ON; + func_808CAF08(this); + } +} + +void func_808CAB90(EnMinideath* this) { + this->actor.shape.rot.x = 0; + this->actionFunc = func_808CABB0; + this->actor.speedXZ = 0.0f; +} + +void func_808CABB0(EnMinideath* this, GlobalContext* globalCtx) { + s16 sp1E = this->spawnShapeRot + this->actor.parent->shape.rot.y; + + this->actor.world.pos.x = this->actor.parent->world.pos.x + Math_SinS(sp1E) * 60.0f; + this->actor.world.pos.z = this->actor.parent->world.pos.z + Math_CosS(sp1E) * 60.0f; + this->actor.world.pos.y = this->actor.parent->world.pos.y + this->unk_158; + this->actor.shape.rot.y = this->actor.parent->shape.rot.y; +} + +void func_808CAC54(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actor.speedXZ = 8.0f; + func_800BE33C(&this->actor.parent->world.pos, &this->actor.world.pos, &this->unk_150, false); + if (D_808CC258 != 0) { + this->timer = D_808CC258; + } else { + this->timer = 200; + } + func_808CA308(this, false); + this->actionFunc = func_808CACD8; +} + +void func_808CACD8(EnMinideath* this, GlobalContext* globalCtx) { + f32 temp_fv0; + f32 temp_fv1; + + Math_StepToF(&this->actor.speedXZ, 6.0f, 0.5f); + + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = (Rand_Next() >> 18) + this->actor.wallYaw; + } + + if (Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480)) { + temp_fv0 = this->actor.world.pos.y; + temp_fv1 = this->actor.parent->home.pos.y; + + if (temp_fv0 < temp_fv1 + 50.0f) { + this->unk_150.x = -0x800 - ((u32)Rand_Next() >> 20); + } else if (temp_fv0 > temp_fv1 + 200.0f) { + this->unk_150.x = ((u32)Rand_Next() >> 20) + 0x800; + } + } + + if (this->timer == 0) { + func_808CAE00(this); + } else { + this->timer--; + } +} + +void func_808CAE00(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CAE18; +} + +void func_808CAE18(EnMinideath* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_fv0 = Actor_DistanceToPoint(&this->actor, &this->actor.parent->focus.pos); + f32 phi_fa0 = temp_fv0 * 0.016666668f; + + if (phi_fa0 > 1.0f) { + phi_fa0 = 1.0f; + } + Math_StepToF(&this->actor.speedXZ, 6.0f * phi_fa0, 0.5f); + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.parent->focus.pos), 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, Actor_PitchToPoint(&this->actor, &this->actor.parent->focus.pos), + 0x800); + if (temp_fv0 < 30.0f) { + func_808CAF08(this); + } +} + +void func_808CAF08(EnMinideath* this) { + s32 phi_v0; + + this->actor.speedXZ = 0.0f; + func_808CA308(this, true); + + for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(this->unk_160); phi_v0++) { + this->unk_160[phi_v0].unk_22 = 0; + } + this->actionFunc = func_808CAF68; +} + +void func_808CAF68(EnMinideath* this, GlobalContext* globalCtx) { + Vec3f target; + f32 dist; + s16 sp26; + s32 done; + + done = Math_ScaledStepToS(&this->actor.shape.rot.y, this->spawnShapeRot + this->actor.parent->shape.rot.y, 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x800); + sp26 = this->spawnShapeRot + this->actor.parent->shape.rot.y; + target.x = this->actor.parent->world.pos.x + Math_SinS(sp26) * 60.0f; + target.z = this->actor.parent->world.pos.z + Math_CosS(sp26) * 60.0f; + target.y = this->actor.parent->world.pos.y + this->unk_158; + + dist = Math_Vec3f_StepTo(&this->actor.world.pos, &target, 10.0f); + if (done && dist < 20.0f) { + func_808CAB90(this); + } +} + +void func_808CB07C(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CB094; +} + +void func_808CB094(EnMinideath* this, GlobalContext* globalCtx) { + Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.parent->focus.pos, 5.0f); +} + +void func_808CB0C8(EnMinideath* this, GlobalContext* globalCtx) { + s32 phi_a2; + s32 phi_v1; + s32 phi_a1; + + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actor.speedXZ = 8.0f; + + if (this->number >= 10) { + phi_v1 = 19 - this->number; + phi_a1 = 1; + phi_a2 = 0; + } else { + phi_v1 = 9 - this->number; + phi_a1 = -1; + phi_a2 = 0x200; + } + this->actor.shape.rot.y = this->actor.parent->shape.rot.y + (phi_a1 * 0x4000) + ((phi_v1 * 0x2000) * phi_a1); + this->actor.shape.rot.x = (phi_a2 - phi_v1 * 0x400) + 0xC00; + + this->actor.world.pos.x = this->actor.parent->focus.pos.x + Math_SinS(this->actor.shape.rot.y) * 60.0f; + this->actor.world.pos.z = this->actor.parent->focus.pos.z + Math_CosS(this->actor.shape.rot.y) * 60.0f; + this->actor.world.pos.y = this->actor.parent->focus.pos.y - Math_SinS(this->actor.shape.rot.x) * 60.0f; + + func_808CA34C(this); + this->timer = 100; + func_808CA308(this, false); + + D_808CC254 = 0; + + if (this->actor.child == NULL || this->number == 9) { + this->unk_15C = &GET_PLAYER(globalCtx)->actor; + } else { + this->unk_15C = this->actor.child; + } + this->actionFunc = func_808CB22C; +} + +void func_808CB22C(EnMinideath* this, GlobalContext* globalCtx) { + Vec3f sp34; + s16 sp32 = 0; + + Math_StepToF(&this->actor.speedXZ, 6.0f, 0.2f); + if (this->timer > 0) { + this->timer--; + } + + if (this->unk_15C->id != ACTOR_EN_MINIDEATH) { + if (this->timer == 0) { + this->unk_15C = this->actor.parent; + } + Math_Vec3f_Copy(&sp34, &this->unk_15C->focus.pos); + if (Actor_DistanceToPoint(&this->actor, &sp34) > 200.0f) { + if (this->number < 10) { + sp32 = -0x1C00; + } else { + sp32 = 0x1C00; + } + sp34.y += 50.0f; + } + } else if (((EnMinideath*)this->unk_15C)->actionFunc != func_808CB22C) { + Math_Vec3f_Copy(&sp34, &this->actor.parent->focus.pos); + } else { + Math_Vec3f_Copy(&sp34, &this->unk_15C->focus.pos); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &sp34) + sp32, 5, 0xC00, 0x80); + Math_SmoothStepToS(&this->actor.shape.rot.x, Actor_PitchToPoint(&this->actor, &sp34), 5, 0xC00, 0x80); + if ((this->collider.base.atFlags & AT_HIT) && this->timer > 0) { + D_808CC254 += 1; + } + if (this->timer == 0 && Actor_DistanceToPoint(&this->actor, &this->actor.parent->focus.pos) < 50.0f) { + func_808CAF08(this); + } +} + +void func_808CB418(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->timer = 10; + func_808CA34C(this); + this->actionFunc = func_808CB454; +} + +void func_808CB454(EnMinideath* this, GlobalContext* globalCtx) { + Vec3f target; + + if (this->timer > 0) { + this->timer--; + } + target.x = (Math_SinS(this->actor.parent->shape.rot.y) * 20.0f) + this->actor.parent->focus.pos.x; + target.z = (Math_CosS(this->actor.parent->shape.rot.y) * 20.0f) + this->actor.parent->focus.pos.z; + target.y = this->actor.parent->focus.pos.y; + Math_Vec3f_StepTo(&this->actor.world.pos, &target, 5.0f); + if (this->timer == 0 && ((EnMinideath*)this->actor.child)->actionFunc != func_808CB22C) { + func_808CAB90(this); + } +} + +void func_808CB524(EnMinideath* this) { + s32 i; + + this->actor.params = MINIDEATH_ACTION_CONTINUE; + func_808CA308(this, false); + this->collider.base.atFlags &= ~AT_ON; + + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + this->unk_160[i].unk_1 = 0; + } + + this->unk_150.y = this->actor.shape.rot.y; + this->unk_150.x = this->actor.shape.rot.x; + this->actionFunc = func_808CB59C; +} + +void func_808CB59C(EnMinideath* this, GlobalContext* globalCtx) { + f32 temp_fv0; + f32 temp_fv1; + + Math_StepToF(&this->actor.speedXZ, 5.0f, 0.2f); + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = (Rand_Next() >> 0x12) + this->actor.wallYaw; + } + if (Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480)) { + temp_fv0 = this->actor.world.pos.y; + temp_fv1 = this->actor.parent->home.pos.y; + if (temp_fv0 < (temp_fv1 + 50.0f)) { + this->unk_150.x = -0x800 - ((u32)Rand_Next() >> 20); + } else if (temp_fv0 > (temp_fv1 + 200.0f)) { + this->unk_150.x = ((u32)Rand_Next() >> 20) + 0x800; + } + } +} + +void EnMinideath_SetupDie(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->unk_150.x = 0x4000; + this->actionFunc = EnMinideath_Die; + this->actor.gravity = -0.5f; +} + +void EnMinideath_Die(EnMinideath* this, GlobalContext* globalCtx) { + MiniDeathStruct* phi_s0; + s32 i; + s32 phi_s2 = 0; + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); + Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480); + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + + for (phi_s0 = this->unk_160, i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + if (Math_StepToF(&phi_s0->unk_10.y, 0.0f, 7.0f)) { + phi_s2++; + } + } + + if (phi_s2 == ARRAY_COUNT(this->unk_160)) { + EnMinideath_SetupDead(this); + } + } +} + +void EnMinideath_SetupDead(EnMinideath* this) { + this->actionFunc = EnMinideath_Dead; +} + +void EnMinideath_Dead(EnMinideath* this, GlobalContext* globalCtx) { + if (this->actor.parent->update == NULL) { + Actor_MarkForDeath(&this->actor); + } else { + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } +} + +void EnMinideath_SetNextAction(EnMinideath* this, GlobalContext* globalCtx) { + s16 action = this->actor.params; + + if (action == MINIDEATH_ACTION_6) { + func_808CB524(this); + } else if (action == MINIDEATH_ACTION_2) { + func_808CAE00(this); + } else if (action == MINIDEATH_ACTION_3) { + func_808CB07C(this); + } else if (action == MINIDEATH_ACTION_4) { + if (this->number == 0 || this->number == 10) { + func_808CB418(this); + } else { + func_808CB0C8(this, globalCtx); + } + } else if (action == MINIDEATH_ACTION_1) { + func_808CAC54(this); + } else if (action == MINIDEATH_ACTION_DIE) { + EnMinideath_SetupDie(this); + } +} + +void func_808CB8F4(EnMinideath* this, GlobalContext* globalCtx) { + s32 temp_a0_2; + EnMinideath* temp_a0_3; + s32 phi_a2; + s32 phi_v0_2; + s32 phi_a0; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actor.colChkInfo.damageEffect == DMGEFF_STUN) { + if (this->actionFunc == func_808CABB0 || this->actionFunc == func_808CAF68) { + D_808CC258 = 5; + } else if (this->actionFunc == func_808CB22C) { + EnMinideath** miniDeaths = (EnMinideath**)((EnDeath*)this->actor.parent)->miniDeaths; + + for (temp_a0_2 = this->number - 1; temp_a0_2 >= 0; temp_a0_2--) { + temp_a0_3 = miniDeaths[temp_a0_2]; + + if (temp_a0_3->unk_15C == &this->actor) { + temp_a0_3->unk_15C = this->unk_15C; + break; + } + } + + this->timer = 0; + this->unk_15C = &GET_PLAYER(globalCtx)->actor; + } + } else { + for (phi_a2 = 0; phi_a2 < ARRAY_COUNT(this->colliderElements); phi_a2++) { + if (this->collider.elements[phi_a2].info.bumperFlags & BUMP_HIT) { + this->collider.elements[phi_a2].info.bumperFlags &= ~(BUMP_ON | BUMP_HIT); + this->collider.elements[phi_a2].info.toucherFlags &= ~(TOUCH_ON | TOUCH_HIT); + this->unk_160[phi_a2].unk_10.y = -1.0f; + this->unk_160[phi_a2].unk_1 = 1; + this->unk_160[phi_a2].unk_1E = this->actor.shape.rot.y; + this->unk_160[phi_a2].unk_22 = 60; + + if ((this->actionFunc == func_808CABB0 || this->actionFunc == func_808CAF68) && + this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW) { + D_808CC258 = 200; + } + } + } + + phi_a0 = 0; + for (phi_v0_2 = 0; phi_v0_2 < ARRAY_COUNT(this->unk_160); phi_v0_2++) { + if (this->unk_160[phi_v0_2].unk_1 != 0) { + phi_a0++; + } + } + + if (phi_a0 > 1) { + func_808CA308(this, false); + } + + if (D_808CC25C == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_DEAD); + D_808CC25C = 1; + } + } + } +} + +void EnMinideath_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMinideath* this = THIS; + s32 pad; + ColliderJntSphElement* elem; + s32 temp; + s32 i; + MiniDeathStruct* phi_s0; + EnMinideath* phi_s0_3; + + if (sItemDropTimer > 0) { + sItemDropTimer--; + } + + if (this->actionFunc != EnMinideath_Dead) { + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + if (this->unk_160[i].unk_1 == 0) { + func_800B9010(&this->actor, NA_SE_EV_BAT_FLY - SFX_FLAG); + break; + } + } + } + + func_808CB8F4(this, globalCtx); + + EnMinideath_SetNextAction(this, globalCtx); + this->actionFunc(this, globalCtx); + + if (this->actionFunc != EnMinideath_Dead) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -this->actor.shape.rot.x; + + if (this->actionFunc == EnMinideath_Die) { + Actor_MoveWithGravity(&this->actor); + } else { + Actor_MoveWithoutGravity(&this->actor); + } + + if (this->actionFunc != func_808CABB0 && this->actionFunc != func_808CAF68) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 50.0f, 80.0f, 7); + } + + if (this->actionFunc != EnMinideath_Die) { + func_808CA458(this, globalCtx); + } + + Actor_SetFocus(&this->actor, 0.0f); + + phi_s0 = this->unk_160; + elem = this->collider.elements; + for (i = 0; i != ARRAY_COUNT(this->colliderElements); i++) { + if (phi_s0->unk_1 == 0) { + Math_Vec3f_Sum(&this->actor.world.pos, &phi_s0->unk_10, &phi_s0->unk_4); + + if (this->actionFunc != EnMinideath_Die) { + phi_s0->animFrame++; + if (phi_s0->animFrame == MINIDEATH_ANIM_LENGTH) { + phi_s0->animFrame = 0; + } + } + + elem->dim.worldSphere.center.x = phi_s0->unk_4.x; + elem->dim.worldSphere.center.y = phi_s0->unk_4.y; + elem->dim.worldSphere.center.z = phi_s0->unk_4.z; + } + phi_s0++; + elem++; + } + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + this->attackTimer = 40; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_ATTACK); + } + if (this->collider.base.atFlags & AT_ON) { + temp = (this->actionFunc == func_808CABB0) ? (globalCtx->gameplayFrames % 4) : 4; + + if (temp == 4 || temp == (this->number & 3)) { + if (this->attackTimer == 0 && this->actor.parent->shape.rot.x == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->actionFunc != func_808CB094) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + } + if (this->attackTimer > 0) { + this->attackTimer--; + } + if (this->number == 19) { + phi_s0_3 = NULL; + D_808CC25C = 0; + + if (D_808CC258 != 0) { + do { + phi_s0_3 = + (EnMinideath*)SubS_FindActor(globalCtx, &phi_s0_3->actor, ACTORCAT_ENEMY, ACTOR_EN_MINIDEATH); + if (phi_s0_3 != NULL) { + func_808CAC54(phi_s0_3); + phi_s0_3 = (EnMinideath*)phi_s0_3->actor.next; + } + } while (phi_s0_3 != NULL); + + globalCtx->envCtx.lightSettingOverride = 28; + + if (D_808CC258 == 5) { + ((EnDeath*)this->actor.parent)->unk_2FC = 5; + } else { + ((EnDeath*)this->actor.parent)->unk_2FC = 20; + } + D_808CC258 = 0; + } else if (D_808CC254 >= 5) { + do { + phi_s0_3 = + (EnMinideath*)SubS_FindActor(globalCtx, &phi_s0_3->actor, ACTORCAT_ENEMY, ACTOR_EN_MINIDEATH); + if (phi_s0_3 != NULL) { + phi_s0_3->timer = 0; + phi_s0_3 = (EnMinideath*)phi_s0_3->actor.next; + } + } while (phi_s0_3 != NULL); + D_808CC254 = 0; + } + } + } +} diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h index 7ac4dee6c..f8a02ea81 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h @@ -7,10 +7,47 @@ struct EnMinideath; typedef void (*EnMinideathActionFunc)(struct EnMinideath*, GlobalContext*); +// "animation" length +#define MINIDEATH_ANIM_LENGTH 9 + +typedef enum { + MINIDEATH_ACTION_CONTINUE, // continue with current action until it is changed + MINIDEATH_ACTION_1, // scatter after light arrows? + MINIDEATH_ACTION_2, // gomess damaged + MINIDEATH_ACTION_3, + MINIDEATH_ACTION_4, // chase player? + MINIDEATH_ACTION_DIE, // dead? + MINIDEATH_ACTION_6, + MINIDEATH_ACTION_7, + MINIDEATH_ACTION_8, + MINIDEATH_ACTION_9 +} MinideathAction; + +typedef struct { + /* 0x00 */ u8 animFrame; + /* 0x01 */ u8 unk_1; + /* 0x04 */ Vec3f unk_4; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ s16 unk_1C; + /* 0x1E */ s16 unk_1E; + /* 0x20 */ char unk_20[0x2]; + /* 0x22 */ s16 unk_22; +} MiniDeathStruct; // size = 0x24 + typedef struct EnMinideath { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMinideathActionFunc actionFunc; - /* 0x0148 */ char unk_148[0x164]; + /* 0x0148 */ u8 number; + /* 0x0149 */ u8 unk_149; + /* 0x014A */ s16 timer; + /* 0x014C */ s16 spawnShapeRot; + /* 0x014E */ s16 attackTimer; + /* 0x0150 */ Vec3s unk_150; // move direction? + /* 0x0158 */ f32 unk_158; + /* 0x015C */ Actor* unk_15C; + /* 0x0160 */ MiniDeathStruct unk_160[3]; + /* 0x01CC */ ColliderJntSph collider; + /* 0x01EC */ ColliderJntSphElement colliderElements[3]; } EnMinideath; // size = 0x2AC extern const ActorInit En_Minideath_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index fe4697ca9..ec6f3c690 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -6209,7 +6209,7 @@ 0x808C96C8:("EnDeath_Draw",), 0x808CA0B0:("EnMinideath_Init",), 0x808CA23C:("EnMinideath_Destroy",), - 0x808CA268:("func_808CA268",), + 0x808CA268:("EnMinideath_DropCollectible",), 0x808CA308:("func_808CA308",), 0x808CA34C:("func_808CA34C",), 0x808CA458:("func_808CA458",), @@ -6239,7 +6239,7 @@ 0x808CB6D4:("func_808CB6D4",), 0x808CB7B8:("func_808CB7B8",), 0x808CB7CC:("func_808CB7CC",), - 0x808CB810:("func_808CB810",), + 0x808CB810:("EnMinideath_SetNextAction",), 0x808CB8F4:("func_808CB8F4",), 0x808CBB18:("EnMinideath_Update",), 0x808CC260:("EnVm_Init",),