From 9297e6dd5220dd4aac84ab67e99d4a1a64f77b02 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis Date: Tue, 21 Feb 2023 17:30:09 +0000 Subject: [PATCH] EnDekubaba OK and documented, object_dekubaba documented, EnKarebaba documented (#1088) * OK, struct documented * Data imported, update spec * Name data * Name all functions and variables * Document object * Bit more documentation * Document Karebaba * Add note to object_dekubaba * Bit more cleanup * Review * Shadow * Review * Rename functions, add hit enum * Figured out the enum * Review * MarkForDeath -> Kill --- assets/xml/objects/object_dekubaba.xml | 59 +- spec | 3 +- .../actors/ovl_En_Dekubaba/z_en_dekubaba.c | 1400 +++++++++++++++-- .../actors/ovl_En_Dekubaba/z_en_dekubaba.h | 23 +- .../actors/ovl_En_Karebaba/z_en_karebaba.c | 585 ++++--- .../actors/ovl_En_Karebaba/z_en_karebaba.h | 25 +- tools/disasm/functions.txt | 134 +- tools/disasm/variables.txt | 22 +- undefined_syms.txt | 10 - 9 files changed, 1718 insertions(+), 543 deletions(-) diff --git a/assets/xml/objects/object_dekubaba.xml b/assets/xml/objects/object_dekubaba.xml index eb80e770b7..87634d654c 100644 --- a/assets/xml/objects/object_dekubaba.xml +++ b/assets/xml/objects/object_dekubaba.xml @@ -1,27 +1,40 @@  + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec b/spec index bef1b4654f..0b50e32ac8 100644 --- a/spec +++ b/spec @@ -963,8 +963,7 @@ beginseg name "ovl_En_Dekubaba" compress include "build/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.o" - include "build/data/ovl_En_Dekubaba/ovl_En_Dekubaba.data.o" - include "build/data/ovl_En_Dekubaba/ovl_En_Dekubaba.reloc.o" + include "build/src/overlays/actors/ovl_En_Dekubaba/ovl_En_Dekubaba_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c index 93d4952670..45b851271a 100644 --- a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c +++ b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c @@ -5,6 +5,8 @@ */ #include "z_en_dekubaba.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) @@ -15,23 +17,31 @@ void EnDekubaba_Destroy(Actor* thisx, PlayState* play); void EnDekubaba_Update(Actor* thisx, PlayState* play); void EnDekubaba_Draw(Actor* thisx, PlayState* play); -void func_808B1B14(EnDekubaba* this, PlayState* play); -void func_808B1CF0(EnDekubaba* this, PlayState* play); -void func_808B2240(EnDekubaba* this, PlayState* play); -void func_808B2660(EnDekubaba* this, PlayState* play); -void func_808B28B4(EnDekubaba* this, PlayState* play); -void func_808B29C4(EnDekubaba* this, PlayState* play); -void func_808B2CB8(EnDekubaba* this, PlayState* play); -void func_808B3078(EnDekubaba* this, PlayState* play); -void func_808B3280(EnDekubaba* this, PlayState* play); -void func_808B3404(EnDekubaba* this, PlayState* play); -void func_808B37E8(EnDekubaba* this, PlayState* play); -void func_808B3B48(EnDekubaba* this, PlayState* play); -void func_808B3C50(EnDekubaba* this, PlayState* play); -void func_808B3DA8(EnDekubaba* this, PlayState* play); -void func_808B3EE8(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupWait(EnDekubaba* this); +void EnDekubaba_Wait(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupGrow(EnDekubaba* this); +void EnDekubaba_Grow(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupRetract(EnDekubaba* this); +void EnDekubaba_Retract(EnDekubaba* this, PlayState* play); +void EnDekubaba_DecideLunge(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupPrepareLunge(EnDekubaba* this); +void EnDekubaba_PrepareLunge(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupLunge(EnDekubaba* this); +void EnDekubaba_Lunge(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupPullBack(EnDekubaba* this); +void EnDekubaba_PullBack(EnDekubaba* this, PlayState* play); +void EnDekubaba_Recover(EnDekubaba* this, PlayState* play); +void EnDekubaba_Hit(EnDekubaba* this, PlayState* play); +void EnDekubaba_PrunedSomersaultDie(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupShrinkDie(EnDekubaba* this); +void EnDekubaba_ShrinkDie(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupStunnedVertical(EnDekubaba* this); +void EnDekubaba_StunnedVertical(EnDekubaba* this, PlayState* play); +void EnDekubaba_Sway(EnDekubaba* this, PlayState* play); +void EnDekubaba_Frozen(EnDekubaba* this, PlayState* play); +void EnDekubaba_SetupDeadStickDrop(EnDekubaba* this, PlayState* play); +void EnDekubaba_DeadStickDrop(EnDekubaba* this, PlayState* play); -#if 0 ActorInit En_Dekubaba_InitVars = { ACTOR_EN_DEKUBABA, ACTORCAT_ENEMY, @@ -44,188 +54,1332 @@ ActorInit En_Dekubaba_InitVars = { (ActorFunc)EnDekubaba_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[7] = { -static ColliderJntSphElementInit D_808B4D60[7] = { +static ColliderJntSphElementInit sJntSphElementsInit[7] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 1, { { 0, 100, 1000 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 51, { { 0, 0, 1500 }, 8 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 52, { { 0, 0, 500 }, 8 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 53, { { 0, 0, 1500 }, 8 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 54, { { 0, 0, 500 }, 8 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 55, { { 0, 0, 1500 }, 8 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 56, { { 0, 0, 500 }, 8 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808B4E5C = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_808B4D60, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT6, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808B4E6C = { 2, 25, 25, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 25, 25, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_808B4E74 = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(3, 0x0), - /* Horse trample */ DMG_ENTRY(1, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* Zora boomerang */ DMG_ENTRY(1, 0xF), - /* Normal arrow */ DMG_ENTRY(3, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0xD), - /* Goron punch */ DMG_ENTRY(2, 0x0), - /* Sword */ DMG_ENTRY(1, 0xF), - /* Goron pound */ DMG_ENTRY(4, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(3, 0x3), - /* Light arrow */ DMG_ENTRY(3, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(1, 0xF), - /* Deku bubble */ DMG_ENTRY(3, 0x0), - /* Deku launch */ DMG_ENTRY(2, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(0, 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, 0xF), - /* Sword beam */ DMG_ENTRY(0, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0x0), +typedef enum { + /* 0x0 */ DEKUBABA_DMGEFF_NONE, + /* 0x1 */ DEKUBABA_DMGEFF_NUT, + /* 0x2 */ DEKUBABA_DMGEFF_FIRE, + /* 0x3 */ DEKUBABA_DMGEFF_ICE, + /* 0x4 */ DEKUBABA_DMGEFF_LIGHT, + /* 0x5 */ DEKUBABA_DMGEFF_ELECTRIC, + /* 0xD */ DEKUBABA_DMGEFF_HOOKSHOT = 0xD, + /* 0xF */ DEKUBABA_DMGEFF_CUT = 0xF +} DekuBabaDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NUT), + /* Deku Stick */ DMG_ENTRY(3, DEKUBABA_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, DEKUBABA_DMGEFF_CUT), + /* Normal arrow */ DMG_ENTRY(3, DEKUBABA_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, DEKUBABA_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(2, DEKUBABA_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, DEKUBABA_DMGEFF_CUT), + /* Goron pound */ DMG_ENTRY(4, DEKUBABA_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, DEKUBABA_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(3, DEKUBABA_DMGEFF_ICE), + /* Light arrow */ DMG_ENTRY(3, DEKUBABA_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, DEKUBABA_DMGEFF_CUT), + /* Deku bubble */ DMG_ENTRY(3, DEKUBABA_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, DEKUBABA_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NUT), + /* Zora barrier */ DMG_ENTRY(0, DEKUBABA_DMGEFF_ELECTRIC), + /* Normal shield */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, DEKUBABA_DMGEFF_CUT), + /* Sword beam */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DEKUBABA_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DEKUBABA_DMGEFF_NONE), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808B4E94[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 1500, ICHAIN_STOP), }; -#endif +void EnDekubaba_Init(Actor* thisx, PlayState* play) { + EnDekubaba* this = THIS; + s32 i; -extern ColliderJntSphElementInit D_808B4D60[7]; -extern ColliderJntSphInit D_808B4E5C; -extern CollisionCheckInfoInit D_808B4E6C; -extern DamageTable D_808B4E74; -extern InitChainEntry D_808B4E94[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 22.0f); + SkelAnime_Init(play, &this->skelAnime, &gDekuBabaSkel, &gDekuBabaFastChompAnim, this->jointTable, this->morphTable, + DEKUBABA_LIMB_MAX); + Collider_InitAndSetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -extern UNK_TYPE D_06000208; -extern UNK_TYPE D_060002B8; -extern UNK_TYPE D_060010F0; -extern UNK_TYPE D_06001330; -extern UNK_TYPE D_06001828; + if (this->actor.params == DEKUBABA_BIG) { + this->size = 2.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/EnDekubaba_Init.s") + for (i = 0; i < sJntSphInit.count; i++) { + this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius = + (sJntSphElementsInit[i].dim.modelSphere.radius * 2.50f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/EnDekubaba_Destroy.s") + this->actor.colChkInfo.health = 4; + // Big Deku Baba hint does not exist in MM + this->actor.hintId = TATL_HINT_ID_BIO_DEKU_BABA; + this->actor.targetMode = 2; + } else { + this->size = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1530.s") + for (i = 0; i < sJntSphInit.count; i++) { + this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; + } + this->actor.hintId = TATL_HINT_ID_DEKU_BABA; + this->actor.targetMode = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B15B8.s") + EnDekubaba_SetupWait(this); + this->timer = 0; + this->boundFloor = NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B16BC.s") +void EnDekubaba_Destroy(Actor* thisx, PlayState* play) { + EnDekubaba* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1798.s") + Collider_DestroyJntSph(play, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1814.s") +void EnDekubaba_DisableHitboxes(EnDekubaba* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B18A8.s") + for (i = 1; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].info.bumperFlags &= ~BUMP_ON; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1B14.s") +void EnDekubaba_UpdateHeadPosition(EnDekubaba* this) { + f32 horizontalHeadShift = (Math_CosS(this->stemSectionAngle[0]) + Math_CosS(this->stemSectionAngle[1]) + + Math_CosS(this->stemSectionAngle[2])) * + 20.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1BC0.s") + this->actor.world.pos.x = + this->actor.home.pos.x + Math_SinS(this->actor.shape.rot.y) * (horizontalHeadShift * this->size); + this->actor.world.pos.y = + this->actor.home.pos.y - (Math_SinS(this->stemSectionAngle[0]) + Math_SinS(this->stemSectionAngle[1]) + + Math_SinS(this->stemSectionAngle[2])) * + 20.0f * this->size; + this->actor.world.pos.z = + this->actor.home.pos.z + Math_CosS(this->actor.shape.rot.y) * (horizontalHeadShift * this->size); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B1CF0.s") +void EnDekubaba_SetFireLightEffects(EnDekubaba* this, PlayState* play, s32 index) { + ColliderJntSphElement* sphElement; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2158.s") + if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_FIRE) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_LIGHT) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; + sphElement = &this->collider.elements[index]; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, sphElement->info.bumper.hitPos.x, + sphElement->info.bumper.hitPos.y, sphElement->info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_SMALL_LIGHT_RAYS); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2240.s") +void EnDekubaba_SetFrozenEffects(EnDekubaba* this) { + this->drawDmgEffScale = 0.75f; + this->drawDmgEffFrozenSteamScale = 1.125f; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->collider.base.colType = COLTYPE_HIT3; + this->timer = 80; + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2608.s") +void EnDekubaba_SpawnIceEffects(EnDekubaba* this, PlayState* play) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider.base.colType = COLTYPE_HIT6; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), 4, + this->size * 0.3f, this->size * 0.2f); + this->actor.flags |= ACTOR_FLAG_400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2660.s") +void EnDekubaba_SetupWait(EnDekubaba* this) { + s32 i; + ColliderJntSphElement* element; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2890.s") + this->actor.shape.rot.x = -0x4000; + this->stemSectionAngle[0] = this->stemSectionAngle[1] = this->stemSectionAngle[2] = this->actor.shape.rot.x; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B28B4.s") + this->actor.world.pos.x = this->actor.home.pos.x; + this->actor.world.pos.z = this->actor.home.pos.z; + this->actor.world.pos.y = this->actor.home.pos.y + 14.0f * this->size; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2980.s") + Actor_SetScale(&this->actor, this->size * 0.01f * 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B29C4.s") + this->collider.base.colType = COLTYPE_HARD; + this->collider.base.acFlags |= AC_HARD; + this->timer = 45; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2C40.s") + for (i = 1; i < ARRAY_COUNT(this->colliderElements); i++) { + element = &this->collider.elements[i]; + element->dim.worldSphere.center.x = this->actor.world.pos.x; + element->dim.worldSphere.center.y = (s32)this->actor.world.pos.y - 7; + element->dim.worldSphere.center.z = this->actor.world.pos.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B2CB8.s") + this->actionFunc = EnDekubaba_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3044.s") +void EnDekubaba_Wait(EnDekubaba* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3078.s") + this->actor.world.pos.x = this->actor.home.pos.x; + this->actor.world.pos.z = this->actor.home.pos.z; + this->actor.world.pos.y = this->actor.home.pos.y + 14.0f * this->size; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3170.s") + if ((this->timer == 0) && (this->actor.xzDistToPlayer < 200.0f * this->size) && + (fabsf(this->actor.playerHeightRel) < 30.0f * this->size)) { + EnDekubaba_SetupGrow(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3280.s") +void EnDekubaba_SetupGrow(EnDekubaba* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3390.s") + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, + Animation_GetLastFrame(&gDekuBabaFastChompAnim) * (1.0f / 15), 0.0f, + Animation_GetLastFrame(&gDekuBabaFastChompAnim), ANIMMODE_ONCE, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3404.s") + this->timer = 15; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3768.s") + for (i = 2; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].info.ocElemFlags |= OCELEM_ON; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B37E8.s") + this->collider.base.colType = COLTYPE_HIT6; + this->collider.base.acFlags &= ~AC_HARD; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_WAKEUP); + this->actionFunc = EnDekubaba_Grow; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B39AC.s") +void EnDekubaba_Grow(EnDekubaba* this, PlayState* play) { + Player* player = GET_PLAYER(play); + f32 headDistHorizontal; + f32 headDistVertical; + f32 headShiftX; + f32 headShiftZ; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3B48.s") + if (this->timer != 0) { + this->timer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3BE4.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3C50.s") + this->actor.scale.x = this->actor.scale.y = this->actor.scale.z = + this->size * 0.01f * (0.5f + (15 - this->timer) * 0.5f / 15.0f); + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x1800, 0x800); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3D74.s") + headDistVertical = sin_rad(CLAMP_MAX((15 - this->timer) * (1.0f / 15), 0.7f) * M_PI) * 32.0f + 14.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3DA8.s") + if (this->actor.shape.rot.x < -0x38E3) { + headDistHorizontal = 0.0f; + } else if (this->actor.shape.rot.x < -0x238E) { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0x5555, 0x38E); + headDistHorizontal = Math_CosS(this->stemSectionAngle[0]) * 20.0f; + } else if (this->actor.shape.rot.x < -0xE38) { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0xAAA, 0x38E); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x5555, 0x38E); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5555, 0x222); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3E40.s") + headDistHorizontal = 20.0f * (Math_CosS(this->stemSectionAngle[0]) + Math_CosS(this->stemSectionAngle[1])) + + (headDistVertical - + 20.0f * (-Math_SinS(this->stemSectionAngle[0]) - Math_SinS(this->stemSectionAngle[1]))) * + Math_CosS(this->stemSectionAngle[2]) / -Math_SinS(this->stemSectionAngle[2]); + } else { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0xAAA, 0x38E); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x31C7, 0x222); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5555, 0x222); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3EE8.s") + headDistHorizontal = 20.0f * (Math_CosS(this->stemSectionAngle[0]) + Math_CosS(this->stemSectionAngle[1])) + + (headDistVertical - + 20.0f * (-Math_SinS(this->stemSectionAngle[0]) - Math_SinS(this->stemSectionAngle[1]))) * + Math_CosS(this->stemSectionAngle[2]) / -Math_SinS(this->stemSectionAngle[2]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B3F50.s") + if (this->timer < 10) { + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos), 2, + 0xE38); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/EnDekubaba_Update.s") + this->actor.world.pos.y = this->actor.home.pos.y + (headDistVertical * this->size); + //! FAKE: + headShiftX = headDistHorizontal; + headShiftX = headShiftX * this->size * Math_SinS(this->actor.shape.rot.y); + headShiftZ = headDistHorizontal; + headShiftZ = headShiftZ * this->size * Math_CosS(this->actor.shape.rot.y); + this->actor.world.pos.x = this->actor.home.pos.x + headShiftX; + this->actor.world.pos.z = this->actor.home.pos.z + headShiftZ; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B4548.s") + EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, this->size * 3.0f, 0, this->size * 12.0f, this->size * 5.0f, + 1, HAHEN_OBJECT_DEFAULT, 10, NULL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B465C.s") + if (this->timer == 0) { + if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 240.0f * this->size) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupRetract(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B48FC.s") +void EnDekubaba_SetupRetract(EnDekubaba* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B49C8.s") + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, -1.5f, Animation_GetLastFrame(&gDekuBabaFastChompAnim), + 0.0f, ANIMMODE_ONCE, -3.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/func_808B4ABC.s") + this->timer = 15; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dekubaba/EnDekubaba_Draw.s") + for (i = 2; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].info.ocElemFlags &= ~OCELEM_ON; + } + + this->actionFunc = EnDekubaba_Retract; +} + +void EnDekubaba_Retract(EnDekubaba* this, PlayState* play) { + f32 headDistHorizontal; + f32 headDistVertical; + f32 xShift; + f32 zShift; + + if (this->timer != 0) { + this->timer--; + } + + SkelAnime_Update(&this->skelAnime); + + this->actor.scale.x = this->actor.scale.y = this->actor.scale.z = + this->size * 0.01f * (0.5f + this->timer * (1.0f / 30)); + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x4000, 0x300); + + headDistVertical = (sin_rad(CLAMP_MAX(this->timer * 0.033f, 0.7f) * M_PI) * 32.0f) + 14.0f; + + if (this->actor.shape.rot.x < -0x38E3) { + headDistHorizontal = 0.0f; + } else if (this->actor.shape.rot.x < -0x238E) { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0x4000, 0x555); + headDistHorizontal = Math_CosS(this->stemSectionAngle[0]) * 20.0f; + } else if (this->actor.shape.rot.x < -0xE38) { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0x5555, 0x555); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x4000, 0x555); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x4000, 0x333); + + headDistHorizontal = 20.0f * (Math_CosS(this->stemSectionAngle[0]) + Math_CosS(this->stemSectionAngle[1])) + + (headDistVertical - + 20.0f * (-Math_SinS(this->stemSectionAngle[0]) - Math_SinS(this->stemSectionAngle[1]))) * + Math_CosS(this->stemSectionAngle[2]) / -Math_SinS(this->stemSectionAngle[2]); + } else { + Math_ScaledStepToS(&this->stemSectionAngle[0], -0x5555, 0x555); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x5555, 0x333); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x4000, 0x333); + + headDistHorizontal = 20.0f * (Math_CosS(this->stemSectionAngle[0]) + Math_CosS(this->stemSectionAngle[1])) + + (headDistVertical - + 20.0f * (-Math_SinS(this->stemSectionAngle[0]) - Math_SinS(this->stemSectionAngle[1]))) * + Math_CosS(this->stemSectionAngle[2]) / -Math_SinS(this->stemSectionAngle[2]); + } + + this->actor.world.pos.y = this->actor.home.pos.y + (headDistVertical * this->size); + xShift = headDistHorizontal * this->size * Math_SinS(this->actor.shape.rot.y); + zShift = headDistHorizontal * this->size * Math_CosS(this->actor.shape.rot.y); + this->actor.world.pos.x = this->actor.home.pos.x + xShift; + this->actor.world.pos.z = this->actor.home.pos.z + zShift; + + EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, this->size * 3.0f, 0, this->size * 12.0f, this->size * 5.0f, + 1, HAHEN_OBJECT_DEFAULT, 10, NULL); + if (this->timer == 0) { + EnDekubaba_SetupWait(this); + } +} + +void EnDekubaba_SetupDecideLunge(EnDekubaba* this) { + this->timer = Animation_GetLastFrame(&gDekuBabaFastChompAnim) * 2; + Animation_MorphToLoop(&this->skelAnime, &gDekuBabaFastChompAnim, -3.0f); + this->actionFunc = EnDekubaba_DecideLunge; +} + +void EnDekubaba_DecideLunge(EnDekubaba* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f)) { + if (this->actor.params == DEKUBABA_BIG) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_MOUTH); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + } + + if (this->timer != 0) { + this->timer--; + } + + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos), 2, + (this->timer % 5) * 0x222); + + if (this->timer < 10) { + this->stemSectionAngle[0] += 0x16C; + this->stemSectionAngle[1] += 0x16C; + this->stemSectionAngle[2] += 0xB6; + this->actor.shape.rot.x += 0x222; + } else if (this->timer < 20) { + this->stemSectionAngle[0] -= 0x16C; + this->stemSectionAngle[1] += 0x111; + this->actor.shape.rot.x += 0x16C; + } else if (this->timer < 30) { + this->stemSectionAngle[1] -= 0x111; + this->actor.shape.rot.x -= 0xB6; + } else { + this->stemSectionAngle[1] -= 0xB6; + this->stemSectionAngle[2] += 0xB6; + this->actor.shape.rot.x -= 0x16C; + } + + EnDekubaba_UpdateHeadPosition(this); + + if ((240.0f * this->size) < Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos)) { + EnDekubaba_SetupRetract(this); + } else if ((this->timer == 0) || (this->actor.xzDistToPlayer < (80.0f * this->size))) { + EnDekubaba_SetupPrepareLunge(this); + } +} + +void EnDekubaba_SetupPrepareLunge(EnDekubaba* this) { + this->timer = 8; + this->skelAnime.playSpeed = 0.0f; + this->actionFunc = EnDekubaba_PrepareLunge; +} + +void EnDekubaba_PrepareLunge(EnDekubaba* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (this->timer != 0) { + this->timer--; + } + + Math_SmoothStepToS(&this->actor.shape.rot.x, 0x1800, 2, 0xE38, 0x71C); + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos), 2, 0xE38); + Math_ScaledStepToS(this->stemSectionAngle, 0xAAA, 0x444); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x4718, 0x888); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x6AA4, 0x888); + + if (this->timer == 0) { + EnDekubaba_SetupLunge(this); + } + + EnDekubaba_UpdateHeadPosition(this); +} + +void EnDekubaba_SetupLunge(EnDekubaba* this) { + Animation_PlayOnce(&this->skelAnime, &gDekuBabaPauseChompAnim); + this->timer = 0; + this->actionFunc = EnDekubaba_Lunge; +} + +void EnDekubaba_Lunge(EnDekubaba* this, PlayState* play) { + static Color_RGBA8 sDustPrimColor = { 105, 255, 105, 255 }; + static Color_RGBA8 sDustEnvColor = { 150, 250, 150, 0 }; + s32 allStepsDone; + s16 curFrame10; + Vec3f velocity; + + SkelAnime_Update(&this->skelAnime); + + if (this->timer == 0) { + if (Animation_OnFrame(&this->skelAnime, 1.0f)) { + if (this->actor.params == DEKUBABA_BIG) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_ATTACK); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_ATTACK); + } + } + + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x222); + + curFrame10 = (s32)(this->skelAnime.curFrame * 10.0f); + + allStepsDone = true; + allStepsDone &= Math_ScaledStepToS(&this->stemSectionAngle[0], -0xE38, curFrame10 + 0x38E); + allStepsDone &= Math_ScaledStepToS(&this->stemSectionAngle[1], -0xE38, curFrame10 + 0x71C); + allStepsDone &= Math_ScaledStepToS(&this->stemSectionAngle[2], -0xE38, curFrame10 + 0xE38); + if (allStepsDone) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gDekuBabaFastChompAnim, 4.0f); + velocity.x = Math_SinS(this->actor.shape.rot.y) * 5.0f; + velocity.y = 0.0f; + velocity.z = Math_CosS(this->actor.shape.rot.y) * 5.0f; + func_800B0DE0(play, &this->actor.world.pos, &velocity, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, 1, + (s32)(this->size * 100.0f)); + this->timer = 1; + } + } else if (this->timer > 10) { + EnDekubaba_SetupPullBack(this); + } else { + this->timer++; + + if ((this->timer >= 4) && !Actor_IsFacingPlayer(&this->actor, 0x16C)) { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xF, 0x71C); + } + + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f)) { + if (this->actor.params == DEKUBABA_BIG) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_MOUTH); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + } + } + + EnDekubaba_UpdateHeadPosition(this); +} + +void EnDekubaba_SetupPullBack(EnDekubaba* this) { + Animation_Change(&this->skelAnime, &gDekuBabaPauseChompAnim, 1.0f, 15.0f, + Animation_GetLastFrame(&gDekuBabaPauseChompAnim), ANIMMODE_ONCE, -3.0f); + this->timer = 0; + this->actionFunc = EnDekubaba_PullBack; +} + +void EnDekubaba_PullBack(EnDekubaba* this, PlayState* play) { + Vec3f dustPos; + f32 xIncr; + f32 zIncr; + s32 i; + + SkelAnime_Update(&this->skelAnime); + + if (this->timer == 0) { + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x93E, 0x38E); + Math_ScaledStepToS(&this->stemSectionAngle[0], -0x888, 0x16C); + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x888, 0x16C); + + if (Math_ScaledStepToS(&this->stemSectionAngle[2], -0x888, 0x16C)) { + xIncr = Math_SinS(this->actor.shape.rot.y) * 30.0f * this->size; + zIncr = Math_CosS(this->actor.shape.rot.y) * 30.0f * this->size; + dustPos = this->actor.home.pos; + + for (i = 0; i < 3; i++) { + func_800B1210(play, &dustPos, &gZeroVec3f, &gZeroVec3f, (s32)(this->size * 500.0f), + (s32)(this->size * 50.0f)); + dustPos.x += xIncr; + dustPos.z += zIncr; + } + + this->timer = 1; + } + } else if (this->timer == 11) { + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x93E, 0x200); + Math_ScaledStepToS(this->stemSectionAngle, -0xAAA, 0x200); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5C71, 0x200); + + if (Math_ScaledStepToS(&this->stemSectionAngle[1], 0x238C, 0x200)) { + this->timer = 12; + } + } else if (this->timer == 18) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x2AA8, 0xAAA); + + if (Math_ScaledStepToS(&this->stemSectionAngle[0], 0x1554, 0x5B0)) { + this->timer = 25; + } + + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x38E3, 0xAAA); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5C71, 0x2D8); + } else if (this->timer == 25) { + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x5550, 0xAAA); + + if (Math_ScaledStepToS(&this->stemSectionAngle[0], -0x6388, 0x93E)) { + this->timer = 26; + } + + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x3FFC, 0x4FA); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x238C, 0x444); + } else if (this->timer == 26) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x1800, 0x93E); + + if (Math_ScaledStepToS(&this->stemSectionAngle[0], -0x1555, 0x71C)) { + this->timer = 27; + } + + Math_ScaledStepToS(&this->stemSectionAngle[1], -0x38E3, 0x2D8); + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5C71, 0x5B0); + } else if (this->timer >= 27) { + this->timer++; + if (this->timer > 30) { + if (this->actor.xzDistToPlayer < (80.0f * this->size)) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupDecideLunge(this); + } + } + } else { + this->timer++; + if (this->timer == 10) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_SCRAPE); + } + + if (this->timer >= 12) { + Math_ScaledStepToS(&this->stemSectionAngle[2], -0x5C71, 0x88); + } + } + + EnDekubaba_UpdateHeadPosition(this); +} + +void EnDekubaba_SetupRecover(EnDekubaba* this) { + this->timer = 9; + this->collider.base.acFlags |= AC_ON; + this->skelAnime.playSpeed = -1.0f; + this->actionFunc = EnDekubaba_Recover; +} + +void EnDekubaba_Recover(EnDekubaba* this, PlayState* play) { + s32 anyStepsDone; + + SkelAnime_Update(&this->skelAnime); + + if (this->timer > 8) { + anyStepsDone = Math_SmoothStepToS(&this->actor.shape.rot.x, 0x1800, 1, 0x11C6, 0x71C); + anyStepsDone |= Math_SmoothStepToS(&this->stemSectionAngle[0], -0x1555, 1, 0xAAA, 0x71C); + anyStepsDone |= Math_SmoothStepToS(&this->stemSectionAngle[1], -0x38E3, 1, 0xE38, 0x71C); + anyStepsDone |= Math_SmoothStepToS(&this->stemSectionAngle[2], -0x5C71, 1, 0x11C6, 0x71C); + if (!anyStepsDone) { + this->timer = 8; + } + } else { + if (this->timer != 0) { + this->timer--; + } + + if (this->timer == 0) { + EnDekubaba_SetupDecideLunge(this); + } + } + + EnDekubaba_UpdateHeadPosition(this); +} + +typedef enum { + /* 0 */ DEKUBABA_HIT_NO_STUN, + /* 1 */ DEKUBABA_HIT_STUN_OTHER, + /* 2 */ DEKUBABA_HIT_STUN_NUT, + /* 3 */ DEKUBABA_HIT_STUN_ELECTRIC +} DekuBabaHitType; + +void EnDekubaba_SetupHit(EnDekubaba* this, s32 hitType) { + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuBabaPauseChompAnim, -5.0f); + this->timer = hitType; + this->collider.base.acFlags &= ~AC_ON; + Actor_SetScale(&this->actor, this->size * 0.01f); + + if (hitType == DEKUBABA_HIT_STUN_NUT) { + Actor_SetColorFilter(&this->actor, 0, 155, 0, 42); + } else if (hitType == DEKUBABA_HIT_STUN_ELECTRIC) { + Actor_SetColorFilter(&this->actor, 0, 155, 0, 42); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 2.0f; + } else { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 42); + } + this->actionFunc = EnDekubaba_Hit; +} + +/** + * Hit by a weapon or hit something when lunging. + */ +void EnDekubaba_Hit(EnDekubaba* this, PlayState* play) { + s32 allStepsDone; + + SkelAnime_Update(&this->skelAnime); + allStepsDone = true; + allStepsDone &= Math_ScaledStepToS(&this->actor.shape.rot.x, -0x4000, 0xE38); + allStepsDone &= Math_ScaledStepToS(this->stemSectionAngle, -0x4000, 0xE38); + allStepsDone &= Math_ScaledStepToS(&this->stemSectionAngle[1], -0x4000, 0xE38); + allStepsDone &= Math_ScaledStepToS(&this->stemSectionAngle[2], -0x4000, 0xE38); + if (allStepsDone) { + if (this->actor.colChkInfo.health == 0) { + EnDekubaba_SetupShrinkDie(this); + } else { + this->collider.base.acFlags |= AC_ON; + + if (this->timer == DEKUBABA_HIT_NO_STUN) { + if (this->actor.xzDistToPlayer < (80.0f * this->size)) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupRecover(this); + } + } else { + EnDekubaba_SetupStunnedVertical(this); + } + } + } + + EnDekubaba_UpdateHeadPosition(this); +} + +void EnDekubaba_SetupPrunedSomersaultDie(EnDekubaba* this) { + this->timer = 0; + this->skelAnime.playSpeed = 0.0f; + this->actor.gravity = -0.8f; + this->actor.velocity.y = 4.0f; + this->actor.world.rot.y = this->actor.shape.rot.y + 0x8000; + this->actor.speedXZ = this->size * 3.0f; + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= ACTOR_FLAG_10 | ACTOR_FLAG_20; + this->actionFunc = EnDekubaba_PrunedSomersaultDie; +} + +void EnDekubaba_PrunedSomersaultDie(EnDekubaba* this, PlayState* play) { + s32 i; + Vec3f dustPos; + f32 deltaX; + f32 deltaY; + f32 deltaZ; + + Math_StepToF(&this->actor.speedXZ, 0.0f, this->size * 0.1f); + + if (this->timer == 0) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4800, 0x71C); + Math_ScaledStepToS(this->stemSectionAngle, 0x4800, 0x71C); + Math_ScaledStepToS(&this->stemSectionAngle[1], 0x4800, 0x71C); + + EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, this->size * 3.0f, 0, (s32)(this->size * 12.0f), + (s32)(this->size * 5.0f), 1, HAHEN_OBJECT_DEFAULT, 10, NULL); + + if ((this->actor.scale.x > 0.005f) && ((this->actor.bgCheckFlags & 2) || (this->actor.bgCheckFlags & 8))) { + this->actor.scale.z = 0.0f; + this->actor.scale.y = 0.0f; + this->actor.scale.x = 0.0f; + this->actor.speedXZ = 0.0f; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, this->size * 3.0f, 0, (s32)(this->size * 12.0f), + (s32)(this->size * 5.0f), 15, HAHEN_OBJECT_DEFAULT, 10, NULL); + } + + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + this->timer = 1; + } + } else if (this->timer == 1) { + dustPos = this->actor.world.pos; + + deltaY = 20.0f * Math_SinS(this->actor.shape.rot.x); + deltaX = -20.0f * Math_CosS(this->actor.shape.rot.x) * Math_SinS(this->actor.shape.rot.y); + deltaZ = -20.0f * Math_CosS(this->actor.shape.rot.x) * Math_CosS(this->actor.shape.rot.y); + + for (i = 0; i < 4; i++) { + func_800B1210(play, &dustPos, &gZeroVec3f, &gZeroVec3f, 500, 50); + dustPos.x += deltaX; + dustPos.y += deltaY; + dustPos.z += deltaZ; + } + + func_800B1210(play, &this->actor.home.pos, &gZeroVec3f, &gZeroVec3f, (s32)(this->size * 500.0f), + (s32)(this->size * 100.0f)); + EnDekubaba_SetupDeadStickDrop(this, play); + } +} + +void EnDekubaba_SetupShrinkDie(EnDekubaba* this) { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, -1.5f, Animation_GetLastFrame(&gDekuBabaFastChompAnim), + 0.0f, ANIMMODE_ONCE, -3.0f); + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = EnDekubaba_ShrinkDie; +} + +/** + * Die and drop Deku Nuts (Deku Stick drop is handled elsewhere). + */ +void EnDekubaba_ShrinkDie(EnDekubaba* this, PlayState* play) { + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, this->size * 5.0f); + + if (Math_StepToF(&this->actor.scale.x, this->size * 0.1f * 0.01f, this->size * 0.1f * 0.01f)) { + func_800B1210(play, &this->actor.home.pos, &gZeroVec3f, &gZeroVec3f, (s32)(this->size * 500.0f), + (s32)(this->size * 100.0f)); + + if (!this->actor.dropFlag) { + Item_DropCollectible(play, &this->actor.world.pos, ITEM00_NUTS_1); + if (this->actor.params == DEKUBABA_BIG) { + Item_DropCollectible(play, &this->actor.world.pos, ITEM00_NUTS_1); + Item_DropCollectible(play, &this->actor.world.pos, ITEM00_NUTS_1); + } + } else { + Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0x30); + } + Actor_Kill(&this->actor); + } + + this->actor.scale.y = this->actor.scale.z = this->actor.scale.x; + this->actor.shape.rot.z += 0x1C70; + EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, this->size * 3.0f, 0, (s32)(this->size * 12.0f), + (s32)(this->size * 5.0f), 1, HAHEN_OBJECT_DEFAULT, 10, NULL); +} + +void EnDekubaba_SetupStunnedVertical(EnDekubaba* this) { + s32 i; + + for (i = 1; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].info.bumperFlags |= BUMP_ON; + } + + if (this->timer == 1) { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, 4.0f, 0.0f, + Animation_GetLastFrame(&gDekuBabaFastChompAnim), ANIMMODE_LOOP, -3.0f); + this->timer = 0x28; + } else { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, 0.0f, 0.0f, + Animation_GetLastFrame(&gDekuBabaFastChompAnim), ANIMMODE_LOOP, -3.0f); + if (this->timer == 2) { + this->timer = 40; + } else { + this->timer = 40; + } + } + + this->actor.world.pos.x = this->actor.home.pos.x; + this->actor.world.pos.y = this->actor.home.pos.y + (60.0f * this->size); + this->actor.world.pos.z = this->actor.home.pos.z; + this->actionFunc = EnDekubaba_StunnedVertical; +} + +void EnDekubaba_StunnedVertical(EnDekubaba* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + + if (this->timer != 0) { + this->timer--; + } + + if (this->timer == 0) { + EnDekubaba_DisableHitboxes(this); + + if (this->actor.xzDistToPlayer < (80.0f * this->size)) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupRecover(this); + } + } +} + +void EnDekubaba_SetupSway(EnDekubaba* this) { + this->targetSwayAngle = -0x6000; + this->stemSectionAngle[2] = -0x5000; + this->stemSectionAngle[1] = -0x4800; + EnDekubaba_DisableHitboxes(this); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 35); + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = EnDekubaba_Sway; +} + +/** + * Sway back and forth with decaying amplitude until close enough to vertical. + */ +void EnDekubaba_Sway(EnDekubaba* this, PlayState* play) { + s16 angleToVertical; + + SkelAnime_Update(&this->skelAnime); + Math_ScaledStepToS(&this->actor.shape.rot.x, this->stemSectionAngle[0], 0x71C); + Math_ScaledStepToS(this->stemSectionAngle, this->stemSectionAngle[1], 0x71C); + Math_ScaledStepToS(&this->stemSectionAngle[1], this->stemSectionAngle[2], 0x71C); + if (Math_ScaledStepToS(&this->stemSectionAngle[2], this->targetSwayAngle, 0x71C) != 0) { + this->targetSwayAngle = -0x4000 - (s32)((this->targetSwayAngle + 0x4000) * 0.8f); + } + + angleToVertical = this->targetSwayAngle + 0x4000; + + if (ABS_ALT(angleToVertical) < 0x100) { + this->collider.base.acFlags |= AC_ON; + if (this->actor.xzDistToPlayer < (80.0f * this->size)) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupRecover(this); + } + } + EnDekubaba_UpdateHeadPosition(this); +} + +void EnDekubaba_SetupFrozen(EnDekubaba* this) { + EnDekubaba_SetFrozenEffects(this); + this->actionFunc = EnDekubaba_Frozen; +} + +void EnDekubaba_Frozen(EnDekubaba* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; + } + if (this->timer == 0) { + EnDekubaba_SpawnIceEffects(this, play); + + if (this->actor.colChkInfo.health == 0) { + EnDekubaba_SetupShrinkDie(this); + } else if (this->actor.xzDistToPlayer < (80.0f * this->size)) { + EnDekubaba_SetupPrepareLunge(this); + } else { + EnDekubaba_SetupRecover(this); + } + } +} + +void EnDekubaba_SetupDeadStickDrop(EnDekubaba* this, PlayState* play) { + Actor_SetScale(&this->actor, 0.03f); + this->actor.shape.rot.x -= 0x4000; + this->actor.shape.yOffset = 1000.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.shape.shadowScale = 3.0f; + func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_MISC); + this->actor.flags &= ~ACTOR_FLAG_20; + this->timer = 200; + this->drawDmgEffAlpha = 0.0f; + this->actionFunc = EnDekubaba_DeadStickDrop; +} + +void EnDekubaba_DeadStickDrop(EnDekubaba* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; + } + + if (Actor_HasParent(&this->actor, play) || (this->timer == 0)) { + Actor_Kill(&this->actor); + return; + } + + Actor_PickUpNearby(&this->actor, play, GI_STICKS_1); +} + +/* Update and associated functions */ + +void EnDekubaba_UpdateDamage(EnDekubaba* this, PlayState* play) { + s32 newHealth; + s32 i; + ColliderJntSphElement* sphElement; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlagJntSph(&this->actor, &this->collider); + + if ((this->collider.base.colType != COLTYPE_HARD) && + (this->actor.colChkInfo.damageEffect != DEKUBABA_DMGEFF_HOOKSHOT)) { + sphElement = &this->collider.elements[0]; + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++, sphElement++) { + if (sphElement->info.bumperFlags & BUMP_HIT) { + break; + } + } + + if ((i != ARRAY_COUNT(this->colliderElements)) && + ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + (!(sphElement->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)))) { + EnDekubaba_SpawnIceEffects(this, play); + newHealth = this->actor.colChkInfo.health - this->actor.colChkInfo.damage; + + if (this->actionFunc != EnDekubaba_StunnedVertical) { + if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_ICE) { + EnDekubaba_SetupFrozen(this); + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_ELECTRIC) { + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_ELECTRIC); + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_NUT) { + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_NUT); + } else { + EnDekubaba_SetFireLightEffects(this, play, i); + + if (this->actionFunc == EnDekubaba_PullBack) { + if (newHealth <= 0) { + newHealth = 1; + } + + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_OTHER); + } else { + EnDekubaba_SetupHit(this, DEKUBABA_HIT_NO_STUN); + } + } + } else { + if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_CUT) { + if (newHealth > 0) { + EnDekubaba_SetupSway(this); + } else { + EnDekubaba_SetupPrunedSomersaultDie(this); + } + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_ELECTRIC) { + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_ELECTRIC); + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_NUT) { + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_NUT); + } else if (this->actor.colChkInfo.damageEffect == DEKUBABA_DMGEFF_ICE) { + EnDekubaba_SetupFrozen(this); + } else { + EnDekubaba_SetFireLightEffects(this, play, i); + EnDekubaba_SetupHit(this, DEKUBABA_HIT_NO_STUN); + } + } + + if (newHealth < 0) { + this->actor.colChkInfo.health = 0; + } else { + this->actor.colChkInfo.health = newHealth; + } + } else { + return; + } + } else { + return; + } + } else if ((play->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < SQ(200.0f)) && + (this->collider.base.colType != COLTYPE_HARD) && (this->actionFunc != EnDekubaba_StunnedVertical) && + (this->actionFunc != EnDekubaba_Hit) && (this->actor.colChkInfo.health != 0)) { + this->actor.colChkInfo.health--; + this->actor.dropFlag = 0; + EnDekubaba_SetupHit(this, DEKUBABA_HIT_STUN_OTHER); + } else { + return; + } + + if (this->actor.colChkInfo.health != 0) { + if ((this->timer == 2) || (this->timer == 3)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_DAMAGE); + } + } else { + Enemy_StartFinishingBlow(play, &this->actor); + + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->timer = 3; + this->collider.base.acFlags &= ~AC_ON; + } else if (this->drawDmgEffAlpha > 1.5f) { + this->drawDmgEffAlpha = 1.5f; + } + + if (this->actor.params == DEKUBABA_BIG) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_DEAD); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_JR_DEAD); + } + } +} + +void EnDekubaba_Update(Actor* thisx, PlayState* play) { + s32 pad; + EnDekubaba* this = THIS; + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + EnDekubaba_SetupRecover(this); + } + + EnDekubaba_UpdateDamage(this, play); + this->actionFunc(this, play); + + if (this->actionFunc == EnDekubaba_PrunedSomersaultDie) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, this->size * 15.0f, 10.0f, 5); + } else if (this->actionFunc != EnDekubaba_DeadStickDrop) { + Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); + if (this->boundFloor == NULL) { + this->boundFloor = this->actor.floorPoly; + } + } + + if (this->actionFunc == EnDekubaba_Lunge) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); + this->actor.flags |= ACTOR_FLAG_1000000; + } + + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); + } + + if (this->actionFunc != EnDekubaba_DeadStickDrop) { + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + } + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.375f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.75f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.75f / 40)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +/* Draw functions */ + +void EnDekubaba_DrawStemRetracted(EnDekubaba* this, PlayState* play) { + f32 horizontalScale; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + horizontalScale = this->size * 0.01f; + + Matrix_Translate(this->actor.home.pos.x, this->actor.home.pos.y + (-6.0f * this->size), this->actor.home.pos.z, + MTXMODE_NEW); + Matrix_RotateZYX(this->stemSectionAngle[0], this->actor.shape.rot.y, 0, MTXMODE_APPLY); + Matrix_Scale(horizontalScale, horizontalScale, horizontalScale, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaStemTopDL); + + for (i = 1; i < ARRAY_COUNT(this->bodyPartsPos); i++) { + Matrix_MultZero(&this->bodyPartsPos[i]); + } + + Actor_SetFocus(&this->actor, 0.0f); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDekubaba_DrawStemExtended(EnDekubaba* this, PlayState* play) { + static Gfx* sStemDLists[] = { gDekuBabaStemTopDL, gDekuBabaStemMiddleDL, gDekuBabaStemBaseDL }; + MtxF mf; + s32 i; + f32 scale; + f32 horizontalStepSize; + s32 stemSections; + + OPEN_DISPS(play->state.gfxCtx); + + if (this->actionFunc == EnDekubaba_PrunedSomersaultDie) { + stemSections = 2; + } else { + stemSections = 3; + } + + scale = this->size * 0.01f; + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Get(&mf); + + for (i = 0; i < stemSections; i++) { + mf.yw += 20.0f * Math_SinS(this->stemSectionAngle[i]) * this->size; + horizontalStepSize = Math_CosS(this->stemSectionAngle[i]) * 20.0f * this->size; + mf.xw -= horizontalStepSize * Math_SinS(this->actor.shape.rot.y); + mf.zw -= horizontalStepSize * Math_CosS(this->actor.shape.rot.y); + + Matrix_Put(&mf); + Matrix_RotateZYX(this->stemSectionAngle[i], this->actor.shape.rot.y, 0, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sStemDLists[i]); + + Collider_UpdateSpheres(51 + 2 * i, &this->collider); + Collider_UpdateSpheres(52 + 2 * i, &this->collider); + + if (i == 0) { + if (this->actionFunc != EnDekubaba_Sway) { + this->actor.focus.pos.x = mf.xw; + this->actor.focus.pos.y = mf.yw; + this->actor.focus.pos.z = mf.zw; + } else { + this->actor.focus.pos.x = this->actor.home.pos.x; + this->actor.focus.pos.y = this->actor.home.pos.y + (40.0f * this->size); + this->actor.focus.pos.z = this->actor.home.pos.z; + } + } + + Matrix_MultZero(&this->bodyPartsPos[i + 1]); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDekubaba_DrawStemBasePruned(EnDekubaba* this, PlayState* play) { + OPEN_DISPS(play->state.gfxCtx); + + Matrix_RotateZYX(this->stemSectionAngle[2], this->actor.shape.rot.y, 0, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaStemBaseDL); + + Collider_UpdateSpheres(55, &this->collider); + Collider_UpdateSpheres(56, &this->collider); + + Matrix_MultZero(&this->bodyPartsPos[3]); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDekubaba_DrawShadow(EnDekubaba* this, PlayState* play) { + MtxF mf; + f32 horizontalScale; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C448(play->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 255); + + func_800C0094(this->boundFloor, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, &mf); + Matrix_Mult(&mf, MTXMODE_NEW); + horizontalScale = this->size * 0.15f; + Matrix_Scale(horizontalScale, 1.0f, horizontalScale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gCircleShadowDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDekubaba_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnDekubaba* this = THIS; + + if (limbIndex == DEKUBABA_LIMB_ROOT) { + Collider_UpdateSpheres(limbIndex, &this->collider); + } +} + +void EnDekubaba_Draw(Actor* thisx, PlayState* play) { + EnDekubaba* this = THIS; + f32 scale; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C28C(play->state.gfxCtx); + Math_Vec3f_Copy(&this->bodyPartsPos[0], &this->actor.world.pos); + + if (this->actionFunc != EnDekubaba_DeadStickDrop) { + SkelAnime_DrawOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, EnDekubaba_PostLimbDraw, + &this->actor); + if (this->actionFunc == EnDekubaba_Wait) { + EnDekubaba_DrawStemRetracted(this, play); + } else { + EnDekubaba_DrawStemExtended(this, play); + } + + scale = this->size * 0.01f; + Matrix_Translate(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.home.rot.y, MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaBaseLeavesDL); + + if (this->actionFunc == EnDekubaba_PrunedSomersaultDie) { + EnDekubaba_DrawStemBasePruned(this, play); + } + if (this->boundFloor != NULL) { + EnDekubaba_DrawShadow(this, play); + } + + // Display solid until 40 frames left, then blink until killed. + } else if ((this->timer > 40) || ((this->timer % 2) != 0)) { + Matrix_Translate(0.0f, 0.0f, 200.0f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaStickDropDL); + } + + CLOSE_DISPS(play->state.gfxCtx); + Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->drawDmgEffScale * this->size, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); +} diff --git a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h index 848f056bf9..b1c7f98bcc 100644 --- a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h +++ b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h @@ -2,16 +2,35 @@ #define Z_EN_DEKUBABA_H #include "global.h" +#include "objects/object_dekubaba/object_dekubaba.h" struct EnDekubaba; typedef void (*EnDekubabaActionFunc)(struct EnDekubaba*, PlayState*); +typedef enum { + /* 0 */ DEKUBABA_NORMAL, + /* 1 */ DEKUBABA_BIG +} DekuBabaType; + typedef struct EnDekubaba { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x44]; + /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnDekubabaActionFunc actionFunc; - /* 0x18C */ char unk_18C[0x290]; + /* 0x18C */ u8 drawDmgEffType; + /* 0x18E */ s16 timer; + /* 0x190 */ s16 targetSwayAngle; + /* 0x192 */ s16 stemSectionAngle[3]; + /* 0x198 */ Vec3s jointTable[DEKUBABA_LIMB_MAX]; + /* 0x1C8 */ Vec3s morphTable[DEKUBABA_LIMB_MAX]; + /* 0x1F8 */ f32 size; + /* 0x1FC */ f32 drawDmgEffAlpha; + /* 0x200 */ f32 drawDmgEffScale; + /* 0x204 */ f32 drawDmgEffFrozenSteamScale; + /* 0x208 */ Vec3f bodyPartsPos[4]; + /* 0x238 */ CollisionPoly* boundFloor; + /* 0x23C */ ColliderJntSph collider; + /* 0x25C */ ColliderJntSphElement colliderElements[7]; } EnDekubaba; // size = 0x41C #endif // Z_EN_DEKUBABA_H diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c index 46ad2c30b7..dd8d513e49 100644 --- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c +++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c @@ -1,13 +1,12 @@ /* * File: z_en_karebaba.c * Overlay: ovl_En_Karebaba - * Description: Wilted Deku Baba + * Description: Wilted Deku Baba and Mini Baba */ #include "z_en_karebaba.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "objects/gameplay_keep/gameplay_keep.h" -#include "objects/object_dekubaba/object_dekubaba.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) @@ -18,27 +17,26 @@ void EnKarebaba_Destroy(Actor* thisx, PlayState* play); void EnKarebaba_Update(Actor* thisx, PlayState* play2); void EnKarebaba_Draw(Actor* thisx, PlayState* play); -void func_808F155C(EnKarebaba* this); -void func_808F15B0(EnKarebaba* this, PlayState* play); -void func_808F1648(EnKarebaba* this); -void func_808F169C(EnKarebaba* this, PlayState* play); -void func_808F16FC(EnKarebaba* this); -void func_808F1778(EnKarebaba* this, PlayState* play); -void func_808F1878(EnKarebaba* this); -void func_808F190C(EnKarebaba* this, PlayState* play); -void func_808F1A3C(EnKarebaba* this); -void func_808F1A58(EnKarebaba* this, PlayState* play); -void func_808F1BF8(EnKarebaba* this); -void func_808F1C84(EnKarebaba* this, PlayState* play); -void func_808F1FAC(EnKarebaba* this); -void func_808F200C(EnKarebaba* this, PlayState* play); -void func_808F20FC(EnKarebaba* this, PlayState* play); -void func_808F21A4(EnKarebaba* this, PlayState* play); -void func_808F220C(EnKarebaba* this); -void func_808F228C(EnKarebaba* this, PlayState* play); -void func_808F238C(EnKarebaba* this); -void func_808F241C(EnKarebaba* this, PlayState* play); -void func_808F254C(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupGrow(EnKarebaba* this); +void EnKarebaba_Grow(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupIdle(EnKarebaba* this); +void EnKarebaba_Idle(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupAwaken(EnKarebaba* this); +void EnKarebaba_Awaken(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupUpright(EnKarebaba* this); +void EnKarebaba_Upright(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupSpin(EnKarebaba* this); +void EnKarebaba_Spin(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupDying(EnKarebaba* this); +void EnKarebaba_Dying(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupShrinkDie(EnKarebaba* this); +void EnKarebaba_ShrinkDie(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupDeadItemDrop(EnKarebaba* this, PlayState* play); +void EnKarebaba_DeadItemDrop(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupRetract(EnKarebaba* this); +void EnKarebaba_Retract(EnKarebaba* this, PlayState* play); +void EnKarebaba_SetupDead(EnKarebaba* this); +void EnKarebaba_Dead(EnKarebaba* this, PlayState* play); ActorInit En_Karebaba_InitVars = { ACTOR_EN_KAREBABA, @@ -52,7 +50,7 @@ ActorInit En_Karebaba_InitVars = { (ActorFunc)EnKarebaba_Draw, }; -static ColliderCylinderInit sCylinderInit1 = { +static ColliderCylinderInit sHurtCylinderInit = { { COLTYPE_HARD, AT_NONE, @@ -72,7 +70,7 @@ static ColliderCylinderInit sCylinderInit1 = { { 7, 25, 0, { 0, 0, 0 } }, }; -static ColliderCylinderInit sCylinderInit2 = { +static ColliderCylinderInit sAttackCylinderInit = { { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, @@ -94,39 +92,47 @@ static ColliderCylinderInit sCylinderInit2 = { static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 80, MASS_HEAVY }; +typedef enum { + /* 0x0 */ KAREBABA_DMGEFF_NONE, + /* 0x2 */ KAREBABA_DMGEFF_FIRE = 2, + /* 0x3 */ KAREBABA_DMGEFF_ICE, + /* 0x4 */ KAREBABA_DMGEFF_LIGHT, + /* 0x5 */ KAREBABA_DMGEFF_ELECTRIC, +} DekuBabaDamageEffect; + static DamageTable sDamageTable = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(3, 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(2, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(2, 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, 0x0), - /* 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, KAREBABA_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(3, KAREBABA_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(2, KAREBABA_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, KAREBABA_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(2, KAREBABA_DMGEFF_ICE), + /* Light arrow */ DMG_ENTRY(2, KAREBABA_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, KAREBABA_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(1, KAREBABA_DMGEFF_ELECTRIC), + /* Normal shield */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, KAREBABA_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, KAREBABA_DMGEFF_NONE), }; static InitChainEntry sInitChain[] = { @@ -134,211 +140,208 @@ static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 1, ICHAIN_STOP), }; -Color_RGBA8 D_808F2E28 = { 0, 0, 0, 0 }; - -Gfx* D_808F2E2C[] = { object_dekubaba_DL_001330, object_dekubaba_DL_001628, object_dekubaba_DL_001828 }; - void EnKarebaba_Init(Actor* thisx, PlayState* play) { EnKarebaba* this = THIS; Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 22.0f); - SkelAnime_Init(play, &this->skelAnime, &object_dekubaba_Skel_002A40, &object_dekubaba_Anim_0002B8, this->jointTable, - this->morphTable, 8); + SkelAnime_Init(play, &this->skelAnime, &gDekuBabaSkel, &gDekuBabaFastChompAnim, this->jointTable, this->morphTable, + DEKUBABA_LIMB_MAX); - Collider_InitAndSetCylinder(play, &this->collider2, &this->actor, &sCylinderInit1); - Collider_UpdateCylinder(&this->actor, &this->collider2); - Collider_InitAndSetCylinder(play, &this->collider1, &this->actor, &sCylinderInit2); - Collider_UpdateCylinder(&this->actor, &this->collider1); + Collider_InitAndSetCylinder(play, &this->hurtCollider, &this->actor, &sHurtCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->hurtCollider); + Collider_InitAndSetCylinder(play, &this->attackCollider, &this->actor, &sAttackCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->attackCollider); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - this->unk_22C = NULL; - if (this->actor.params == ENKAREBABA_2) { + this->boundFloor = NULL; + if (this->actor.params == KAREBABA_MINI) { this->actor.hintId = TATL_HINT_ID_MINI_BABA; } else { this->actor.hintId = TATL_HINT_ID_WILTED_DEKU_BABA; } if (this->actor.params == ENKAREBABA_0) { - func_808F155C(this); + EnKarebaba_SetupGrow(this); } else { - func_808F1648(this); + EnKarebaba_SetupIdle(this); } } void EnKarebaba_Destroy(Actor* thisx, PlayState* play) { EnKarebaba* this = THIS; - Collider_DestroyCylinder(play, &this->collider2); - Collider_DestroyCylinder(play, &this->collider1); + Collider_DestroyCylinder(play, &this->hurtCollider); + Collider_DestroyCylinder(play, &this->attackCollider); } -void func_808F1374(EnKarebaba* this, PlayState* play) { - s32 phi_a3; +void EnKarebaba_SpawnIceEffects(EnKarebaba* this, PlayState* play) { + s32 limbPosCount; if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->drawDmgEffAlpha = 0.0f; - if (this->actor.params == ENKAREBABA_2) { - phi_a3 = 1; + + if (this->actor.params == KAREBABA_MINI) { + limbPosCount = 1; } else { - phi_a3 = 4; + limbPosCount = 4; } - Actor_SpawnIceEffects(play, &this->actor, this->limbPos, phi_a3, 4, 0.3f, 0.2f); + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, limbPosCount, 4, 0.3f, 0.2f); } } -void func_808F13FC(EnKarebaba* this, PlayState* play) { - if (this->actor.colChkInfo.damageEffect == 2) { +void EnKarebaba_SetDamageEffects(EnKarebaba* this, PlayState* play) { + if (this->actor.colChkInfo.damageEffect == KAREBABA_DMGEFF_FIRE) { this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->drawDmgEffScale = 0.75f; this->drawDmgEffAlpha = 3.0f; - } else if (this->actor.colChkInfo.damageEffect == 4) { + } else if (this->actor.colChkInfo.damageEffect == KAREBABA_DMGEFF_LIGHT) { this->drawDmgEffScale = 0.75f; this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; this->drawDmgEffAlpha = 3.0f; - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->collider2.info.bumper.hitPos.x, - this->collider2.info.bumper.hitPos.y, this->collider2.info.bumper.hitPos.z, 0, 0, 0, + + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->hurtCollider.info.bumper.hitPos.x, + this->hurtCollider.info.bumper.hitPos.y, this->hurtCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_SMALL_LIGHT_RAYS); - } else if (this->actor.colChkInfo.damageEffect == 3) { + } else if (this->actor.colChkInfo.damageEffect == KAREBABA_DMGEFF_ICE) { this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; this->drawDmgEffScale = 0.75f; this->drawDmgEffAlpha = 1.0f; this->drawDmgEffFrozenSteamScale = 1.125f; - } else if (this->actor.colChkInfo.damageEffect == 5) { + } else if (this->actor.colChkInfo.damageEffect == KAREBABA_DMGEFF_ELECTRIC) { this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; this->drawDmgEffScale = 0.75f; this->drawDmgEffAlpha = 3.0f; } } -void func_808F152C(EnKarebaba* this) { - this->collider2.dim.radius = 7; - this->collider2.dim.height = 25; - this->collider2.base.colType = COLTYPE_HARD; - this->collider2.base.acFlags |= AC_HARD; - this->collider1.dim.height = 25; +void EnKarebaba_ResetColliders(EnKarebaba* this) { + this->hurtCollider.dim.radius = 7; + this->hurtCollider.dim.height = 25; + this->hurtCollider.base.colType = COLTYPE_HARD; + this->hurtCollider.base.acFlags |= AC_HARD; + this->attackCollider.dim.height = 25; } -void func_808F155C(EnKarebaba* this) { +void EnKarebaba_SetupGrow(EnKarebaba* this) { Actor_SetScale(&this->actor, 0.0f); this->actor.shape.rot.x = -0x4000; - this->unk_1EE = 0; + this->timer = 0; this->actor.world.pos.y = this->actor.home.pos.y + 14.0f; - this->actionFunc = func_808F15B0; + this->actionFunc = EnKarebaba_Grow; } -void func_808F15B0(EnKarebaba* this, PlayState* play) { - f32 sp1C; +void EnKarebaba_Grow(EnKarebaba* this, PlayState* play) { + f32 scale; - this->unk_1EE++; - sp1C = this->unk_1EE * 0.05f; - Actor_SetScale(&this->actor, 0.005f * sp1C); - this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * sp1C); - if (this->unk_1EE == 20) { - func_808F1648(this); + this->timer++; + scale = this->timer * 0.05f; + Actor_SetScale(&this->actor, 0.005f * scale); + this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * scale); + if (this->timer == 20) { + EnKarebaba_SetupIdle(this); } } -void func_808F1648(EnKarebaba* this) { +void EnKarebaba_SetupIdle(EnKarebaba* this) { Actor_SetScale(&this->actor, 0.005f); this->actor.shape.rot.x = -0x4000; this->actor.world.pos.y = this->actor.home.pos.y + 14.0f; - this->actionFunc = func_808F169C; + this->actionFunc = EnKarebaba_Idle; } -void func_808F169C(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Idle(EnKarebaba* this, PlayState* play) { if ((this->actor.xzDistToPlayer < 200.0f) && (fabsf(this->actor.playerHeightRel) < 30.0f)) { - func_808F16FC(this); + EnKarebaba_SetupAwaken(this); } } -void func_808F16FC(EnKarebaba* this) { - Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, 4.0f, 0.0f, - Animation_GetLastFrame(&object_dekubaba_Anim_0002B8), ANIMMODE_LOOP, -3.0f); +void EnKarebaba_SetupAwaken(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, 4.0f, 0.0f, + Animation_GetLastFrame(&gDekuBabaFastChompAnim), ANIMMODE_LOOP, -3.0f); Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_WAKEUP); - this->actionFunc = func_808F1778; + this->actionFunc = EnKarebaba_Awaken; } -void func_808F1778(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Awaken(EnKarebaba* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f) && (this->actor.params == ENKAREBABA_2)) { - func_808F1878(this); + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f) && (this->actor.params == KAREBABA_MINI)) { + EnKarebaba_SetupUpright(this); } - this->actor.scale.z = this->actor.scale.x; - this->actor.scale.y = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.z = this->actor.scale.x; if ((this->actor.params == ENKAREBABA_1) && Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 60.0f, 5.0f)) { - func_808F1878(this); + EnKarebaba_SetupUpright(this); } - this->actor.shape.rot.y += 0x1999; + this->actor.shape.rot.y += 0x10000 / 10; EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, 3.0f, 0, 12, 5, 1, HAHEN_OBJECT_DEFAULT, 10, NULL); } -void func_808F1878(EnKarebaba* this) { - if (this->actionFunc != func_808F1A58) { +void EnKarebaba_SetupUpright(EnKarebaba* this) { + if (this->actionFunc != EnKarebaba_Spin) { Actor_SetScale(&this->actor, 0.01f); - this->collider2.base.colType = COLTYPE_HIT6; - this->collider2.base.acFlags &= ~AC_HARD; - this->collider2.dim.radius = 15; + this->hurtCollider.base.colType = COLTYPE_HIT6; + this->hurtCollider.base.acFlags &= ~AC_HARD; + this->hurtCollider.dim.radius = 15; if (this->actor.params == ENKAREBABA_1) { - this->collider2.dim.height = 80; - this->collider1.dim.height = 80; + this->hurtCollider.dim.height = 80; + this->attackCollider.dim.height = 80; } else { - this->collider2.dim.height = 35; - this->collider1.dim.height = 35; + this->hurtCollider.dim.height = 35; + this->attackCollider.dim.height = 35; } } - this->unk_1EE = 40; - this->actionFunc = func_808F190C; + this->timer = 40; + this->actionFunc = EnKarebaba_Upright; } -void func_808F190C(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Upright(EnKarebaba* this, PlayState* play) { Player* player = GET_PLAYER(play); SkelAnime_Update(&this->skelAnime); - if (this->unk_1EE != 0) { - this->unk_1EE--; + if (this->timer != 0) { + this->timer--; } if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f)) { Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); } - if (this->collider2.base.acFlags & AC_HIT) { - func_808F13FC(this, play); + if (this->hurtCollider.base.acFlags & AC_HIT) { + EnKarebaba_SetDamageEffects(this, play); if (this->actor.params == ENKAREBABA_1) { - func_808F1BF8(this); + EnKarebaba_SetupDying(this); } else { - func_808F1FAC(this); + EnKarebaba_SetupShrinkDie(this); } Enemy_StartFinishingBlow(play, &this->actor); } else if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) > 240.0f) { - func_808F220C(this); - } else if ((this->unk_1EE == 0) && (this->actor.params == ENKAREBABA_1)) { - func_808F1A3C(this); + EnKarebaba_SetupRetract(this); + } else if ((this->timer == 0) && (this->actor.params == ENKAREBABA_1)) { + EnKarebaba_SetupSpin(this); } } -void func_808F1A3C(EnKarebaba* this) { - this->unk_1EE = 40; - this->actionFunc = func_808F1A58; +void EnKarebaba_SetupSpin(EnKarebaba* this) { + this->timer = 40; + this->actionFunc = EnKarebaba_Spin; } -void func_808F1A58(EnKarebaba* this, PlayState* play) { - s32 phi_v0; - f32 sp28; +void EnKarebaba_Spin(EnKarebaba* this, PlayState* play) { + s32 temp; // Used for cylinder radius and shape rotations + f32 headDistHorizontal; - if (this->unk_1EE != 0) { - this->unk_1EE--; + if (this->timer != 0) { + this->timer--; } SkelAnime_Update(&this->skelAnime); @@ -347,66 +350,66 @@ void func_808F1A58(EnKarebaba* this, PlayState* play) { Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); } - phi_v0 = 20 - this->unk_1EE; - phi_v0 = 20 - ABS_ALT(phi_v0); - if (phi_v0 > 10) { - phi_v0 = 10; + temp = 20 - this->timer; + temp = 20 - ABS_ALT(temp); + if (temp > 10) { + temp = 10; } - this->collider1.dim.radius = sCylinderInit2.dim.radius + (phi_v0 * 2); - this->actor.shape.rot.x = 0xC000 - (phi_v0 << 8); - this->actor.shape.rot.y += phi_v0 * 0x2C0; + this->attackCollider.dim.radius = sAttackCylinderInit.dim.radius + (temp * 2); + this->actor.shape.rot.x = 0xC000 - temp * 0x100; + this->actor.shape.rot.y += temp * 0x2C0; this->actor.world.pos.y = (Math_SinS(this->actor.shape.rot.x) * -60.0f) + this->actor.home.pos.y; - sp28 = Math_CosS(this->actor.shape.rot.x) * 60.0f; - this->actor.world.pos.x = (Math_SinS(this->actor.shape.rot.y) * sp28) + this->actor.home.pos.x; - this->actor.world.pos.z = (Math_CosS(this->actor.shape.rot.y) * sp28) + this->actor.home.pos.z; + headDistHorizontal = Math_CosS(this->actor.shape.rot.x) * 60.0f; + this->actor.world.pos.x = (Math_SinS(this->actor.shape.rot.y) * headDistHorizontal) + this->actor.home.pos.x; + this->actor.world.pos.z = (Math_CosS(this->actor.shape.rot.y) * headDistHorizontal) + this->actor.home.pos.z; - if (this->collider2.base.acFlags & AC_HIT) { - func_808F13FC(this, play); - func_808F1BF8(this); + if (this->hurtCollider.base.acFlags & AC_HIT) { + EnKarebaba_SetDamageEffects(this, play); + EnKarebaba_SetupDying(this); Enemy_StartFinishingBlow(play, &this->actor); - } else if (this->unk_1EE == 0) { - func_808F1878(this); + } else if (this->timer == 0) { + EnKarebaba_SetupUpright(this); } } -void func_808F1BF8(EnKarebaba* this) { +void EnKarebaba_SetupDying(EnKarebaba* this) { if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { - this->unk_1EE = 0; + this->timer = 0; this->actor.gravity = -0.8f; this->actor.velocity.y = 4.0f; this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); this->actor.speedXZ = 3.0f; } else { - this->unk_1EE = 3; + this->timer = 3; } Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_JR_DEAD); this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); - this->actionFunc = func_808F1C84; + this->actionFunc = EnKarebaba_Dying; } -void func_808F1C84(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Dying(EnKarebaba* this, PlayState* play) { s32 i; - Vec3f sp78; - f32 temp_f20; - f32 temp_f22; - f32 temp_f24; + Vec3f dustPos; + f32 xIncr; + f32 zIncr; + f32 yIncr; if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { - this->unk_1EE--; - if (this->unk_1EE == 0) { + this->timer--; + if (this->timer == 0) { this->actor.gravity = -0.8f; this->actor.speedXZ = 3.0f; this->actor.velocity.y = 4.0f; this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); - func_808F1374(this, play); + EnKarebaba_SpawnIceEffects(this, play); } } else { Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f); - if (this->unk_1EE == 0) { + if (this->timer == 0) { Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4800, 0x71C); EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 3.0f, 0, 12, 5, 1, HAHEN_OBJECT_DEFAULT, 10, NULL); @@ -422,156 +425,155 @@ void func_808F1C84(EnKarebaba* this, PlayState* play) { if (this->actor.bgCheckFlags & 2) { Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); - this->unk_1EE = 1; + this->timer = 1; } - } else if (this->unk_1EE == 1) { - Math_Vec3f_Copy(&sp78, &this->actor.world.pos); + } else if (this->timer == 1) { + Math_Vec3f_Copy(&dustPos, &this->actor.world.pos); - temp_f24 = Math_SinS(this->actor.shape.rot.x) * 20.0f; - temp_f20 = (-20.0f * Math_CosS(this->actor.shape.rot.x)) * Math_SinS(this->actor.shape.rot.y); - temp_f22 = (-20.0f * Math_CosS(this->actor.shape.rot.x)) * Math_CosS(this->actor.shape.rot.y); + yIncr = Math_SinS(this->actor.shape.rot.x) * 20.0f; + xIncr = -20.0f * Math_CosS(this->actor.shape.rot.x) * Math_SinS(this->actor.shape.rot.y); + zIncr = -20.0f * Math_CosS(this->actor.shape.rot.x) * Math_CosS(this->actor.shape.rot.y); for (i = 0; i < 4; i++) { - func_800B1210(play, &sp78, &gZeroVec3f, &gZeroVec3f, 500, 50); - sp78.x += temp_f20; - sp78.y += temp_f24; - sp78.z += temp_f22; + func_800B1210(play, &dustPos, &gZeroVec3f, &gZeroVec3f, 500, 50); + dustPos.x += xIncr; + dustPos.y += yIncr; + dustPos.z += zIncr; } func_800B1210(play, &this->actor.home.pos, &gZeroVec3f, &gZeroVec3f, 500, 100); - func_808F20FC(this, play); + EnKarebaba_SetupDeadItemDrop(this, play); } } } -void func_808F1FAC(EnKarebaba* this) { +void EnKarebaba_SetupShrinkDie(EnKarebaba* this) { Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_JR_DEAD); this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); this->actor.flags &= ~ACTOR_FLAG_1; if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { - this->unk_1EE = 3; + this->timer = 3; } - this->actionFunc = func_808F200C; + this->actionFunc = EnKarebaba_ShrinkDie; } -void func_808F200C(EnKarebaba* this, PlayState* play) { +void EnKarebaba_ShrinkDie(EnKarebaba* this, PlayState* play) { if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { - this->unk_1EE--; - if (this->unk_1EE == 0) { - func_808F1374(this, play); + this->timer--; + if (this->timer == 0) { + EnKarebaba_SpawnIceEffects(this, play); } } else { if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.0005f)) { Item_DropCollectible(play, &this->actor.world.pos, ITEM00_NUTS_1); - func_808F238C(this); + EnKarebaba_SetupDead(this); } else { EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 3.0f, 0, 12, 5, 1, HAHEN_OBJECT_DEFAULT, 10, NULL); Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 1.0f); } - this->actor.scale.y = this->actor.scale.x; - this->actor.scale.z = this->actor.scale.x; + + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; } } -void func_808F20FC(EnKarebaba* this, PlayState* play) { +void EnKarebaba_SetupDeadItemDrop(EnKarebaba* this, PlayState* play) { Actor_SetScale(&this->actor, 0.03f); this->actor.shape.rot.x -= 0x4000; this->actor.shape.yOffset = 1000.0f; this->actor.gravity = 0.0f; this->actor.velocity.y = 0.0f; this->actor.shape.shadowScale = 3.0f; - func_800BC154(play, &play->actorCtx, &this->actor, 8); - this->unk_1EE = 200; + func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_MISC); + this->timer = 200; this->actor.flags &= ~ACTOR_FLAG_20; this->drawDmgEffAlpha = 0.0f; - this->actionFunc = func_808F21A4; + this->actionFunc = EnKarebaba_DeadItemDrop; } -void func_808F21A4(EnKarebaba* this, PlayState* play) { - if (this->unk_1EE != 0) { - this->unk_1EE--; +void EnKarebaba_DeadItemDrop(EnKarebaba* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; } - if (Actor_HasParent(&this->actor, play) || (this->unk_1EE == 0)) { - func_808F238C(this); + if (Actor_HasParent(&this->actor, play) || (this->timer == 0)) { + EnKarebaba_SetupDead(this); } else { Actor_PickUpNearby(&this->actor, play, GI_STICKS_1); } } -void func_808F220C(EnKarebaba* this) { - Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, -3.0f, - Animation_GetLastFrame(&object_dekubaba_Anim_0002B8), 0.0f, ANIMMODE_ONCE, -3.0f); - func_808F152C(this); - this->actionFunc = func_808F228C; +void EnKarebaba_SetupRetract(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, -3.0f, Animation_GetLastFrame(&gDekuBabaFastChompAnim), + 0.0f, ANIMMODE_ONCE, -3.0f); + EnKarebaba_ResetColliders(this); + this->actionFunc = EnKarebaba_Retract; } -void func_808F228C(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Retract(EnKarebaba* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (Math_StepToF(&this->actor.scale.x, 0.005f, 0.0005f) && (this->actor.params == ENKAREBABA_2)) { - func_808F1648(this); + if (Math_StepToF(&this->actor.scale.x, 0.005f, 0.0005f) && (this->actor.params == KAREBABA_MINI)) { + EnKarebaba_SetupIdle(this); } - this->actor.scale.z = this->actor.scale.x; - this->actor.scale.y = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.z = this->actor.scale.x; if ((this->actor.params == ENKAREBABA_1) && Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 14.0f, 5.0f)) { - func_808F1648(this); + EnKarebaba_SetupIdle(this); } - this->actor.shape.rot.y += 0x1999; + this->actor.shape.rot.y += 0x10000 / 10; EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, 3.0f, 0, 12, 5, 1, HAHEN_OBJECT_DEFAULT, 10, NULL); } -void func_808F238C(EnKarebaba* this) { - Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f); - func_808F152C(this); +void EnKarebaba_SetupDead(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &gDekuBabaFastChompAnim, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f); + EnKarebaba_ResetColliders(this); this->actor.shape.rot.x = -0x4000; - this->unk_1EE = 200; + this->timer = 200; this->actor.parent = NULL; this->actor.shape.shadowScale = 0.0f; this->drawDmgEffAlpha = 0.0f; Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); - this->actionFunc = func_808F254C; + this->actionFunc = EnKarebaba_Dead; } -void func_808F241C(EnKarebaba* this, PlayState* play) { - f32 sp1C; +void EnKarebaba_Regrow(EnKarebaba* this, PlayState* play) { + f32 scale; - this->unk_1EE++; - sp1C = this->unk_1EE * 0.05f; - Actor_SetScale(&this->actor, 0.005f * sp1C); - this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * sp1C); + this->timer++; + scale = this->timer * 0.05f; + Actor_SetScale(&this->actor, 0.005f * scale); + this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * scale); - if (this->unk_1EE == 20) { + if (this->timer == 20) { this->actor.flags &= ~ACTOR_FLAG_10; this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); if (this->actor.params == ENKAREBABA_1) { - func_800BC154(play, &play->actorCtx, &this->actor, 5); + func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_ENEMY); } - func_808F1648(this); + EnKarebaba_SetupIdle(this); } } -void func_808F24F8(EnKarebaba* this) { +void EnKarebaba_SetupRegrow(EnKarebaba* this) { this->actor.shape.yOffset = 0.0f; this->actor.shape.shadowScale = 22.0f; - this->collider1.dim.radius = sCylinderInit2.dim.radius; + this->attackCollider.dim.radius = sAttackCylinderInit.dim.radius; Actor_SetScale(&this->actor, 0.0f); - this->actionFunc = func_808F241C; + this->actionFunc = EnKarebaba_Regrow; } -void func_808F254C(EnKarebaba* this, PlayState* play) { +void EnKarebaba_Dead(EnKarebaba* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (this->unk_1EE != 0) { - this->unk_1EE--; + if (this->timer != 0) { + this->timer--; } - if (this->unk_1EE == 0) { - func_808F24F8(this); + if (this->timer == 0) { + EnKarebaba_SetupRegrow(this); } } @@ -591,30 +593,30 @@ void EnKarebaba_Update(Actor* thisx, PlayState* play2) { } else { this->drawDmgEffScale = this->drawDmgEffScale; } - } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.01875f)) { + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.75f / 40)) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } - if (this->actionFunc != func_808F254C) { - if (this->actionFunc == func_808F1C84) { + if (this->actionFunc != EnKarebaba_Dead) { + if (this->actionFunc == EnKarebaba_Dying) { Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 15.0f, 10.0f, 5); } else { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); - if (this->unk_22C == 0) { - this->unk_22C = this->actor.floorPoly; + if (this->boundFloor == 0) { + this->boundFloor = this->actor.floorPoly; } } - if ((this->actionFunc != func_808F1C84) && (this->actionFunc != func_808F200C) && - (this->actionFunc != func_808F21A4)) { - if ((this->actionFunc != func_808F241C) && (this->actionFunc != func_808F15B0)) { - CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); - CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base); + if ((this->actionFunc != EnKarebaba_Dying) && (this->actionFunc != EnKarebaba_ShrinkDie) && + (this->actionFunc != EnKarebaba_DeadItemDrop)) { + if ((this->actionFunc != EnKarebaba_Regrow) && (this->actionFunc != EnKarebaba_Grow)) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->attackCollider.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->hurtCollider.base); } - CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->attackCollider.base); Actor_SetFocus(&this->actor, (this->actor.scale.x * 10.0f) / 0.01f); max = this->actor.home.pos.y + 40.0f; @@ -625,8 +627,8 @@ void EnKarebaba_Update(Actor* thisx, PlayState* play2) { } } -void func_808F280C(EnKarebaba* this, PlayState* play) { - MtxF sp40; +void EnKarebaba_DrawShadow(EnKarebaba* this, PlayState* play) { + MtxF mf; OPEN_DISPS(play->state.gfxCtx); @@ -634,10 +636,9 @@ void func_808F280C(EnKarebaba* this, PlayState* play) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 255); - func_800C0094(this->unk_22C, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, &sp40); - Matrix_Mult(&sp40, MTXMODE_NEW); + func_800C0094(this->boundFloor, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, &mf); + Matrix_Mult(&mf, MTXMODE_NEW); Matrix_Scale(0.15f, 1.0f, 0.15f, MTXMODE_APPLY); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gCircleShadowDL); @@ -645,53 +646,53 @@ void func_808F280C(EnKarebaba* this, PlayState* play) { } void EnKarebaba_Draw(Actor* thisx, PlayState* play) { + static Color_RGBA8 sFogColor = { 0, 0, 0, 0 }; + static Gfx* sStemDLists[] = { gDekuBabaStemTopDL, gDekuBabaStemMiddleDL, gDekuBabaStemBaseDL }; EnKarebaba* this = THIS; s32 i; - s32 sp94; + s32 stemSections; s16 limbCount; - f32 sp8C = 0.01f; + f32 scale = 0.01f; OPEN_DISPS(play->state.gfxCtx); func_8012C28C(play->state.gfxCtx); - Math_Vec3f_Copy(this->limbPos, &this->actor.world.pos); + Math_Vec3f_Copy(this->bodyPartsPos, &this->actor.world.pos); - if (this->actionFunc == func_808F21A4) { - if ((this->unk_1EE > 40) || (this->unk_1EE & 1)) { + if (this->actionFunc == EnKarebaba_DeadItemDrop) { + if ((this->timer > 40) || (this->timer & 1)) { Matrix_Translate(0.0f, 0.0f, 200.0f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, object_dekubaba_DL_003070); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaStickDropDL); } - } else if (this->actionFunc != func_808F254C) { - func_800AE2A0(play, &D_808F2E28, 1, 2); + } else if (this->actionFunc != EnKarebaba_Dead) { + func_800AE2A0(play, &sFogColor, 1, 2); SkelAnime_DrawOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, NULL); Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); - if ((this->actionFunc == func_808F241C) || (this->actionFunc == func_808F200C) || - (this->actionFunc == func_808F15B0)) { - sp8C = this->unk_1EE * 0.0005f; + if ((this->actionFunc == EnKarebaba_Regrow) || (this->actionFunc == EnKarebaba_ShrinkDie) || + (this->actionFunc == EnKarebaba_Grow)) { + scale = this->timer * 0.0005f; } - Matrix_Scale(sp8C, sp8C, sp8C, MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); Matrix_RotateZYX(this->actor.shape.rot.x, this->actor.shape.rot.y, 0, MTXMODE_APPLY); - if (this->actor.params == ENKAREBABA_2) { - sp94 = 1; - } else if (this->actionFunc == func_808F1C84) { - sp94 = 2; + if (this->actor.params == KAREBABA_MINI) { + stemSections = 1; + } else if (this->actionFunc == EnKarebaba_Dying) { + stemSections = 2; } else { - sp94 = 3; + stemSections = 3; } - for (i = 0; i < sp94; i++) { + for (i = 0; i < stemSections; i++) { Matrix_Translate(0.0f, 0.0f, -2000.0f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_808F2E2C[i]); + gSPDisplayList(POLY_OPA_DISP++, sStemDLists[i]); - Matrix_MultZero(&this->limbPos[1 + i]); - if ((i == 0) && (this->actionFunc == func_808F1C84)) { + Matrix_MultZero(&this->bodyPartsPos[1 + i]); + if ((i == 0) && (this->actionFunc == EnKarebaba_Dying)) { Matrix_MultZero(&this->actor.focus.pos); } } @@ -699,41 +700,39 @@ void EnKarebaba_Draw(Actor* thisx, PlayState* play) { func_800AE5A0(play); } - func_800AE2A0(play, &D_808F2E28, 1, 2); + func_800AE2A0(play, &sFogColor, 1, 2); Matrix_Translate(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, MTXMODE_NEW); - if (this->actionFunc != func_808F15B0) { - sp8C = 0.01f; + if (this->actionFunc != EnKarebaba_Grow) { + scale = 0.01f; } - Matrix_Scale(sp8C, sp8C, sp8C, MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); Matrix_RotateYS(this->actor.home.rot.y, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, object_dekubaba_DL_0010F0); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaBaseLeavesDL); - if (this->actionFunc == func_808F1C84) { + if (this->actionFunc == EnKarebaba_Dying) { Matrix_RotateZYX(-0x4000, this->actor.shape.rot.y - this->actor.home.rot.y, 0, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, object_dekubaba_DL_001828); + gSPDisplayList(POLY_OPA_DISP++, gDekuBabaStemBaseDL); - Matrix_MultZero(&this->limbPos[3]); + Matrix_MultZero(&this->bodyPartsPos[3]); } func_800AE5A0(play); - if (this->actor.params == ENKAREBABA_2) { + if (this->actor.params == KAREBABA_MINI) { limbCount = 1; } else { - limbCount = ARRAY_COUNT(this->limbPos); + limbCount = ARRAY_COUNT(this->bodyPartsPos); } - Actor_DrawDamageEffects(play, &this->actor, this->limbPos, limbCount, this->drawDmgEffScale, + Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, limbCount, this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); - if (this->unk_22C != 0) { - func_808F280C(this, play); + if (this->boundFloor != 0) { + EnKarebaba_DrawShadow(this, play); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h index 5063a8dbe6..aa05aec0a1 100644 --- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h +++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h @@ -2,32 +2,33 @@ #define Z_EN_KAREBABA_H #include "global.h" +#include "objects/object_dekubaba/object_dekubaba.h" struct EnKarebaba; typedef void (*EnKarebabaActionFunc)(struct EnKarebaba*, PlayState*); -enum { - /* 0 */ ENKAREBABA_0, - /* 1 */ ENKAREBABA_1, - /* 2 */ ENKAREBABA_2, -}; +typedef enum { + /* 0 */ ENKAREBABA_0, // Unused, always shrinks and drops a Deku Nut + /* 1 */ ENKAREBABA_1, // Drops sticks (Only type OoT has) + /* 2 */ KAREBABA_MINI, +} KarebabaType; typedef struct EnKarebaba { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnKarebabaActionFunc actionFunc; - /* 0x18C */ Vec3s jointTable[8]; - /* 0x1BC */ Vec3s morphTable[8]; + /* 0x18C */ Vec3s jointTable[DEKUBABA_LIMB_MAX]; + /* 0x1BC */ Vec3s morphTable[DEKUBABA_LIMB_MAX]; /* 0x1EC */ u8 drawDmgEffType; - /* 0x1EE */ s16 unk_1EE; + /* 0x1EE */ s16 timer; /* 0x1F0 */ f32 drawDmgEffAlpha; /* 0x1F4 */ f32 drawDmgEffScale; /* 0x1F8 */ f32 drawDmgEffFrozenSteamScale; - /* 0x1FC */ Vec3f limbPos[4]; - /* 0x22C */ CollisionPoly* unk_22C; - /* 0x230 */ ColliderCylinder collider1; - /* 0x27C */ ColliderCylinder collider2; + /* 0x1FC */ Vec3f bodyPartsPos[4]; + /* 0x22C */ CollisionPoly* boundFloor; + /* 0x230 */ ColliderCylinder attackCollider; + /* 0x27C */ ColliderCylinder hurtCollider; } EnKarebaba; // size = 0x2C8 #endif // Z_EN_KAREBABA_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 7dfe176114..5447b0c0f0 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -5901,48 +5901,48 @@ 0x808B0F98:("EnAm_Draw",), 0x808B1330:("EnDekubaba_Init",), 0x808B1504:("EnDekubaba_Destroy",), - 0x808B1530:("func_808B1530",), - 0x808B15B8:("func_808B15B8",), - 0x808B16BC:("func_808B16BC",), - 0x808B1798:("func_808B1798",), - 0x808B1814:("func_808B1814",), - 0x808B18A8:("func_808B18A8",), - 0x808B1B14:("func_808B1B14",), - 0x808B1BC0:("func_808B1BC0",), - 0x808B1CF0:("func_808B1CF0",), - 0x808B2158:("func_808B2158",), - 0x808B2240:("func_808B2240",), - 0x808B2608:("func_808B2608",), - 0x808B2660:("func_808B2660",), - 0x808B2890:("func_808B2890",), - 0x808B28B4:("func_808B28B4",), - 0x808B2980:("func_808B2980",), - 0x808B29C4:("func_808B29C4",), - 0x808B2C40:("func_808B2C40",), - 0x808B2CB8:("func_808B2CB8",), - 0x808B3044:("func_808B3044",), - 0x808B3078:("func_808B3078",), - 0x808B3170:("func_808B3170",), - 0x808B3280:("func_808B3280",), - 0x808B3390:("func_808B3390",), - 0x808B3404:("func_808B3404",), - 0x808B3768:("func_808B3768",), - 0x808B37E8:("func_808B37E8",), - 0x808B39AC:("func_808B39AC",), - 0x808B3B48:("func_808B3B48",), - 0x808B3BE4:("func_808B3BE4",), - 0x808B3C50:("func_808B3C50",), - 0x808B3D74:("func_808B3D74",), - 0x808B3DA8:("func_808B3DA8",), - 0x808B3E40:("func_808B3E40",), - 0x808B3EE8:("func_808B3EE8",), - 0x808B3F50:("func_808B3F50",), + 0x808B1530:("EnDekubaba_DisableHitboxes",), + 0x808B15B8:("EnDekubaba_UpdateHeadPosition",), + 0x808B16BC:("EnDekubaba_SetFireLightEffects",), + 0x808B1798:("EnDekubaba_SetFrozenEffects",), + 0x808B1814:("EnDekubaba_SpawnIceEffects",), + 0x808B18A8:("EnDekubaba_SetupWait",), + 0x808B1B14:("EnDekubaba_Wait",), + 0x808B1BC0:("EnDekubaba_SetupGrow",), + 0x808B1CF0:("EnDekubaba_Grow",), + 0x808B2158:("EnDekubaba_SetupRetract",), + 0x808B2240:("EnDekubaba_Retract",), + 0x808B2608:("EnDekubaba_SetupDecideLunge",), + 0x808B2660:("EnDekubaba_DecideLunge",), + 0x808B2890:("EnDekubaba_SetupPrepareLunge",), + 0x808B28B4:("EnDekubaba_PrepareLunge",), + 0x808B2980:("EnDekubaba_SetupLunge",), + 0x808B29C4:("EnDekubaba_Lunge",), + 0x808B2C40:("EnDekubaba_SetupPullBack",), + 0x808B2CB8:("EnDekubaba_PullBack",), + 0x808B3044:("EnDekubaba_SetupRecover",), + 0x808B3078:("EnDekubaba_Recover",), + 0x808B3170:("EnDekubaba_SetupHit",), + 0x808B3280:("EnDekubaba_Hit",), + 0x808B3390:("EnDekubaba_SetupPrunedSomersaultDie",), + 0x808B3404:("EnDekubaba_PrunedSomersaultDie",), + 0x808B3768:("EnDekubaba_SetupShrinkDie",), + 0x808B37E8:("EnDekubaba_ShrinkDie",), + 0x808B39AC:("EnDekubaba_SetupStunnedVertical",), + 0x808B3B48:("EnDekubaba_StunnedVertical",), + 0x808B3BE4:("EnDekubaba_SetupSway",), + 0x808B3C50:("EnDekubaba_Sway",), + 0x808B3D74:("EnDekubaba_SetupFrozen",), + 0x808B3DA8:("EnDekubaba_Frozen",), + 0x808B3E40:("EnDekubaba_SetupDeadStickDrop",), + 0x808B3EE8:("EnDekubaba_DeadStickDrop",), + 0x808B3F50:("EnDekubaba_UpdateDamage",), 0x808B42FC:("EnDekubaba_Update",), - 0x808B4548:("func_808B4548",), - 0x808B465C:("func_808B465C",), - 0x808B48FC:("func_808B48FC",), - 0x808B49C8:("func_808B49C8",), - 0x808B4ABC:("func_808B4ABC",), + 0x808B4548:("EnDekubaba_DrawStemRetracted",), + 0x808B465C:("EnDekubaba_DrawStemExtended",), + 0x808B48FC:("EnDekubaba_DrawStemBasePruned",), + 0x808B49C8:("EnDekubaba_DrawShadow",), + 0x808B4ABC:("EnDekubaba_PostLimbDraw",), 0x808B4AF8:("EnDekubaba_Draw",), 0x808B5230:("EnMFire1_Init",), 0x808B5294:("EnMFire1_Destroy",), @@ -6675,33 +6675,33 @@ 0x808ED3F4:("func_808ED3F4",), 0x808F1200:("EnKarebaba_Init",), 0x808F1334:("EnKarebaba_Destroy",), - 0x808F1374:("func_808F1374",), - 0x808F13FC:("func_808F13FC",), - 0x808F152C:("func_808F152C",), - 0x808F155C:("func_808F155C",), - 0x808F15B0:("func_808F15B0",), - 0x808F1648:("func_808F1648",), - 0x808F169C:("func_808F169C",), - 0x808F16FC:("func_808F16FC",), - 0x808F1778:("func_808F1778",), - 0x808F1878:("func_808F1878",), - 0x808F190C:("func_808F190C",), - 0x808F1A3C:("func_808F1A3C",), - 0x808F1A58:("func_808F1A58",), - 0x808F1BF8:("func_808F1BF8",), - 0x808F1C84:("func_808F1C84",), - 0x808F1FAC:("func_808F1FAC",), - 0x808F200C:("func_808F200C",), - 0x808F20FC:("func_808F20FC",), - 0x808F21A4:("func_808F21A4",), - 0x808F220C:("func_808F220C",), - 0x808F228C:("func_808F228C",), - 0x808F238C:("func_808F238C",), - 0x808F241C:("func_808F241C",), - 0x808F24F8:("func_808F24F8",), - 0x808F254C:("func_808F254C",), + 0x808F1374:("EnKarebaba_SpawnIceEffects",), + 0x808F13FC:("EnKarebaba_SetDamageEffects",), + 0x808F152C:("EnKarebaba_ResetColliders",), + 0x808F155C:("EnKarebaba_SetupGrow",), + 0x808F15B0:("EnKarebaba_Grow",), + 0x808F1648:("EnKarebaba_SetupIdle",), + 0x808F169C:("EnKarebaba_Idle",), + 0x808F16FC:("EnKarebaba_SetupAwaken",), + 0x808F1778:("EnKarebaba_Awaken",), + 0x808F1878:("EnKarebaba_SetupUpright",), + 0x808F190C:("EnKarebaba_Upright",), + 0x808F1A3C:("EnKarebaba_SetupSpin",), + 0x808F1A58:("EnKarebaba_Spin",), + 0x808F1BF8:("EnKarebaba_SetupDying",), + 0x808F1C84:("EnKarebaba_Dying",), + 0x808F1FAC:("EnKarebaba_SetupShrinkDie",), + 0x808F200C:("EnKarebaba_ShrinkDie",), + 0x808F20FC:("EnKarebaba_SetupDeadItemDrop",), + 0x808F21A4:("EnKarebaba_DeadItemDrop",), + 0x808F220C:("EnKarebaba_SetupRetract",), + 0x808F228C:("EnKarebaba_Retract",), + 0x808F238C:("EnKarebaba_SetupDead",), + 0x808F241C:("EnKarebaba_Regrow",), + 0x808F24F8:("EnKarebaba_SetupRegrow",), + 0x808F254C:("EnKarebaba_Dead",), 0x808F25A4:("EnKarebaba_Update",), - 0x808F280C:("func_808F280C",), + 0x808F280C:("EnKarebaba_DrawShadow",), 0x808F28F8:("EnKarebaba_Draw",), 0x808F30B0:("EnIn_ChangeAnim",), 0x808F3178:("func_808F3178",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index f88af903e3..071fce9db1 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -6431,15 +6431,15 @@ 0x808B11B0:("D_808B11B0","f32","",0x4), 0x808B11B4:("D_808B11B4","f32","",0x4), 0x808B11B8:("D_808B11B8","f32","",0x4), - 0x808B4D40:("En_Dekubaba_InitVars","UNK_TYPE1","",0x1), - 0x808B4D60:("D_808B4D60","UNK_TYPE1","",0x1), - 0x808B4E5C:("D_808B4E5C","UNK_TYPE1","",0x1), - 0x808B4E6C:("D_808B4E6C","UNK_TYPE1","",0x1), - 0x808B4E74:("D_808B4E74","UNK_TYPE1","",0x1), - 0x808B4E94:("D_808B4E94","UNK_TYPE1","",0x1), - 0x808B4E98:("D_808B4E98","UNK_TYPE1","",0x1), - 0x808B4E9C:("D_808B4E9C","UNK_TYPE1","",0x1), - 0x808B4EA0:("D_808B4EA0","UNK_PTR","",0x4), + 0x808B4D40:("En_Dekubaba_InitVars","ActorInit","",0x20), + 0x808B4D60:("sJntSphElementsInit","ColliderJntSphElementInit","[7]",0xFC), + 0x808B4E5C:("sJntSphInit","ColliderJntSphInit","",0x10), + 0x808B4E6C:("sColChkInfoInit","CollisionCheckInfoInit","",0x4), + 0x808B4E74:("sDamageTable","DamageTable","",0x20), + 0x808B4E94:("sInitChain","InitChainEntry","[1]",0x4), + 0x808B4E98:("sDustPrimColor","Color_RGBA8","",0x4), + 0x808B4E9C:("sDustEnvColor","Color_RGBA8","",0x4), + 0x808B4EA0:("sStemDLists","Gfx*","[3]",0xC), 0x808B4EB0:("D_808B4EB0","f32","",0x4), 0x808B4EB4:("D_808B4EB4","f32","",0x4), 0x808B4EB8:("D_808B4EB8","f32","",0x4), @@ -7197,8 +7197,8 @@ 0x808F2DF8:("D_808F2DF8","UNK_TYPE1","",0x1), 0x808F2E00:("D_808F2E00","UNK_TYPE1","",0x1), 0x808F2E20:("D_808F2E20","UNK_TYPE1","",0x1), - 0x808F2E28:("D_808F2E28","UNK_TYPE1","",0x1), - 0x808F2E2C:("D_808F2E2C","UNK_PTR","",0x4), + 0x808F2E28:("sFogColor","Color_RGBA8","",0x4), + 0x808F2E2C:("sStemDLists","Gfx*","[3]",0xC), 0x808F2E40:("D_808F2E40","f32","",0x4), 0x808F2E44:("D_808F2E44","f32","",0x4), 0x808F2E48:("D_808F2E48","f32","",0x4), diff --git a/undefined_syms.txt b/undefined_syms.txt index 649b781ced..f6436d5430 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -780,16 +780,6 @@ D_0600CB2C = 0x0600CB2C; D_0600CB84 = 0x0600CB84; D_0600CBC0 = 0x0600CBC0; -// ovl_En_Dekubaba - -D_06000208 = 0x06000208; -D_060002B8 = 0x060002B8; -D_060010F0 = 0x060010F0; -D_06001330 = 0x06001330; -D_06001828 = 0x06001828; -D_06002A40 = 0x06002A40; -D_06003070 = 0x06003070; - // ovl_En_Dnh D_06002950 = 0x06002950;