diff --git a/assets/xml/overlays/ovl_Boss_05.xml b/assets/xml/overlays/ovl_Boss_05.xml new file mode 100644 index 000000000..8eef13a4e --- /dev/null +++ b/assets/xml/overlays/ovl_Boss_05.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/spec b/spec index 6067fba85..0040f4dba 100644 --- a/spec +++ b/spec @@ -2320,8 +2320,6 @@ beginseg name "ovl_Boss_05" compress include "build/src/overlays/actors/ovl_Boss_05/z_boss_05.o" - include "build/data/ovl_Boss_05/ovl_Boss_05.data.o" - include "build/data/ovl_Boss_05/ovl_Boss_05.bss.o" include "build/data/ovl_Boss_05/ovl_Boss_05.reloc.o" endseg diff --git a/src/overlays/actors/ovl_Boss_05/z_boss_05.c b/src/overlays/actors/ovl_Boss_05/z_boss_05.c index 56d26129a..47d0d8277 100644 --- a/src/overlays/actors/ovl_Boss_05/z_boss_05.c +++ b/src/overlays/actors/ovl_Boss_05/z_boss_05.c @@ -15,68 +15,135 @@ void Boss05_Destroy(Actor* thisx, PlayState* play); void Boss05_Update(Actor* thisx, PlayState* play); void Boss05_Draw(Actor* thisx, PlayState* play); +void func_809EEDD0(Boss05* this, PlayState* play); void func_809EEDE8(Boss05* this, PlayState* play); void func_809EF9BC(Boss05* this, PlayState* play); void func_809EFAB4(Boss05* this, PlayState* play); +void func_809F00CC(Boss05* this, PlayState* play); void func_809F010C(Boss05* this, PlayState* play); +void func_809F01CC(Boss05* this, PlayState* play); void func_809F0244(Boss05* this, PlayState* play); +void func_809F02D0(Boss05* this, PlayState* play); void func_809F0374(Boss05* this, PlayState* play); +void func_809F0474(Boss05* this, PlayState* play); void func_809F04C0(Boss05* this, PlayState* play); +void func_809F0538(Boss05* this, PlayState* arg1); void func_809F0590(Boss05* this, PlayState* play); +void func_809F0650(Boss05* this, PlayState* arg1); void func_809F06B8(Boss05* this, PlayState* play); +void func_809F0708(Boss05* this, PlayState* play); void func_809F0780(Boss05* this, PlayState* play); +void func_809F0A0C(Boss05* this, PlayState* play); +void func_809F0A64(Boss05* this, PlayState* play); void func_809F0ABC(Boss05* this, PlayState* play); void func_809F0B0C(Boss05* this, PlayState* play); -#if 0 +#include "overlays/ovl_Boss_05/ovl_Boss_05.c" + // static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_809F1B2C[2] = { +ColliderJntSphElementInit D_809F1B2C[2] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1B74 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1B2C, // sJntSphElementsInit, +ColliderJntSphInit D_809F1B74 = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1B2C), + D_809F1B2C, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809F1B84[1] = { +ColliderJntSphElementInit D_809F1B84[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1BA8 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1B84, // sJntSphElementsInit, +ColliderJntSphInit D_809F1BA8 = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1B84), + D_809F1B84, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809F1BB8[1] = { +ColliderJntSphElementInit D_809F1BB8[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7FFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7FFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1BDC = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1BB8, // sJntSphElementsInit, +ColliderJntSphInit D_809F1BDC = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1BB8), + D_809F1BB8, // sJntSphElementsInit, }; +Color_RGBA8 D_809F1BEC = { 170, 255, 255, 255 }; +Color_RGBA8 D_809F1BF0 = { 200, 200, 255, 255 }; +Vec3f D_809F1BF4 = { 0.0f, -1.0f, 0.0f }; + // static DamageTable sDamageTable = { -static DamageTable D_809F1C00 = { +DamageTable D_809F1C00 = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -112,7 +179,7 @@ static DamageTable D_809F1C00 = { }; // static DamageTable sDamageTable = { -static DamageTable D_809F1C20 = { +DamageTable D_809F1C20 = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(3, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -159,107 +226,1242 @@ ActorInit Boss_05_InitVars = { /**/ Boss05_Draw, }; -#endif +extern AnimationHeader D_060006A4; +extern AnimationHeader D_06000A5C; +extern AnimationHeader D_06000ABC; +extern FlexSkeletonHeader D_060024E0; +extern AnimationHeader D_06002F0C; +extern AnimationHeader D_06003448; +extern AnimatedMaterial D_06006240[]; +extern FlexSkeletonHeader D_06006378; +extern AnimationHeader D_06006484; +extern AnimationHeader D_06006E50; +extern AnimationHeader D_06007488; +extern AnimationHeader D_06007908; -extern ColliderJntSphElementInit D_809F1B2C[2]; -extern ColliderJntSphInit D_809F1B74; -extern ColliderJntSphElementInit D_809F1B84[1]; -extern ColliderJntSphInit D_809F1BA8; -extern ColliderJntSphElementInit D_809F1BB8[1]; -extern ColliderJntSphInit D_809F1BDC; -extern DamageTable D_809F1C00; -extern DamageTable D_809F1C20; +void func_809EE4E0(Boss05* this, PlayState* play) { + Vec3f icePos; + Vec3f iceVelocity; + s32 i; -extern UNK_TYPE D_060006A4; -extern UNK_TYPE D_06000A5C; -extern UNK_TYPE D_06000ABC; -extern UNK_TYPE D_06002F0C; -extern UNK_TYPE D_06003448; -extern UNK_TYPE D_06006240; -extern UNK_TYPE D_06006E50; -extern UNK_TYPE D_06007488; -extern UNK_TYPE D_06007908; + SoundSource_PlaySfxAtFixedWorldPos(play, &this->limbPos[0], 30, NA_SE_EV_ICE_BROKEN); + for (i = 0; i < 8; i++) { + iceVelocity.x = Rand_CenteredFloat(7.0f); + iceVelocity.z = Rand_CenteredFloat(7.0f); + iceVelocity.y = Rand_ZeroFloat(6.0f) + 4.0f; + icePos.x = this->limbPos[0].x + iceVelocity.x; + icePos.y = this->limbPos[0].y + iceVelocity.y; + icePos.z = this->limbPos[0].z + iceVelocity.z; + EffectSsEnIce_Spawn(play, &icePos, Rand_ZeroFloat(0.5f) + 0.7f, &iceVelocity, &D_809F1BF4, &D_809F1BEC, + &D_809F1BF0, 30); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EE4E0.s") +void func_809EE668(s32 elementIndex, ColliderJntSph* collider, Vec3f* pos) { + collider->elements[elementIndex].dim.worldSphere.center.x = (s32)pos->x; + collider->elements[elementIndex].dim.worldSphere.center.y = (s32)pos->y; + collider->elements[elementIndex].dim.worldSphere.center.z = (s32)pos->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EE668.s") + collider->elements[elementIndex].dim.worldSphere.radius = + (s32)(collider->elements[elementIndex].dim.modelSphere.radius * collider->elements[elementIndex].dim.scale); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Init.s") +void Boss05_Init(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = THIS; + CollisionHeader* colHeader = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Destroy.s") + this->dyna.actor.targetMode = 3; + this->dyna.actor.colChkInfo.mass = MASS_HEAVY; + this->dyna.actor.colChkInfo.health = 2; + this->unk160 = (s32)Rand_ZeroFloat(1000.0f); + this->unk35C = 1.0f; + this->dyna.actor.gravity = -0.3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EECBC.s") + Actor_SetScale(&this->dyna.actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EEDD0.s") + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_0) || (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1)) { + if (this->dyna.actor.world.rot.z == 0) { + this->dyna.actor.world.rot.z = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EEDE8.s") + this->dyna.actor.shape.rot.z = 0; + this->unk168 = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z; + this->dyna.actor.colChkInfo.damageTable = &D_809F1C00; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EF9BC.s") + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&sBioBabaLilypadCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); + func_809EEDD0(this, play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EFAB4.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); + this->lastAnimFrame = Animation_GetLastFrame(&D_06006484); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EFE50.s") + Collider_InitAndSetJntSph(play, &this->collider2, &this->dyna.actor, &D_809F1B74, this->colliderElements2); + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BA8, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0014.s") + if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { + this->dyna.actor.params = BIO_DEKU_BABA_TYPE_2; + this->actionFunc = func_809EF9BC; + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + } + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) { + this->actionFunc = func_809EF9BC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0058.s") + CollisionHeader_GetVirtual(&sBioBabaLilypadCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F00CC.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_3) { + this->actionFunc = func_809EFAB4; + this->unk198 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F010C.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); + this->lastAnimFrame = Animation_GetLastFrame(&D_06006484); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F01CC.s") + Collider_InitAndSetJntSph(play, &this->collider2, &this->dyna.actor, &D_809F1B74, this->colliderElements2); + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BA8, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0244.s") + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->dyna.actor.colChkInfo.damageTable = &D_809F1C00; + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + func_809F00CC(this, play); + this->dyna.actor.colChkInfo.mass = 90; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F02D0.s") + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0374.s") + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BDC, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0474.s") + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->dyna.actor.colChkInfo.damageTable = &D_809F1C20; + this->dyna.actor.flags |= ACTOR_FLAG_10 | ACTOR_FLAG_20; + } else if (this->dyna.actor.params >= BIO_DEKU_BABA_TYPE_10) { + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F04C0.s") + this->dyna.actor.gravity = 0.0f; + this->dyna.actor.world.rot.y = (s32)Rand_ZeroFloat(0x8000); + this->dyna.actor.speed = Rand_ZeroFloat(3.0f) + 3.0f; + this->dyna.actor.velocity.y = Rand_ZeroFloat(1.5f) + 1.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0538.s") + this->unk500.x = (s32)Rand_CenteredFloat(700.0f); + this->unk500.y = (s32)Rand_CenteredFloat(1500.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(30.0f) + 50.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0590.s") + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + this->actionFunc = func_809F0B0C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0650.s") +void Boss05_Destroy(Actor* thisx, PlayState* play) { + Boss05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F06B8.s") + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) || (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_0) || + (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1)) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0708.s") +s32 func_809EECBC(Boss05* this, PlayState* play) { + if (this->unk16C == 0) { + s32 i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0780.s") + while (true) { + if (this->collider2.elements[i].info.bumperFlags & BUMP_HIT) { + switch (this->dyna.actor.colChkInfo.damageEffect) { + case 2: + return 11; + case 3: + return 20; + case 4: + return 30; + default: + return 10; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0A0C.s") + i++; + if (i == 2) { + if (this->collider1.elements[0].info.bumperFlags & BUMP_HIT) { + u8 damage = this->dyna.actor.colChkInfo.damage; + this->dyna.actor.colChkInfo.health -= damage; + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + Enemy_StartFinishingBlow(play, &this->dyna.actor); + return 2; + } else { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk16C = 15; + this->unk15C = 0; + this->unk162[0] = 30; + return 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0A64.s") + break; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0ABC.s") + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0B0C.s") +void func_809EEDD0(Boss05* this, PlayState* play) { + this->actionFunc = func_809EEDE8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Update.s") +Vec3s D_809F1C60[7] = { + { 0x3200, 0, 0 }, { -0x1E00, 0, 0 }, { -0x1400, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, +}; +Vec3s D_809F1C8C[7] = { + { -0x3200, 0, 0 }, { 0, 0, 0 }, { 0x1E00, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1050.s") +void func_809EEDE8(Boss05* this, PlayState* play) { + s32 i; + Player* sp108 = GET_PLAYER(play); + s32 j; + u8 sp103 = 0; + Vec3s spD8[7]; + s32 spD4; + s32 spD0; + s32 spCC; + s32 spC8; + s32 spC4; + s32 spC0; + s32 spBC; + s32 spB8; + s32 spB4; + s32 var_s6; + s32 var_s7; + s16 var_s5; + s16 var_s4; + f32 spA4; + f32 var_fv1; + Vec3f sp94; + s32 var_s4_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1170.s") + this->dyna.actor.hintId = TATL_HINT_ID_BIO_DEKU_BABA; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1284.s") + if (this->unk174 == 0) { + spD4 = 0x3E8; + spD0 = 0x3E80; + spCC = 0x7D0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F12A0.s") + spC8 = 0x5DC; + spC4 = 0x1770; + spC0 = 0xBB8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F135C.s") + spBC = 0x514; + spB8 = 0x5208; + spB4 = 0xDAC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1404.s") + var_s6 = 0xA; + var_s7 = 0x300; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1430.s") + if (this->unk16C != 0) { + spD4 = 0x1B58; + spCC = 0x1770; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1464.s") + spC0 = 0x1770; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F14AC.s") + spBC = 0x1C84; + spB4 = 0x1964; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1550.s") + var_s6 = 1; + var_s7 = 0x1000; + } + } else if (this->unk174 == 3) { + spD4 = 0x1B58; + spD0 = 0x3E80; + spCC = 0x1388; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Draw.s") + spC8 = 0x5DC; + spC4 = 0x2328; + spC0 = 0x1388; + + spBC = 0x1C84; + spB8 = 0x5208; + spB4 = 0x157C; + + var_s6 = 1; + var_s7 = 0x1000; + } else { + spD4 = spD0 = spCC = spC8 = spC4 = spC0 = spBC = spB8 = spB4 = var_s6 = var_s7 = 0; + } + + for (i = 0; i < 7; i++) { + if ((this->unk174 == 0) || (this->unk174 == 3)) { + if (i < 3) { + spD8[i].y = 0; + spD8[i].x = (s32)(Math_SinS((this->unk160 * spD4) + (i * spD0)) * spCC); + } else { + spD8[i].x = 0; + spD8[i].y = (s32)(Math_SinS((this->unk160 * spC8) + (i * spC4)) * spC0); + } + + if ((i == 4) || (i == 6)) { + spD8[i].z = (s32)(Math_SinS((this->unk160 * spBC) + (i * spB8)) * spB4 * 2.0f); + } else { + spD8[i].z = (s32)(Math_SinS((this->unk160 * spBC) + (i * spB8)) * spB4); + } + + var_s4 = var_s6; + var_s5 = var_s7; + } else { + if (this->unk174 == 1) { + var_s6 = 5; + var_s7 = 0x1000; + + spD8[i].x = D_809F1C60[i].x; + spD8[i].y = D_809F1C60[i].y; + spD8[i].z = D_809F1C60[i].z; + } else if (this->unk174 == 2) { + var_s6 = 1; + var_s7 = 0x2000; + + spD8[i].x = D_809F1C8C[i].x; + spD8[i].y = D_809F1C8C[i].y; + spD8[i].z = D_809F1C8C[i].z; + } + var_s4 = var_s6; + var_s5 = var_s7; + } + + Math_ApproachS(&this->unk19E[i].x, spD8[i].x, var_s6, var_s7); + Math_ApproachS(&this->unk19E[i].y, spD8[i].y, var_s6, var_s7); + Math_ApproachS(&this->unk19E[i].z, spD8[i].z, var_s6, var_s7); + } + + // There is some scope for which of var_s4,var_s5 and var_s6,var_s7 are used here + spA4 = (sp108->actor.world.pos.y - this->dyna.actor.world.pos.y) + 10.0f; + if (spA4 < 0.0f) { + Math_ApproachS(&this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer, var_s4, var_s5); + } + + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->unk35C, 1.0f, 0.1f, 0.1f); + + if (this->unk15C != 10) { + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 0x14, 0x800); + } + + switch (this->unk15C) { + case 0: + this->unk174 = 0; + this->skelAnime20.playSpeed = 1.0f; + if (spA4 < 0.0f) { + if (sp108->actor.speed > 10.0f) { + var_fv1 = 220.0f; + } else { + var_fv1 = 150.0f; + } + if ((this->unk162[0] == 0) && (sqrtf(this->dyna.actor.xyzDistToPlayerSq) <= var_fv1)) { + this->unk15C = 1; + this->unk162[0] = 10; + } + this->unk15E = 0; + } else { + sp103 = 1; + + if (sqrtf(this->dyna.actor.xyzDistToPlayerSq) <= 40.0f) { + this->unk15E++; + if (this->unk15E > 30) { + this->unk15C = 10; + this->unk162[0] = 30; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_ATTACK); + } + } else { + this->unk15E = 0; + } + } + if (!(this->unk160 & 3) && (Rand_ZeroOne() < 0.5f)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + break; + + case 10: + if (!(this->unk160 & 1)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + this->unk19C = (this->unk162[0] & 1) * 0x200; + this->unk174 = 3; + this->skelAnime20.playSpeed = 4.0f; + Math_ApproachS(&this->dyna.actor.shape.rot.x, -0x8000, 2, 0x2000); + Math_ApproachS(&this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer, 2, 0x2000); + if (this->unk162[0] == 0) { + this->unk15E = 0; + this->unk15C = 0; + this->unk162[0] = 100; + } + if (this->unk162[0] == 27) { + Math_Vec3f_Copy(&sp94, &this->dyna.actor.world.pos); + sp94.y += 40.0f; + EffectSsGSplash_Spawn(play, &sp94, NULL, NULL, 1, 2000); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_OUT_OF_WATER); + } + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + this->skelAnime20.playSpeed = 0.0f; + } + this->unk174 = 1; + if (this->unk162[0] == 0) { + this->unk15C = 2; + this->unk162[0] = 20; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_ATTACK); + } + break; + + case 2: + if (!(this->unk160 & 1)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + this->unk19C = (this->unk162[0] & 1) * 0x200; + this->skelAnime20.playSpeed = 4.0f; + Math_ApproachF(&this->unk35C, 1.5f, 1.0f, 0.7f); + this->unk174 = 2; + if (this->unk162[0] == 0) { + this->unk15C = 0; + this->unk162[0] = 30; + } + break; + } + + var_s4_2 = func_809EECBC(this, play); + if ((var_s4_2 != 0) || (this->unk168 == 1)) { + Boss05* temp_v0_6; + + this->dyna.actor.params = BIO_DEKU_BABA_TYPE_2; + this->actionFunc = func_809EF9BC; + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + if (this->unk168 != 0) { + var_s4_2 = 10; + } + if (var_s4_2 >= 10) { + temp_v0_6 = (Boss05*)Actor_SpawnAsChild( + &play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, BIO_DEKU_BABA_TYPE_3); + if (temp_v0_6 != NULL) { + Player* temp_v1 = GET_PLAYER(play); + if (temp_v1->lockOnActor == &this->dyna.actor) { + temp_v1->lockOnActor = &temp_v0_6->dyna.actor; + play->actorCtx.targetCtx.fairyActor = &temp_v0_6->dyna.actor; + play->actorCtx.targetCtx.lockOnActor = &temp_v0_6->dyna.actor; + } + + for (i = 0; i < 10; i++) { + temp_v0_6->skelAnime10.jointTable[i] = this->skelAnime10.jointTable[i]; + } + + for (i = 0; i < 20; i++) { + temp_v0_6->skelAnime20.jointTable[i] = this->skelAnime20.jointTable[i]; + } + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_DAMAGE); + if (var_s4_2 > 10) { + temp_v0_6->drawDmgEffState = var_s4_2 - 10; + } + } + } else if (var_s4_2 == 2) { + for (i = 0; i < 2; i++) { + temp_v0_6 = (Boss05*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, + this->unk324.x, this->unk324.y, this->unk324.z, this->unk330.x, + this->unk330.y, this->unk330.z, i + BIO_DEKU_BABA_TYPE_10); + if (temp_v0_6 != NULL) { + + for (j = 0; j < 20; j++) { + temp_v0_6->skelAnime20.jointTable[j] = this->skelAnime20.jointTable[j]; + } + + temp_v0_6->unk162[0] = (s32)(Rand_ZeroFloat(20.0f) + 20.0f); + } + } + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA_DEAD); + } + } + + if (sp103 == 0) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider2.base); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); + } + + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider1.base); +} + +void func_809EF9BC(Boss05* this, PlayState* play) { + Player* player = GET_PLAYER(play); + f32 distToPlayer = sqrtf(this->dyna.actor.xyzDistToPlayerSq); + s16 var_a1; + + if ((distToPlayer < 50.0f) && (player->actor.bgCheckFlags & 1)) { + var_a1 = (s32)(distToPlayer * 80.0f); + var_a1 = CLAMP_MAX(var_a1, 0x7D0); + // if (var_a1 > 0x7D0) { + // var_a1 = 0x7D0; + // } + Math_ApproachS(&this->unk178, var_a1, 0x14, 0x7D0); + Math_ApproachS(&this->unk176, this->dyna.actor.yawTowardsPlayer, 0x14, 0xFA0); + if ((this->unk160 % 16) == 0) { + EffectSsGRipple_Spawn(play, &this->dyna.actor.world.pos, 500, 1000, 0); + } + } else { + Math_ApproachS(&this->unk178, 0, 0x14, 0x100); + } +} + +void func_809EFAB4(Boss05* this, PlayState* play) { + s32 i; + Vec3f unusedPos; + Vec3f bubblePos; + Boss05* temp_v0; + Player* player; + + Actor_MoveWithGravity(&this->dyna.actor); + this->dyna.actor.world.pos.y -= 85.0f; + this->dyna.actor.prevPos.y -= 85.0f; + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x44); + this->dyna.actor.world.pos.y += 85.0f; + this->dyna.actor.prevPos.y += 85.0f; + + if (this->dyna.actor.bgCheckFlags & 0x20) { + this->dyna.actor.gravity = -0.3f; + this->dyna.actor.terminalVelocity = -5.0f; + } else { + this->dyna.actor.gravity = -2.0f; + this->dyna.actor.terminalVelocity = -20.0f; + } + + if (this->dyna.actor.bgCheckFlags & 0x40) { + this->dyna.actor.velocity.y = -3.0f; + this->dyna.actor.gravity = -0.3f; + this->dyna.actor.terminalVelocity = -5.0f; + Math_Vec3f_Copy(&unusedPos, &this->dyna.actor.world.pos); + unusedPos.y += 20.0f; + EffectSsGSplash_Spawn(play, &this->dyna.actor.world.pos, NULL, NULL, 1, 1000); + this->unk162[2] = 20; + } + + if (this->unk162[2] != 0) { + for (i = 0; i < 3; i++) { + bubblePos.x = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.x; + bubblePos.y = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.y; + bubblePos.z = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.z; + EffectSsBubble_Spawn(play, &bubblePos, 20.0f, 10.0f, 20.0f, 0.13f); + } + } + + if (this->dyna.actor.bgCheckFlags & 1) { + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && (this->unk17A != 0)) { + this->unk17A = 0; + } + + Math_ApproachZeroF(&this->unk198, 1.0f, 0.05f); + + if (this->unk198 == 0.0f) { + temp_v0 = (Boss05*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, + this->unk324.x, this->unk324.y, this->unk324.z, this->unk330.x, + this->unk330.y, this->unk330.z, BIO_DEKU_BABA_TYPE_4); + + if (temp_v0 != NULL) { + player = GET_PLAYER(play); + if (player->lockOnActor == &this->dyna.actor) { + player->lockOnActor = &temp_v0->dyna.actor; + play->actorCtx.targetCtx.fairyActor = &temp_v0->dyna.actor; + play->actorCtx.targetCtx.lockOnActor = &temp_v0->dyna.actor; + } + + for (i = 0; i < 20; i++) { + temp_v0->skelAnime20.jointTable[i] = this->skelAnime20.jointTable[i]; + } + + Actor_PlaySfx(&temp_v0->dyna.actor, NA_SE_EN_MIZUBABA_TRANSFORM); + } + Actor_Kill(&this->dyna.actor); + } + } +} + +void func_809EFE50(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + Boss05* this = THIS; + u8 takeDamage = false; + ColliderInfo* hitInfo; + + if ((this->unk16A == 0) && (this->collider1.elements[0].info.bumperFlags & BUMP_HIT)) { + this->collider1.elements[0].info.bumperFlags &= ~BUMP_HIT; + hitInfo = this->collider1.elements[0].info.acHitInfo; + if (hitInfo->toucher.dmgFlags & 0x300000) { // (DMG_NORMAL_SHIELD | DMG_LIGHT_RAY) + this->unk338 = -12.0f; + this->unk348 = this->dyna.actor.yawTowardsPlayer; + this->unk16A = 6; + return; + } + + this->unk16A = 10; + this->dyna.actor.speed = 0.0f; + this->unk338 = -20.0f; + this->unk348 = this->dyna.actor.yawTowardsPlayer; + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + + switch (this->dyna.actor.colChkInfo.damageEffect) { + case 1: + func_809F0A0C(this, play); + break; + + case 2: + this->drawDmgEffState = 1; + takeDamage = true; + break; + + case 3: + func_809F0A64(this, play); + this->drawDmgEffState = 10; + break; + + case 4: + this->drawDmgEffState = 20; + takeDamage = true; + break; + + default: + takeDamage = true; + break; + } + + if (takeDamage) { + u8 damage; // Probably fake? + + if ((this->actionFunc == func_809F0ABC) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->unk17A != 0)) { + func_809EE4E0(this, play); + this->drawDmgEffState = 0; + } + + damage = this->dyna.actor.colChkInfo.damage; + this->dyna.actor.colChkInfo.health -= damage; + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + Enemy_StartFinishingBlow(play, &this->dyna.actor); + } + + func_809F0708(this, play); + this->unk16C = 15; + } + } +} + +s32 func_809F0014(Boss05* this, PlayState* play) { + s16 yawDiff = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.shape.rot.y; + + if (ABS_ALT(yawDiff) < 0x3000) { + return true; + } else { + return false; + } +} + +void func_809F0058(Boss05* this, PlayState* play) { + if (func_809F0014(this, play) && (this->dyna.actor.xyzDistToPlayerSq <= SQ(200.0f)) && + (fabsf(this->dyna.actor.playerHeightRel) < 70.0f)) { + func_809F0474(this, play); + } +} + +void func_809F00CC(Boss05* this, PlayState* play) { + this->actionFunc = func_809F010C; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06006E50, -5.0f); +} + +void func_809F010C(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 2, 0x400); + Math_ApproachS(&this->dyna.actor.shape.rot.z, 0, 2, 0x400); + Math_ApproachF(&this->unk360, 1.0f, 1.0f, 0.5f); + Math_ApproachF(&this->unk364, 1.0f, 1.0f, 0.14f); + + if (this->unk364 == 1.0f) { + func_809F01CC(this, play); + } +} + +void func_809F01CC(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0244; + Animation_MorphToLoop(&this->skelAnime20, &D_06007488, -10.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(25.0f) + 25.0f); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); +} + +void func_809F0244(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 2, 0x400); + Math_ApproachS(&this->dyna.actor.shape.rot.z, 0, 2, 0x400); + + if (this->unk162[0] == 0) { + func_809F02D0(this, play); + } + + func_809F0058(this, play); +} + +void func_809F02D0(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0374; + Animation_MorphToLoop(&this->skelAnime20, &D_06007908, 0.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(80.0f) + 60.0f); + this->unk34C.x = Rand_CenteredFloat(400.0f) + this->dyna.actor.world.pos.x; + this->unk34C.z = Rand_CenteredFloat(400.0f) + this->dyna.actor.world.pos.z; + this->unk358 = 0.0f; +} + +void func_809F0374(Boss05* this, PlayState* play) { + f32 deltaX; + f32 deltaZ; + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_WALK - SFX_FLAG); + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->dyna.actor.speed, 5.0f, 1.0f, 2.0f); + deltaX = this->unk34C.x - this->dyna.actor.world.pos.x; + deltaZ = this->unk34C.z - this->dyna.actor.world.pos.z; + Math_ApproachS(&this->dyna.actor.world.rot.y, Math_Atan2S(deltaX, deltaZ), 5, (s32)this->unk358); + Math_ApproachF(&this->unk358, 2000.0f, 1.0f, 100.0f); + + if ((this->unk162[0] == 0) || ((SQ(deltaX) + SQ(deltaZ)) < 2500.0f)) { + func_809F01CC(this, play); + } + + func_809F0058(this, play); +} + +void func_809F0474(Boss05* this, PlayState* play) { + this->actionFunc = func_809F04C0; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06003448, 0.0f); + this->unk162[0] = 20; +} + +void func_809F04C0(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_VOICE - SFX_FLAG); + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + Math_ApproachS(&this->dyna.actor.world.rot.y, this->dyna.actor.yawTowardsPlayer, 5, 0x1000); + if (this->unk162[0] == 0) { + func_809F0538(this, play); + } +} + +void func_809F0538(Boss05* this, PlayState* arg1) { + this->actionFunc = func_809F0590; + Animation_MorphToLoop(&this->skelAnime20, &D_06000A5C, 0.0f); + this->unk162[0] = 60; + this->unk358 = 0.0f; +} + +void func_809F0590(Boss05* this, PlayState* play) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_VOICE - SFX_FLAG); + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->dyna.actor.speed, 8.0f, 1.0f, 4.0f); + Math_ApproachS(&this->dyna.actor.world.rot.y, this->dyna.actor.yawTowardsPlayer, 5, (s32)this->unk358); + Math_ApproachF(&this->unk358, 4000.0f, 1.0f, 400.0f); + + if ((this->unk162[0] == 0) || (this->dyna.actor.xyzDistToPlayerSq <= SQ(150.0f))) { + func_809F0650(this, play); + } +} + +void func_809F0650(Boss05* this, PlayState* arg1) { + this->actionFunc = func_809F06B8; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_060006A4, 0.0f); + this->lastAnimFrame = Animation_GetLastFrame(&D_060006A4); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_ATTACK); +} + +void func_809F06B8(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + func_809F01CC(this, play); + } +} + +void func_809F0708(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0780; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06002F0C, 0.0f); + this->lastAnimFrame = Animation_GetLastFrame(&D_060006A4); + Actor_SetColorFilter(&this->dyna.actor, 0x4000, 120, 0, 30); +} + +void func_809F0780(Boss05* this, PlayState* play) { + s32 i; + s32 j; + Vec3f bubblePos; + Boss05* temp_v0; + + SkelAnime_Update(&this->skelAnime20); + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + if (Animation_OnFrame(&this->skelAnime20, 22.0f)) { + for (i = 0; i < 14; i++) { + temp_v0 = (Boss05*)Actor_SpawnAsChild( + &play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, i + BIO_DEKU_BABA_TYPE_10); + + if (temp_v0 != NULL) { + for (j = 0; j < 20; j++) { + temp_v0->skelAnime20.jointTable[j] = this->skelAnime20.jointTable[j]; + } + } + } + + for (i = 0; i < 20; i++) { + bubblePos.x = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.x; + bubblePos.y = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.y; + bubblePos.z = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.z; + EffectSsBubble_Spawn(play, &bubblePos, 20.0f, 10.0f, 20.0f, 0.13f); + } + + SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EN_MIZUBABA_DEAD); + Actor_Kill(&this->dyna.actor); + Item_DropCollectibleRandom(play, NULL, &this->dyna.actor.world.pos, 0xE0); + } + } else if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + func_809F0474(this, play); + } +} + +void func_809F0A0C(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0ABC; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk162[0] = 40; + Actor_SetColorFilter(&this->dyna.actor, 0, 120, 0, 40); +} + +void func_809F0A64(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0ABC; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk162[0] = 80; + Actor_SetColorFilter(&this->dyna.actor, 0, 120, 0, 80); +} + +void func_809F0ABC(Boss05* this, PlayState* play) { + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + if (this->unk162[0] == 0) { + func_809F01CC(this, play); + } +} + +void func_809F0B0C(Boss05* this, PlayState* play) { + Actor_MoveWithGravity(&this->dyna.actor); + + if (this->unk15C == 0) { + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x44); + if (this->dyna.actor.bgCheckFlags & 0x20) { + this->unk15C = 1; + } else { + this->unk15C = 2; + } + } + + if (this->unk15C == 1) { + Math_ApproachF(&this->dyna.actor.velocity.y, 1.0f, 1.0f, 0.1f); + Math_ApproachZeroF(&this->dyna.actor.speed, 0.5f, 0.5f); + this->dyna.actor.shape.rot.x += this->unk500.x; + this->dyna.actor.shape.rot.y += this->unk500.y; + + if (this->unk162[0] == 0) { + Actor_Kill(&this->dyna.actor); + } + } else { + switch (this->unk15C) { + case 2: + this->dyna.actor.velocity.y = Rand_ZeroFloat(3.0f) + 3.0f; + this->dyna.actor.speed = Rand_CenteredFloat(5.0f) + 5.0f; + this->dyna.actor.world.rot.y = (s32)Rand_ZeroFloat(0x10000); + this->dyna.actor.gravity = -1.0f; + this->unk15C = 3; + break; + + case 3: + Actor_MoveWithGravity(&this->dyna.actor); + + if (this->unk324.y < (this->dyna.actor.floorHeight - 30.0f)) { + Actor_Kill(&this->dyna.actor); + } + break; + + default: + break; + } + } +} + +void Boss05_Update(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = (Boss05*)thisx; + s16 var_v0; + + this->unk160++; + + for (var_v0 = 0; var_v0 < 3; var_v0++) { + if (this->unk162[var_v0] != 0) { + this->unk162[var_v0]--; + } + } + + if (this->unk16A != 0) { + this->unk16A--; + } + + if (this->unk16C != 0) { + this->unk16C--; + } + if (this->unk168 != 0) { + this->unk168--; + } + + if (this->unk17A != 0) { + this->unk17A--; + } + + this->actionFunc(this, play); + + if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + Actor_MoveWithGravity(&this->dyna.actor); + Matrix_RotateYS(this->unk348, MTXMODE_NEW); + Matrix_MultVecZ(this->unk338, &this->unk33C); + this->dyna.actor.world.pos.x += this->unk33C.x; + this->dyna.actor.world.pos.z += this->unk33C.z; + Math_ApproachZeroF(&this->unk338, 1.0f, 1.0f); + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x45); + func_809EFE50(&this->dyna.actor, play); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider1.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + } + + switch (this->drawDmgEffState) { + case 0: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->unk17A = 0; + this->drawDmgEffAlpha = 0.0f; + break; + + case 1: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + // fallthrough + case 2: + if (this->unk17A == 0) { + Math_ApproachZeroF(&this->drawDmgEffAlpha, 1.0f, 0.02f); + if (this->drawDmgEffAlpha == 0.0f) { + this->drawDmgEffState = 0; + } + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 0.1f, 0.5f); + } + break; + + case 10: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + this->dmgEffFrozenSteamScale = 2.0f; + // fallthrough + case 11: + if (this->unk17A == 0) { + func_809EE4E0(this, play); + this->drawDmgEffState = 0; + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 1.0f, 0.25f); + Math_ApproachF(&this->dmgEffFrozenSteamScale, 1.0f, 0.1f, 0.1f); + } + break; + + case 20: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + break; + + case 21: + if (this->unk17A == 0) { + Math_ApproachZeroF(&this->drawDmgEffScale, 1.0f, 0.03f); + + if (this->drawDmgEffScale == 0.0f) { + this->drawDmgEffState = 0; + this->drawDmgEffAlpha = 0.0f; + } + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 0.5f, 0.5f); + } + break; + } +} + +s8 D_809F1CB8[] = { -1, -1, 0, 1, 2, 3, 4, 5, 6, -1, -1, 0 }; + +s32 func_809F1050(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + s8 temp_v1; + + if (limbIndex == KREG(32)) { + if (!(this->unk160 & 3)) { + *dList = NULL; + } + + rot->x += KREG(33) * 0x100; + rot->y += KREG(34) * 0x100; + rot->z += KREG(35) * 0x100; + } + + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1) && (limbIndex == 9)) { + *dList = NULL; + } + + if (limbIndex == 2) { + rot->x += this->unk19C; + } + + temp_v1 = D_809F1CB8[limbIndex]; + if (temp_v1 >= 0) { + rot->x = rot->x + this->unk19E[temp_v1].x; + rot->y = rot->y + this->unk19E[temp_v1].y; + rot->z = rot->z + this->unk19E[temp_v1].z; + } + + return false; +} + +Vec3f D_809F1CC4 = { 0.0f, -1400.0f, 600.0f }; + +void func_809F1170(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + MtxF mf; + Vec3f spherePos0; + Vec3f spherePos1; + + if (limbIndex == 4) { + Matrix_MultVec3f(&D_809F1CC4, &this->unk324); + + if (this->actionFunc == func_809EFAB4) { + Matrix_MultVec3f(&D_809F1CC4, &this->dyna.actor.focus.pos); + } + + Matrix_Get(&mf); + Matrix_MtxFToYXZRot(&mf, &this->unk330, false); + this->unk330.x += 0xF00; + } + + if (limbIndex == 2) { + Matrix_MultZero(&spherePos0); + func_809EE668(0, &this->collider2, &spherePos0); + } + + if (limbIndex == 3) { + Matrix_MultVecY(-500.0f, &spherePos1); + func_809EE668(1, &this->collider2, &spherePos1); + + if (this->actionFunc == func_809EEDE8) { + Matrix_MultVecY(1500.0f, &this->dyna.actor.focus.pos); + } + } +} + +s32 func_809F1284(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; +} + +Vec3f D_809F1CD0 = { 1600.0f, -300.0f, 0.0f }; +Vec3f D_809F1CDC = { 700.0f, 0.0f, 0.0f }; + +Vec3f D_809F2110; // bss + +void func_809F12A0(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex == 1) { + Matrix_MultVec3f(&D_809F1CD0, &D_809F2110); + func_809EE668(0, &this->collider1, &D_809F2110); + + if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + Matrix_MultVec3f(&D_809F1CDC, &thisx->focus.pos); + } + + if (this->drawDmgEffState != 0) { + Matrix_MultVec3f(&D_809F1CDC, &this->limbPos[0]); + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) { + this->limbPos[0].y -= 15.0f; + } + } + } +} + +void func_809F135C(PlayState* play, s32 limbIndex, Actor* thisx) { + Boss05* this = THIS; + + if ((limbIndex == 2) || (limbIndex == 3)) { + Matrix_Scale(this->unk35C, 1.0f, this->unk35C, MTXMODE_APPLY); + } + + if (limbIndex == 1) { + Matrix_Scale(this->unk360, this->unk360, this->unk360, MTXMODE_APPLY); + } + + if ((limbIndex >= 4) && (limbIndex < 20)) { + Matrix_Scale(this->unk364, this->unk364, this->unk364, MTXMODE_APPLY); + } +} + +s32 func_809F1404(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + if ((limbIndex >= 3) && (limbIndex < 9)) { + *dList = NULL; + } + + return false; +} + +s32 func_809F1430(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + if ((limbIndex == 1) || (limbIndex == 2) || (limbIndex == 9)) { + *dList = NULL; + } + + return false; +} + +void func_809F1464(PlayState* play, s32 limbIndex, Actor* thisx) { + Boss05* this = THIS; + + if ((limbIndex >= 3) && (limbIndex < 9)) { + Matrix_Scale(this->unk198, this->unk198, this->unk198, MTXMODE_APPLY); + } +} + +s32 D_809F1CE8[] = { 2, 3, 1, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19 }; + +s32 func_809F14AC(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex != D_809F1CE8[this->dyna.actor.params - BIO_DEKU_BABA_TYPE_10]) { + *dList = NULL; + } else if (this->unk15C >= 2) { + rot->x += this->unk160 * 0x3000; + rot->y += this->unk160 * 0x1A00; + rot->z += this->unk160 * 0x2000; + } + return false; +} + +void func_809F1550(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex != D_809F1CE8[this->dyna.actor.params - BIO_DEKU_BABA_TYPE_10]) { + Matrix_MultZero(&this->unk324); + } +} + +void Boss05_Draw(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + if (this->actionFunc == func_809EEDE8) { + SkelAnime_DrawFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1050, func_809F1170, &this->dyna.actor); + + if ((this->unk16C % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + Matrix_Translate(this->unk324.x, this->unk324.y, this->unk324.z, MTXMODE_NEW); + Matrix_RotateYS(this->unk330.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk330.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk330.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) { + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->unk176, MTXMODE_APPLY); + Matrix_RotateXS(this->unk178, MTXMODE_APPLY); + Matrix_RotateYS(-this->unk176, MTXMODE_APPLY); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1404, NULL, &this->dyna.actor); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_3) { + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1430, func_809F1170, func_809F1464, + &this->dyna.actor); + + Matrix_Translate(this->unk324.x, this->unk324.y, this->unk324.z, MTXMODE_NEW); + Matrix_RotateYS(this->unk330.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk330.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk330.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + + Actor_DrawDamageEffects(play, &this->dyna.actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->dmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + if ((this->unk16C % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + + Actor_DrawDamageEffects(play, &this->dyna.actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->dmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } else if (this->dyna.actor.params >= BIO_DEKU_BABA_TYPE_10) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F14AC, func_809F1550, &this->dyna.actor); + } + + POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Boss_05/z_boss_05.h b/src/overlays/actors/ovl_Boss_05/z_boss_05.h index 8f46476ea..51cafa079 100644 --- a/src/overlays/actors/ovl_Boss_05/z_boss_05.h +++ b/src/overlays/actors/ovl_Boss_05/z_boss_05.h @@ -7,11 +7,60 @@ struct Boss05; typedef void (*Boss05ActionFunc)(struct Boss05*, PlayState*); +typedef enum { + /* 0 */ BIO_DEKU_BABA_TYPE_0, + /* 0 */ BIO_DEKU_BABA_TYPE_1, + /* 0 */ BIO_DEKU_BABA_TYPE_2, + /* 0 */ BIO_DEKU_BABA_TYPE_3, + /* 0 */ BIO_DEKU_BABA_TYPE_4, + /* 0 */ BIO_DEKU_BABA_TYPE_10 = 10, // Fragments? +} BioDekuBabaType; + typedef struct Boss05 { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x2C]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ u8 unk15C; /* inferred */ + /* 0x15E */ s16 unk15E; /* inferred */ + /* 0x160 */ s16 unk160; /* inferred */ + /* 0x162 */ s16 unk162[3]; // timers + /* 0x168 */ s16 unk168; // timer + /* 0x16A */ s16 unk16A; // timer + /* 0x16C */ s16 unk16C; // timer /* 0x170 */ Boss05ActionFunc actionFunc; - /* 0x174 */ char unk_174[0x394]; + /* 0x174 */ u8 unk174; + /* 0x176 */ s16 unk176; + /* 0x178 */ s16 unk178; + /* 0x17A */ s16 unk17A; // timer + /* 0x17C */ f32 drawDmgEffScale; + /* 0x180 */ f32 dmgEffFrozenSteamScale; + /* 0x184 */ f32 drawDmgEffAlpha; + /* 0x188 */ u8 drawDmgEffState; // A bit more than just type, possibly we should name it as an internal type? + /* 0x189 */ u8 drawDmgEffType; + /* 0x18C */ Vec3f limbPos[1]; + /* 0x198 */ f32 unk198; + /* 0x19C */ s16 unk19C; + /* 0x19E */ Vec3s unk19E[7]; + /* 0x1C8 */ ColliderJntSph collider2; + /* 0x1E8 */ ColliderJntSphElement colliderElements2[2]; + /* 0x268 */ SkelAnime skelAnime10; + /* 0x2AC */ Vec3s jointTable10[10]; + /* 0x2E8 */ Vec3s morphTable10[10]; + /* 0x324 */ Vec3f unk324; // pos used for spawning and drawing + /* 0x330 */ Vec3s unk330; // rotation used for spawning and drawing + /* 0x338 */ f32 unk338; + /* 0x33C */ Vec3f unk33C; + /* 0x348 */ s16 unk348; + /* 0x34C */ Vec3f unk34C; + /* 0x35C */ f32 unk358; + /* 0x35C */ f32 unk35C; + /* 0x360 */ f32 unk360; + /* 0x364 */ f32 unk364; + /* 0x368 */ ColliderJntSph collider1; + /* 0x388 */ ColliderJntSphElement colliderElements1[1]; + /* 0x3C8 */ SkelAnime skelAnime20; + /* 0x40C */ Vec3s jointTable20[20]; + /* 0x484 */ Vec3s morphTable20[20]; + /* 0x4FC */ f32 lastAnimFrame; + /* 0x500 */ Vec3s unk500; } Boss05; // size = 0x508 #endif // Z_BOSS_05_H diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index d85499bda..5c8ad025d 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -10210,11 +10210,11 @@ 0x809F1C40:("Boss_05_InitVars","UNK_TYPE1","",0x1), 0x809F1C60:("D_809F1C60","UNK_TYPE2","",0x2), 0x809F1C8C:("D_809F1C8C","UNK_TYPE2","",0x2), - 0x809F1CB8:("D_809F1CB8","UNK_TYPE1","",0x1), - 0x809F1CC0:("D_809F1CC0","UNK_TYPE1","",0x1), - 0x809F1CC4:("D_809F1CC4","UNK_TYPE1","",0x1), - 0x809F1CD0:("D_809F1CD0","UNK_TYPE1","",0x1), - 0x809F1CDC:("D_809F1CDC","UNK_TYPE1","",0x1), + 0x809F1CB8:("D_809F1CB8","s8","[12]",0xC), + 0x809F1CC4:("D_809F1CC4","Vec3f","",0xC), + 0x809F1CD0:("D_809F1CD0","Vec3f","",0xC), + 0x809F1CDC:("D_809F1CDC","Vec3f","",0xC), + 0x809F1CE8:("D_809F1CE8","s32","[]",0x38), 0x809F1D20:("D_809F1D20","f32","",0x4), 0x809F1D24:("D_809F1D24","f32","",0x4), 0x809F1D28:("D_809F1D28","f32","",0x4),