diff --git a/assets/xml/objects/object_death.xml b/assets/xml/objects/object_death.xml index 7588c484a..6c75cc824 100644 --- a/assets/xml/objects/object_death.xml +++ b/assets/xml/objects/object_death.xml @@ -1,12 +1,12 @@  - - - - - - - + + + + + + + @@ -39,47 +39,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_Boss_05.xml b/assets/xml/overlays/ovl_Boss_05.xml new file mode 100644 index 000000000..8eef13a4e --- /dev/null +++ b/assets/xml/overlays/ovl_Boss_05.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/include/functions.h b/include/functions.h index 907c35b5f..b1dfb0f17 100644 --- a/include/functions.h +++ b/include/functions.h @@ -216,6 +216,10 @@ void EffectSsFhgFlash_SpawnShock(PlayState* play, Actor* actor, Vec3f* pos, s16 void EffectSsKFire_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scaleMax, u8 type); void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16* playerDetected, s16 flags); void EffectSsKakera_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* arg3, s16 gravity, s16 arg5, s16 arg6, s16 arg7, s16 arg8, s16 scale, s16 arg10, s16 arg11, s32 life, s16 colorIdx, s16 objectId, Gfx* dList); +// void EffectSsFhgFlash_SpawnShock(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, UNK_TYPE2 uParm4, UNK_TYPE1 param_5); +void EffectSsKFire_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scaleMax, u8 type); +void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, s16* linkDetected, s16 drawFlag); +void EffectSsKakera_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* arg3, s16 gravity, s16 arg5, s16 arg6, s16 arg7, s16 arg8, s16 scale, s16 arg10, s16 arg11, s32 life, s16 colorIdx, s16 objId, Gfx* dList); // void EffectSsIcePiece_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, UNK_TYPE4 uParm3, Vec3f* pzParm4, Vec3f* param_5, UNK_TYPE4 param_6); void EffectSsIcePiece_SpawnBurst(PlayState* play, Vec3f* refPos, f32 scale); void func_800B2B44(PlayState* play, Actor* actor, Vec3f* pos, f32 scale); @@ -962,8 +966,6 @@ void Play_GetFloorSurface(PlayState* this, MtxF* mtx, Vec3f* pos); void* Play_LoadFile(PlayState* this, RomFile* entry); void Play_InitEnvironment(PlayState* this, s16 skyboxId); void Play_GetScreenPos(PlayState* this, Vec3f* worldPos, Vec3f* screenPos); -s16 Play_CreateSubCamera(PlayState* this); -s16 Play_GetActiveCamId(PlayState* this); s32 Play_ChangeCameraStatus(PlayState* this, s16 camId, s16 status); void Play_ClearCamera(PlayState* this, s16 camId); Camera* Play_GetCamera(PlayState* this, s16 camId); @@ -988,6 +990,66 @@ s32 Play_CamIsNotFixed(GameState* thisx); s32 FrameAdvance_IsEnabled(GameState* thisx); s32 func_8016A02C(GameState* thisx, Actor* actor, s16* yaw); s32 Play_IsUnderwater(PlayState* this, Vec3f* pos); +// void func_80165460(void); +// void func_80165608(void); +// void func_80165630(void); +void func_80165658(u32 arg0); +void func_8016566C(u32 arg0); +void func_80165690(void); +// void func_801656A4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8); +// void func_80165DCC(void); +// void func_80165DF0(void); +// void func_80165E1C(void); +// void func_80165E7C(void); +// void func_80165EC0(void); +// void func_80166060(void); +Gfx* func_801660B8(PlayState* play, Gfx* gfx); +void Play_Fini(GameState* thisx); +// void func_801663C4(void); +// void func_80166644(void); +// void func_801668B4(void); +void func_80166968(PlayState* play, Camera* camera); +void func_80166B30(PlayState* play); +void func_80167814(PlayState* play); +void func_80167DE4(PlayState* play); +// void func_80167F0C(void); +void Play_Draw(PlayState* play); +void func_80168DAC(PlayState* play); +void Play_Update(PlayState* play); +s32 Play_InCsMode(PlayState* play); +f32 func_80169100(PlayState* play, MtxF* mtx, CollisionPoly** arg2, s32* arg3, Vec3f* feetPosPtr); +// void func_801691F0(void); +void* Play_LoadScene(PlayState* play, RomFile* entry); +void func_8016927C(PlayState* play, s16 sParm2); +// void func_801692C4(PlayState* play, UNK_TYPE1 uParm2); +// void Play_SceneInit(PlayState* play, s32 sceneIndex, UNK_TYPE1 param_3); +UNK_RET func_80169474(PlayState* play, Vec3f* v1, Vec3f* v2); +s16 Play_CreateSubCamera(PlayState* play); +s16 Play_GetActiveCamId(PlayState* play); +void Play_CameraChangeStatus(PlayState* play, s16 camId, s16 status); +void Play_ClearCamera(PlayState* play, s16 camId); +Camera* Play_GetCamera(PlayState* play, s16 index); +s32 Play_CameraSetAtEye(PlayState* play, s16 camId, Vec3f* at, Vec3f* eye); +void Play_CameraSetAtEyeUp(PlayState* play, s16 camId, Vec3f* at, Vec3f* eye, Vec3f* up); +s32 Play_CameraSetFov(PlayState* play, s16 camId, f32 fov); +void Play_CameraSetRoll(PlayState* play, s16 camId, s16 roll); +void Play_CopyCamera(PlayState* play, s16 dstCamId, s16 srcCamId); +// void func_80169A50(void); +void Play_CameraChangeSetting(PlayState* play, s16 camId, s16 setting); +void func_80169AFC(PlayState* play, s16 camId, s16 arg2); +s16 Play_GetCsCamDataSetting(PlayState* play, s32 camId); +Vec3s* Play_GetCsCamDataVec3s(PlayState* play, s32 camId); +s16 Play_GetOriginalSceneNumber(s16 sceneNum); +void Play_SaveCycleSceneFlags(GameState* gameState); +void Play_SetRespawnData(GameState* gameState, s32 respawnNumber, u16 sceneSetup, s32 roomIndex, s32 playerParams, Vec3f* pos, s16 yaw); +void Play_SetupRespawnPoint(GameState* gameState, s32 respawnNumber, s32 playerParams); +void func_80169EFC(GameState* gameState); +void func_80169F78(GameState* gameState); +void func_80169FDC(GameState* gameState); +s32 func_80169FFC(GameState* gameState); +s32 FrameAdvance_IsEnabled(GameState* gameState); +s32 func_8016A02C(GameState* gameState, Actor* actor, s16* yaw); +s32 Play_IsUnderwater(PlayState* play, Vec3f* pos); s32 Play_IsDebugCamEnabled(void); void Play_AssignPlayerCsIdsFromScene(GameState* thisx, s32 spawnCsId); void Play_FillScreen(GameState* thisx, s16 fillScreenOn, u8 red, u8 green, u8 blue, u8 alpha); diff --git a/include/z64subs.h b/include/z64subs.h index 2e751dfc4..a6873ff97 100644 --- a/include/z64subs.h +++ b/include/z64subs.h @@ -133,7 +133,7 @@ s32 SubS_CopyPointFromPathCheckBounds(Path* path, s32 pointIndex, Vec3f* dst); s32 SubS_Offer(Actor* actor, struct PlayState* play, f32 xzRange, f32 yRange, s32 itemId, SubSOfferMode mode); void SubS_FillShadowTex(s32 startCol, s32 startRow, u8* tex, s32 size); -void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween, u8 bodyPartsNum, u8 sizes[], s8 parentBodyParts[]); +void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 weight, u8 bodyPartsNum, u8 sizes[], s8 parentBodyParts[]); void SubS_DrawShadowTex(Actor* actor, struct GameState* gameState, u8* tex); s16 SubS_ComputeTrackPointRot(s16* rot, s16 rotMax, s16 target, f32 slowness, f32 stepMin, f32 stepMax); diff --git a/spec b/spec index 6fa839d5f..e0c529134 100644 --- a/spec +++ b/spec @@ -1029,17 +1029,14 @@ beginseg name "ovl_En_Death" compress include "build/src/overlays/actors/ovl_En_Death/z_en_death.o" - include "build/data/ovl_En_Death/ovl_En_Death.data.o" - include "build/data/ovl_En_Death/ovl_En_Death.reloc.o" + include "build/src/overlays/actors/ovl_En_Death/ovl_En_Death_reloc.o" endseg beginseg name "ovl_En_Minideath" compress include "build/src/overlays/actors/ovl_En_Minideath/z_en_minideath.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.data.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.bss.o" - include "build/data/ovl_En_Minideath/ovl_En_Minideath.reloc.o" + include "build/src/overlays/actors/ovl_En_Minideath/ovl_En_Minideath_reloc.o" endseg beginseg @@ -2176,9 +2173,7 @@ beginseg name "ovl_En_Knight" compress include "build/src/overlays/actors/ovl_En_Knight/z_en_knight.o" - include "build/data/ovl_En_Knight/ovl_En_Knight.data.o" - include "build/data/ovl_En_Knight/ovl_En_Knight.bss.o" - include "build/data/ovl_En_Knight/ovl_En_Knight.reloc.o" + include "build/src/overlays/actors/ovl_En_Knight/ovl_En_Knight_reloc.o" endseg beginseg @@ -2325,8 +2320,6 @@ beginseg name "ovl_Boss_05" compress include "build/src/overlays/actors/ovl_Boss_05/z_boss_05.o" - include "build/data/ovl_Boss_05/ovl_Boss_05.data.o" - include "build/data/ovl_Boss_05/ovl_Boss_05.bss.o" include "build/data/ovl_Boss_05/ovl_Boss_05.reloc.o" endseg @@ -3419,7 +3412,6 @@ beginseg name "ovl_En_Wdhand" compress include "build/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.o" - include "build/data/ovl_En_Wdhand/ovl_En_Wdhand.data.o" include "build/data/ovl_En_Wdhand/ovl_En_Wdhand.reloc.o" endseg @@ -3505,8 +3497,7 @@ beginseg name "ovl_Boss_Hakugin" compress include "build/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.o" - include "build/data/ovl_Boss_Hakugin/ovl_Boss_Hakugin.data.o" - include "build/data/ovl_Boss_Hakugin/ovl_Boss_Hakugin.reloc.o" + include "build/src/overlays/actors/ovl_Boss_Hakugin/ovl_Boss_Hakugin_reloc.o" endseg beginseg diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c index e630ed150..e1e331beb 100644 --- a/src/code/z_sub_s.c +++ b/src/code/z_sub_s.c @@ -963,7 +963,7 @@ void SubS_FillShadowTex(s32 startCol, s32 startRow, u8* tex, s32 size) { } } -void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween, u8 bodyPartsNum, u8 sizes[], +void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 weight, u8 bodyPartsNum, u8 sizes[], s8 parentBodyParts[]) { Vec3f pos; Vec3f startVec; @@ -978,9 +978,9 @@ void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween parentBodyPart = parentBodyParts[i]; bodyPartPos = &bodyPartsPos[i]; - pos.x = (bodyPartsPos[parentBodyPart].x - bodyPartPos->x) * tween + (bodyPartPos->x - worldPos->x); - pos.y = (bodyPartsPos[parentBodyPart].y - bodyPartPos->y) * tween + (bodyPartPos->y - worldPos->y); - pos.z = (bodyPartsPos[parentBodyPart].z - bodyPartPos->z) * tween + (bodyPartPos->z - worldPos->z); + pos.x = (bodyPartsPos[parentBodyPart].x - bodyPartPos->x) * weight + (bodyPartPos->x - worldPos->x); + pos.y = (bodyPartsPos[parentBodyPart].y - bodyPartPos->y) * weight + (bodyPartPos->y - worldPos->y); + pos.z = (bodyPartsPos[parentBodyPart].z - bodyPartPos->z) * weight + (bodyPartPos->z - worldPos->z); } else { bodyPartPos = &bodyPartsPos[i]; diff --git a/src/overlays/actors/ovl_Boss_05/z_boss_05.c b/src/overlays/actors/ovl_Boss_05/z_boss_05.c index 56d26129a..47d0d8277 100644 --- a/src/overlays/actors/ovl_Boss_05/z_boss_05.c +++ b/src/overlays/actors/ovl_Boss_05/z_boss_05.c @@ -15,68 +15,135 @@ void Boss05_Destroy(Actor* thisx, PlayState* play); void Boss05_Update(Actor* thisx, PlayState* play); void Boss05_Draw(Actor* thisx, PlayState* play); +void func_809EEDD0(Boss05* this, PlayState* play); void func_809EEDE8(Boss05* this, PlayState* play); void func_809EF9BC(Boss05* this, PlayState* play); void func_809EFAB4(Boss05* this, PlayState* play); +void func_809F00CC(Boss05* this, PlayState* play); void func_809F010C(Boss05* this, PlayState* play); +void func_809F01CC(Boss05* this, PlayState* play); void func_809F0244(Boss05* this, PlayState* play); +void func_809F02D0(Boss05* this, PlayState* play); void func_809F0374(Boss05* this, PlayState* play); +void func_809F0474(Boss05* this, PlayState* play); void func_809F04C0(Boss05* this, PlayState* play); +void func_809F0538(Boss05* this, PlayState* arg1); void func_809F0590(Boss05* this, PlayState* play); +void func_809F0650(Boss05* this, PlayState* arg1); void func_809F06B8(Boss05* this, PlayState* play); +void func_809F0708(Boss05* this, PlayState* play); void func_809F0780(Boss05* this, PlayState* play); +void func_809F0A0C(Boss05* this, PlayState* play); +void func_809F0A64(Boss05* this, PlayState* play); void func_809F0ABC(Boss05* this, PlayState* play); void func_809F0B0C(Boss05* this, PlayState* play); -#if 0 +#include "overlays/ovl_Boss_05/ovl_Boss_05.c" + // static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_809F1B2C[2] = { +ColliderJntSphElementInit D_809F1B2C[2] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1B74 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1B2C, // sJntSphElementsInit, +ColliderJntSphInit D_809F1B74 = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1B2C), + D_809F1B2C, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809F1B84[1] = { +ColliderJntSphElementInit D_809F1B84[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1BA8 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1B84, // sJntSphElementsInit, +ColliderJntSphInit D_809F1BA8 = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1B84), + D_809F1B84, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809F1BB8[1] = { +ColliderJntSphElementInit D_809F1BB8[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7FFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7FFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809F1BDC = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809F1BB8, // sJntSphElementsInit, +ColliderJntSphInit D_809F1BDC = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809F1BB8), + D_809F1BB8, // sJntSphElementsInit, }; +Color_RGBA8 D_809F1BEC = { 170, 255, 255, 255 }; +Color_RGBA8 D_809F1BF0 = { 200, 200, 255, 255 }; +Vec3f D_809F1BF4 = { 0.0f, -1.0f, 0.0f }; + // static DamageTable sDamageTable = { -static DamageTable D_809F1C00 = { +DamageTable D_809F1C00 = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -112,7 +179,7 @@ static DamageTable D_809F1C00 = { }; // static DamageTable sDamageTable = { -static DamageTable D_809F1C20 = { +DamageTable D_809F1C20 = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(3, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -159,107 +226,1242 @@ ActorInit Boss_05_InitVars = { /**/ Boss05_Draw, }; -#endif +extern AnimationHeader D_060006A4; +extern AnimationHeader D_06000A5C; +extern AnimationHeader D_06000ABC; +extern FlexSkeletonHeader D_060024E0; +extern AnimationHeader D_06002F0C; +extern AnimationHeader D_06003448; +extern AnimatedMaterial D_06006240[]; +extern FlexSkeletonHeader D_06006378; +extern AnimationHeader D_06006484; +extern AnimationHeader D_06006E50; +extern AnimationHeader D_06007488; +extern AnimationHeader D_06007908; -extern ColliderJntSphElementInit D_809F1B2C[2]; -extern ColliderJntSphInit D_809F1B74; -extern ColliderJntSphElementInit D_809F1B84[1]; -extern ColliderJntSphInit D_809F1BA8; -extern ColliderJntSphElementInit D_809F1BB8[1]; -extern ColliderJntSphInit D_809F1BDC; -extern DamageTable D_809F1C00; -extern DamageTable D_809F1C20; +void func_809EE4E0(Boss05* this, PlayState* play) { + Vec3f icePos; + Vec3f iceVelocity; + s32 i; -extern UNK_TYPE D_060006A4; -extern UNK_TYPE D_06000A5C; -extern UNK_TYPE D_06000ABC; -extern UNK_TYPE D_06002F0C; -extern UNK_TYPE D_06003448; -extern UNK_TYPE D_06006240; -extern UNK_TYPE D_06006E50; -extern UNK_TYPE D_06007488; -extern UNK_TYPE D_06007908; + SoundSource_PlaySfxAtFixedWorldPos(play, &this->limbPos[0], 30, NA_SE_EV_ICE_BROKEN); + for (i = 0; i < 8; i++) { + iceVelocity.x = Rand_CenteredFloat(7.0f); + iceVelocity.z = Rand_CenteredFloat(7.0f); + iceVelocity.y = Rand_ZeroFloat(6.0f) + 4.0f; + icePos.x = this->limbPos[0].x + iceVelocity.x; + icePos.y = this->limbPos[0].y + iceVelocity.y; + icePos.z = this->limbPos[0].z + iceVelocity.z; + EffectSsEnIce_Spawn(play, &icePos, Rand_ZeroFloat(0.5f) + 0.7f, &iceVelocity, &D_809F1BF4, &D_809F1BEC, + &D_809F1BF0, 30); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EE4E0.s") +void func_809EE668(s32 elementIndex, ColliderJntSph* collider, Vec3f* pos) { + collider->elements[elementIndex].dim.worldSphere.center.x = (s32)pos->x; + collider->elements[elementIndex].dim.worldSphere.center.y = (s32)pos->y; + collider->elements[elementIndex].dim.worldSphere.center.z = (s32)pos->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EE668.s") + collider->elements[elementIndex].dim.worldSphere.radius = + (s32)(collider->elements[elementIndex].dim.modelSphere.radius * collider->elements[elementIndex].dim.scale); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Init.s") +void Boss05_Init(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = THIS; + CollisionHeader* colHeader = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Destroy.s") + this->dyna.actor.targetMode = 3; + this->dyna.actor.colChkInfo.mass = MASS_HEAVY; + this->dyna.actor.colChkInfo.health = 2; + this->unk160 = (s32)Rand_ZeroFloat(1000.0f); + this->unk35C = 1.0f; + this->dyna.actor.gravity = -0.3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EECBC.s") + Actor_SetScale(&this->dyna.actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EEDD0.s") + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_0) || (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1)) { + if (this->dyna.actor.world.rot.z == 0) { + this->dyna.actor.world.rot.z = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EEDE8.s") + this->dyna.actor.shape.rot.z = 0; + this->unk168 = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z; + this->dyna.actor.colChkInfo.damageTable = &D_809F1C00; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EF9BC.s") + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&sBioBabaLilypadCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); + func_809EEDD0(this, play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EFAB4.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); + this->lastAnimFrame = Animation_GetLastFrame(&D_06006484); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809EFE50.s") + Collider_InitAndSetJntSph(play, &this->collider2, &this->dyna.actor, &D_809F1B74, this->colliderElements2); + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BA8, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0014.s") + if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { + this->dyna.actor.params = BIO_DEKU_BABA_TYPE_2; + this->actionFunc = func_809EF9BC; + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + } + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) { + this->actionFunc = func_809EF9BC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0058.s") + CollisionHeader_GetVirtual(&sBioBabaLilypadCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F00CC.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_3) { + this->actionFunc = func_809EFAB4; + this->unk198 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F010C.s") + SkelAnime_InitFlex(play, &this->skelAnime10, &D_060024E0, &D_06000ABC, this->jointTable10, this->morphTable10, + 10); + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); + this->lastAnimFrame = Animation_GetLastFrame(&D_06006484); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F01CC.s") + Collider_InitAndSetJntSph(play, &this->collider2, &this->dyna.actor, &D_809F1B74, this->colliderElements2); + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BA8, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0244.s") + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->dyna.actor.colChkInfo.damageTable = &D_809F1C00; + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + func_809F00CC(this, play); + this->dyna.actor.colChkInfo.mass = 90; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F02D0.s") + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0374.s") + Collider_InitAndSetJntSph(play, &this->collider1, &this->dyna.actor, &D_809F1BDC, this->colliderElements1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0474.s") + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->dyna.actor.colChkInfo.damageTable = &D_809F1C20; + this->dyna.actor.flags |= ACTOR_FLAG_10 | ACTOR_FLAG_20; + } else if (this->dyna.actor.params >= BIO_DEKU_BABA_TYPE_10) { + SkelAnime_InitFlex(play, &this->skelAnime20, &D_06006378, &D_06006484, this->jointTable20, this->morphTable20, + 20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F04C0.s") + this->dyna.actor.gravity = 0.0f; + this->dyna.actor.world.rot.y = (s32)Rand_ZeroFloat(0x8000); + this->dyna.actor.speed = Rand_ZeroFloat(3.0f) + 3.0f; + this->dyna.actor.velocity.y = Rand_ZeroFloat(1.5f) + 1.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0538.s") + this->unk500.x = (s32)Rand_CenteredFloat(700.0f); + this->unk500.y = (s32)Rand_CenteredFloat(1500.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(30.0f) + 50.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0590.s") + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + this->actionFunc = func_809F0B0C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0650.s") +void Boss05_Destroy(Actor* thisx, PlayState* play) { + Boss05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F06B8.s") + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) || (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_0) || + (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1)) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0708.s") +s32 func_809EECBC(Boss05* this, PlayState* play) { + if (this->unk16C == 0) { + s32 i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0780.s") + while (true) { + if (this->collider2.elements[i].info.bumperFlags & BUMP_HIT) { + switch (this->dyna.actor.colChkInfo.damageEffect) { + case 2: + return 11; + case 3: + return 20; + case 4: + return 30; + default: + return 10; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0A0C.s") + i++; + if (i == 2) { + if (this->collider1.elements[0].info.bumperFlags & BUMP_HIT) { + u8 damage = this->dyna.actor.colChkInfo.damage; + this->dyna.actor.colChkInfo.health -= damage; + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + Enemy_StartFinishingBlow(play, &this->dyna.actor); + return 2; + } else { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk16C = 15; + this->unk15C = 0; + this->unk162[0] = 30; + return 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0A64.s") + break; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0ABC.s") + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F0B0C.s") +void func_809EEDD0(Boss05* this, PlayState* play) { + this->actionFunc = func_809EEDE8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Update.s") +Vec3s D_809F1C60[7] = { + { 0x3200, 0, 0 }, { -0x1E00, 0, 0 }, { -0x1400, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, +}; +Vec3s D_809F1C8C[7] = { + { -0x3200, 0, 0 }, { 0, 0, 0 }, { 0x1E00, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1050.s") +void func_809EEDE8(Boss05* this, PlayState* play) { + s32 i; + Player* sp108 = GET_PLAYER(play); + s32 j; + u8 sp103 = 0; + Vec3s spD8[7]; + s32 spD4; + s32 spD0; + s32 spCC; + s32 spC8; + s32 spC4; + s32 spC0; + s32 spBC; + s32 spB8; + s32 spB4; + s32 var_s6; + s32 var_s7; + s16 var_s5; + s16 var_s4; + f32 spA4; + f32 var_fv1; + Vec3f sp94; + s32 var_s4_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1170.s") + this->dyna.actor.hintId = TATL_HINT_ID_BIO_DEKU_BABA; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1284.s") + if (this->unk174 == 0) { + spD4 = 0x3E8; + spD0 = 0x3E80; + spCC = 0x7D0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F12A0.s") + spC8 = 0x5DC; + spC4 = 0x1770; + spC0 = 0xBB8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F135C.s") + spBC = 0x514; + spB8 = 0x5208; + spB4 = 0xDAC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1404.s") + var_s6 = 0xA; + var_s7 = 0x300; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1430.s") + if (this->unk16C != 0) { + spD4 = 0x1B58; + spCC = 0x1770; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1464.s") + spC0 = 0x1770; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F14AC.s") + spBC = 0x1C84; + spB4 = 0x1964; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/func_809F1550.s") + var_s6 = 1; + var_s7 = 0x1000; + } + } else if (this->unk174 == 3) { + spD4 = 0x1B58; + spD0 = 0x3E80; + spCC = 0x1388; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_05/Boss05_Draw.s") + spC8 = 0x5DC; + spC4 = 0x2328; + spC0 = 0x1388; + + spBC = 0x1C84; + spB8 = 0x5208; + spB4 = 0x157C; + + var_s6 = 1; + var_s7 = 0x1000; + } else { + spD4 = spD0 = spCC = spC8 = spC4 = spC0 = spBC = spB8 = spB4 = var_s6 = var_s7 = 0; + } + + for (i = 0; i < 7; i++) { + if ((this->unk174 == 0) || (this->unk174 == 3)) { + if (i < 3) { + spD8[i].y = 0; + spD8[i].x = (s32)(Math_SinS((this->unk160 * spD4) + (i * spD0)) * spCC); + } else { + spD8[i].x = 0; + spD8[i].y = (s32)(Math_SinS((this->unk160 * spC8) + (i * spC4)) * spC0); + } + + if ((i == 4) || (i == 6)) { + spD8[i].z = (s32)(Math_SinS((this->unk160 * spBC) + (i * spB8)) * spB4 * 2.0f); + } else { + spD8[i].z = (s32)(Math_SinS((this->unk160 * spBC) + (i * spB8)) * spB4); + } + + var_s4 = var_s6; + var_s5 = var_s7; + } else { + if (this->unk174 == 1) { + var_s6 = 5; + var_s7 = 0x1000; + + spD8[i].x = D_809F1C60[i].x; + spD8[i].y = D_809F1C60[i].y; + spD8[i].z = D_809F1C60[i].z; + } else if (this->unk174 == 2) { + var_s6 = 1; + var_s7 = 0x2000; + + spD8[i].x = D_809F1C8C[i].x; + spD8[i].y = D_809F1C8C[i].y; + spD8[i].z = D_809F1C8C[i].z; + } + var_s4 = var_s6; + var_s5 = var_s7; + } + + Math_ApproachS(&this->unk19E[i].x, spD8[i].x, var_s6, var_s7); + Math_ApproachS(&this->unk19E[i].y, spD8[i].y, var_s6, var_s7); + Math_ApproachS(&this->unk19E[i].z, spD8[i].z, var_s6, var_s7); + } + + // There is some scope for which of var_s4,var_s5 and var_s6,var_s7 are used here + spA4 = (sp108->actor.world.pos.y - this->dyna.actor.world.pos.y) + 10.0f; + if (spA4 < 0.0f) { + Math_ApproachS(&this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer, var_s4, var_s5); + } + + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->unk35C, 1.0f, 0.1f, 0.1f); + + if (this->unk15C != 10) { + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 0x14, 0x800); + } + + switch (this->unk15C) { + case 0: + this->unk174 = 0; + this->skelAnime20.playSpeed = 1.0f; + if (spA4 < 0.0f) { + if (sp108->actor.speed > 10.0f) { + var_fv1 = 220.0f; + } else { + var_fv1 = 150.0f; + } + if ((this->unk162[0] == 0) && (sqrtf(this->dyna.actor.xyzDistToPlayerSq) <= var_fv1)) { + this->unk15C = 1; + this->unk162[0] = 10; + } + this->unk15E = 0; + } else { + sp103 = 1; + + if (sqrtf(this->dyna.actor.xyzDistToPlayerSq) <= 40.0f) { + this->unk15E++; + if (this->unk15E > 30) { + this->unk15C = 10; + this->unk162[0] = 30; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_ATTACK); + } + } else { + this->unk15E = 0; + } + } + if (!(this->unk160 & 3) && (Rand_ZeroOne() < 0.5f)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + break; + + case 10: + if (!(this->unk160 & 1)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + this->unk19C = (this->unk162[0] & 1) * 0x200; + this->unk174 = 3; + this->skelAnime20.playSpeed = 4.0f; + Math_ApproachS(&this->dyna.actor.shape.rot.x, -0x8000, 2, 0x2000); + Math_ApproachS(&this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer, 2, 0x2000); + if (this->unk162[0] == 0) { + this->unk15E = 0; + this->unk15C = 0; + this->unk162[0] = 100; + } + if (this->unk162[0] == 27) { + Math_Vec3f_Copy(&sp94, &this->dyna.actor.world.pos); + sp94.y += 40.0f; + EffectSsGSplash_Spawn(play, &sp94, NULL, NULL, 1, 2000); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_OUT_OF_WATER); + } + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + this->skelAnime20.playSpeed = 0.0f; + } + this->unk174 = 1; + if (this->unk162[0] == 0) { + this->unk15C = 2; + this->unk162[0] = 20; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_ATTACK); + } + break; + + case 2: + if (!(this->unk160 & 1)) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + this->unk19C = (this->unk162[0] & 1) * 0x200; + this->skelAnime20.playSpeed = 4.0f; + Math_ApproachF(&this->unk35C, 1.5f, 1.0f, 0.7f); + this->unk174 = 2; + if (this->unk162[0] == 0) { + this->unk15C = 0; + this->unk162[0] = 30; + } + break; + } + + var_s4_2 = func_809EECBC(this, play); + if ((var_s4_2 != 0) || (this->unk168 == 1)) { + Boss05* temp_v0_6; + + this->dyna.actor.params = BIO_DEKU_BABA_TYPE_2; + this->actionFunc = func_809EF9BC; + this->dyna.actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_800BC154(play, &play->actorCtx, &this->dyna.actor, ACTORCAT_BG); + if (this->unk168 != 0) { + var_s4_2 = 10; + } + if (var_s4_2 >= 10) { + temp_v0_6 = (Boss05*)Actor_SpawnAsChild( + &play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, BIO_DEKU_BABA_TYPE_3); + if (temp_v0_6 != NULL) { + Player* temp_v1 = GET_PLAYER(play); + if (temp_v1->lockOnActor == &this->dyna.actor) { + temp_v1->lockOnActor = &temp_v0_6->dyna.actor; + play->actorCtx.targetCtx.fairyActor = &temp_v0_6->dyna.actor; + play->actorCtx.targetCtx.lockOnActor = &temp_v0_6->dyna.actor; + } + + for (i = 0; i < 10; i++) { + temp_v0_6->skelAnime10.jointTable[i] = this->skelAnime10.jointTable[i]; + } + + for (i = 0; i < 20; i++) { + temp_v0_6->skelAnime20.jointTable[i] = this->skelAnime20.jointTable[i]; + } + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_DAMAGE); + if (var_s4_2 > 10) { + temp_v0_6->drawDmgEffState = var_s4_2 - 10; + } + } + } else if (var_s4_2 == 2) { + for (i = 0; i < 2; i++) { + temp_v0_6 = (Boss05*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, + this->unk324.x, this->unk324.y, this->unk324.z, this->unk330.x, + this->unk330.y, this->unk330.z, i + BIO_DEKU_BABA_TYPE_10); + if (temp_v0_6 != NULL) { + + for (j = 0; j < 20; j++) { + temp_v0_6->skelAnime20.jointTable[j] = this->skelAnime20.jointTable[j]; + } + + temp_v0_6->unk162[0] = (s32)(Rand_ZeroFloat(20.0f) + 20.0f); + } + } + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA_DEAD); + } + } + + if (sp103 == 0) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider2.base); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); + } + + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider1.base); +} + +void func_809EF9BC(Boss05* this, PlayState* play) { + Player* player = GET_PLAYER(play); + f32 distToPlayer = sqrtf(this->dyna.actor.xyzDistToPlayerSq); + s16 var_a1; + + if ((distToPlayer < 50.0f) && (player->actor.bgCheckFlags & 1)) { + var_a1 = (s32)(distToPlayer * 80.0f); + var_a1 = CLAMP_MAX(var_a1, 0x7D0); + // if (var_a1 > 0x7D0) { + // var_a1 = 0x7D0; + // } + Math_ApproachS(&this->unk178, var_a1, 0x14, 0x7D0); + Math_ApproachS(&this->unk176, this->dyna.actor.yawTowardsPlayer, 0x14, 0xFA0); + if ((this->unk160 % 16) == 0) { + EffectSsGRipple_Spawn(play, &this->dyna.actor.world.pos, 500, 1000, 0); + } + } else { + Math_ApproachS(&this->unk178, 0, 0x14, 0x100); + } +} + +void func_809EFAB4(Boss05* this, PlayState* play) { + s32 i; + Vec3f unusedPos; + Vec3f bubblePos; + Boss05* temp_v0; + Player* player; + + Actor_MoveWithGravity(&this->dyna.actor); + this->dyna.actor.world.pos.y -= 85.0f; + this->dyna.actor.prevPos.y -= 85.0f; + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x44); + this->dyna.actor.world.pos.y += 85.0f; + this->dyna.actor.prevPos.y += 85.0f; + + if (this->dyna.actor.bgCheckFlags & 0x20) { + this->dyna.actor.gravity = -0.3f; + this->dyna.actor.terminalVelocity = -5.0f; + } else { + this->dyna.actor.gravity = -2.0f; + this->dyna.actor.terminalVelocity = -20.0f; + } + + if (this->dyna.actor.bgCheckFlags & 0x40) { + this->dyna.actor.velocity.y = -3.0f; + this->dyna.actor.gravity = -0.3f; + this->dyna.actor.terminalVelocity = -5.0f; + Math_Vec3f_Copy(&unusedPos, &this->dyna.actor.world.pos); + unusedPos.y += 20.0f; + EffectSsGSplash_Spawn(play, &this->dyna.actor.world.pos, NULL, NULL, 1, 1000); + this->unk162[2] = 20; + } + + if (this->unk162[2] != 0) { + for (i = 0; i < 3; i++) { + bubblePos.x = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.x; + bubblePos.y = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.y; + bubblePos.z = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.z; + EffectSsBubble_Spawn(play, &bubblePos, 20.0f, 10.0f, 20.0f, 0.13f); + } + } + + if (this->dyna.actor.bgCheckFlags & 1) { + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && (this->unk17A != 0)) { + this->unk17A = 0; + } + + Math_ApproachZeroF(&this->unk198, 1.0f, 0.05f); + + if (this->unk198 == 0.0f) { + temp_v0 = (Boss05*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, + this->unk324.x, this->unk324.y, this->unk324.z, this->unk330.x, + this->unk330.y, this->unk330.z, BIO_DEKU_BABA_TYPE_4); + + if (temp_v0 != NULL) { + player = GET_PLAYER(play); + if (player->lockOnActor == &this->dyna.actor) { + player->lockOnActor = &temp_v0->dyna.actor; + play->actorCtx.targetCtx.fairyActor = &temp_v0->dyna.actor; + play->actorCtx.targetCtx.lockOnActor = &temp_v0->dyna.actor; + } + + for (i = 0; i < 20; i++) { + temp_v0->skelAnime20.jointTable[i] = this->skelAnime20.jointTable[i]; + } + + Actor_PlaySfx(&temp_v0->dyna.actor, NA_SE_EN_MIZUBABA_TRANSFORM); + } + Actor_Kill(&this->dyna.actor); + } + } +} + +void func_809EFE50(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + Boss05* this = THIS; + u8 takeDamage = false; + ColliderInfo* hitInfo; + + if ((this->unk16A == 0) && (this->collider1.elements[0].info.bumperFlags & BUMP_HIT)) { + this->collider1.elements[0].info.bumperFlags &= ~BUMP_HIT; + hitInfo = this->collider1.elements[0].info.acHitInfo; + if (hitInfo->toucher.dmgFlags & 0x300000) { // (DMG_NORMAL_SHIELD | DMG_LIGHT_RAY) + this->unk338 = -12.0f; + this->unk348 = this->dyna.actor.yawTowardsPlayer; + this->unk16A = 6; + return; + } + + this->unk16A = 10; + this->dyna.actor.speed = 0.0f; + this->unk338 = -20.0f; + this->unk348 = this->dyna.actor.yawTowardsPlayer; + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + + switch (this->dyna.actor.colChkInfo.damageEffect) { + case 1: + func_809F0A0C(this, play); + break; + + case 2: + this->drawDmgEffState = 1; + takeDamage = true; + break; + + case 3: + func_809F0A64(this, play); + this->drawDmgEffState = 10; + break; + + case 4: + this->drawDmgEffState = 20; + takeDamage = true; + break; + + default: + takeDamage = true; + break; + } + + if (takeDamage) { + u8 damage; // Probably fake? + + if ((this->actionFunc == func_809F0ABC) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->unk17A != 0)) { + func_809EE4E0(this, play); + this->drawDmgEffState = 0; + } + + damage = this->dyna.actor.colChkInfo.damage; + this->dyna.actor.colChkInfo.health -= damage; + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + Enemy_StartFinishingBlow(play, &this->dyna.actor); + } + + func_809F0708(this, play); + this->unk16C = 15; + } + } +} + +s32 func_809F0014(Boss05* this, PlayState* play) { + s16 yawDiff = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.shape.rot.y; + + if (ABS_ALT(yawDiff) < 0x3000) { + return true; + } else { + return false; + } +} + +void func_809F0058(Boss05* this, PlayState* play) { + if (func_809F0014(this, play) && (this->dyna.actor.xyzDistToPlayerSq <= SQ(200.0f)) && + (fabsf(this->dyna.actor.playerHeightRel) < 70.0f)) { + func_809F0474(this, play); + } +} + +void func_809F00CC(Boss05* this, PlayState* play) { + this->actionFunc = func_809F010C; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06006E50, -5.0f); +} + +void func_809F010C(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 2, 0x400); + Math_ApproachS(&this->dyna.actor.shape.rot.z, 0, 2, 0x400); + Math_ApproachF(&this->unk360, 1.0f, 1.0f, 0.5f); + Math_ApproachF(&this->unk364, 1.0f, 1.0f, 0.14f); + + if (this->unk364 == 1.0f) { + func_809F01CC(this, play); + } +} + +void func_809F01CC(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0244; + Animation_MorphToLoop(&this->skelAnime20, &D_06007488, -10.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(25.0f) + 25.0f); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA1_MOUTH); +} + +void func_809F0244(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + Math_ApproachS(&this->dyna.actor.shape.rot.x, 0, 2, 0x400); + Math_ApproachS(&this->dyna.actor.shape.rot.z, 0, 2, 0x400); + + if (this->unk162[0] == 0) { + func_809F02D0(this, play); + } + + func_809F0058(this, play); +} + +void func_809F02D0(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0374; + Animation_MorphToLoop(&this->skelAnime20, &D_06007908, 0.0f); + this->unk162[0] = (s32)(Rand_ZeroFloat(80.0f) + 60.0f); + this->unk34C.x = Rand_CenteredFloat(400.0f) + this->dyna.actor.world.pos.x; + this->unk34C.z = Rand_CenteredFloat(400.0f) + this->dyna.actor.world.pos.z; + this->unk358 = 0.0f; +} + +void func_809F0374(Boss05* this, PlayState* play) { + f32 deltaX; + f32 deltaZ; + + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_WALK - SFX_FLAG); + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->dyna.actor.speed, 5.0f, 1.0f, 2.0f); + deltaX = this->unk34C.x - this->dyna.actor.world.pos.x; + deltaZ = this->unk34C.z - this->dyna.actor.world.pos.z; + Math_ApproachS(&this->dyna.actor.world.rot.y, Math_Atan2S(deltaX, deltaZ), 5, (s32)this->unk358); + Math_ApproachF(&this->unk358, 2000.0f, 1.0f, 100.0f); + + if ((this->unk162[0] == 0) || ((SQ(deltaX) + SQ(deltaZ)) < 2500.0f)) { + func_809F01CC(this, play); + } + + func_809F0058(this, play); +} + +void func_809F0474(Boss05* this, PlayState* play) { + this->actionFunc = func_809F04C0; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06003448, 0.0f); + this->unk162[0] = 20; +} + +void func_809F04C0(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_VOICE - SFX_FLAG); + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + Math_ApproachS(&this->dyna.actor.world.rot.y, this->dyna.actor.yawTowardsPlayer, 5, 0x1000); + if (this->unk162[0] == 0) { + func_809F0538(this, play); + } +} + +void func_809F0538(Boss05* this, PlayState* arg1) { + this->actionFunc = func_809F0590; + Animation_MorphToLoop(&this->skelAnime20, &D_06000A5C, 0.0f); + this->unk162[0] = 60; + this->unk358 = 0.0f; +} + +void func_809F0590(Boss05* this, PlayState* play) { + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_VOICE - SFX_FLAG); + SkelAnime_Update(&this->skelAnime20); + Math_ApproachF(&this->dyna.actor.speed, 8.0f, 1.0f, 4.0f); + Math_ApproachS(&this->dyna.actor.world.rot.y, this->dyna.actor.yawTowardsPlayer, 5, (s32)this->unk358); + Math_ApproachF(&this->unk358, 4000.0f, 1.0f, 400.0f); + + if ((this->unk162[0] == 0) || (this->dyna.actor.xyzDistToPlayerSq <= SQ(150.0f))) { + func_809F0650(this, play); + } +} + +void func_809F0650(Boss05* this, PlayState* arg1) { + this->actionFunc = func_809F06B8; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_060006A4, 0.0f); + this->lastAnimFrame = Animation_GetLastFrame(&D_060006A4); + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_ATTACK); +} + +void func_809F06B8(Boss05* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime20); + if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + func_809F01CC(this, play); + } +} + +void func_809F0708(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0780; + Animation_MorphToPlayOnce(&this->skelAnime20, &D_06002F0C, 0.0f); + this->lastAnimFrame = Animation_GetLastFrame(&D_060006A4); + Actor_SetColorFilter(&this->dyna.actor, 0x4000, 120, 0, 30); +} + +void func_809F0780(Boss05* this, PlayState* play) { + s32 i; + s32 j; + Vec3f bubblePos; + Boss05* temp_v0; + + SkelAnime_Update(&this->skelAnime20); + if ((s8)this->dyna.actor.colChkInfo.health <= 0) { + if (Animation_OnFrame(&this->skelAnime20, 22.0f)) { + for (i = 0; i < 14; i++) { + temp_v0 = (Boss05*)Actor_SpawnAsChild( + &play->actorCtx, &this->dyna.actor, play, ACTOR_BOSS_05, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, i + BIO_DEKU_BABA_TYPE_10); + + if (temp_v0 != NULL) { + for (j = 0; j < 20; j++) { + temp_v0->skelAnime20.jointTable[j] = this->skelAnime20.jointTable[j]; + } + } + } + + for (i = 0; i < 20; i++) { + bubblePos.x = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.x; + bubblePos.y = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.y; + bubblePos.z = Rand_CenteredFloat(40.0f) + this->dyna.actor.world.pos.z; + EffectSsBubble_Spawn(play, &bubblePos, 20.0f, 10.0f, 20.0f, 0.13f); + } + + SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EN_MIZUBABA_DEAD); + Actor_Kill(&this->dyna.actor); + Item_DropCollectibleRandom(play, NULL, &this->dyna.actor.world.pos, 0xE0); + } + } else if (Animation_OnFrame(&this->skelAnime20, this->lastAnimFrame)) { + func_809F0474(this, play); + } +} + +void func_809F0A0C(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0ABC; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk162[0] = 40; + Actor_SetColorFilter(&this->dyna.actor, 0, 120, 0, 40); +} + +void func_809F0A64(Boss05* this, PlayState* play) { + this->actionFunc = func_809F0ABC; + Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_MIZUBABA2_DAMAGE); + this->unk162[0] = 80; + Actor_SetColorFilter(&this->dyna.actor, 0, 120, 0, 80); +} + +void func_809F0ABC(Boss05* this, PlayState* play) { + Math_ApproachZeroF(&this->dyna.actor.speed, 1.0f, 2.5f); + if (this->unk162[0] == 0) { + func_809F01CC(this, play); + } +} + +void func_809F0B0C(Boss05* this, PlayState* play) { + Actor_MoveWithGravity(&this->dyna.actor); + + if (this->unk15C == 0) { + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x44); + if (this->dyna.actor.bgCheckFlags & 0x20) { + this->unk15C = 1; + } else { + this->unk15C = 2; + } + } + + if (this->unk15C == 1) { + Math_ApproachF(&this->dyna.actor.velocity.y, 1.0f, 1.0f, 0.1f); + Math_ApproachZeroF(&this->dyna.actor.speed, 0.5f, 0.5f); + this->dyna.actor.shape.rot.x += this->unk500.x; + this->dyna.actor.shape.rot.y += this->unk500.y; + + if (this->unk162[0] == 0) { + Actor_Kill(&this->dyna.actor); + } + } else { + switch (this->unk15C) { + case 2: + this->dyna.actor.velocity.y = Rand_ZeroFloat(3.0f) + 3.0f; + this->dyna.actor.speed = Rand_CenteredFloat(5.0f) + 5.0f; + this->dyna.actor.world.rot.y = (s32)Rand_ZeroFloat(0x10000); + this->dyna.actor.gravity = -1.0f; + this->unk15C = 3; + break; + + case 3: + Actor_MoveWithGravity(&this->dyna.actor); + + if (this->unk324.y < (this->dyna.actor.floorHeight - 30.0f)) { + Actor_Kill(&this->dyna.actor); + } + break; + + default: + break; + } + } +} + +void Boss05_Update(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = (Boss05*)thisx; + s16 var_v0; + + this->unk160++; + + for (var_v0 = 0; var_v0 < 3; var_v0++) { + if (this->unk162[var_v0] != 0) { + this->unk162[var_v0]--; + } + } + + if (this->unk16A != 0) { + this->unk16A--; + } + + if (this->unk16C != 0) { + this->unk16C--; + } + if (this->unk168 != 0) { + this->unk168--; + } + + if (this->unk17A != 0) { + this->unk17A--; + } + + this->actionFunc(this, play); + + if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + Actor_MoveWithGravity(&this->dyna.actor); + Matrix_RotateYS(this->unk348, MTXMODE_NEW); + Matrix_MultVecZ(this->unk338, &this->unk33C); + this->dyna.actor.world.pos.x += this->unk33C.x; + this->dyna.actor.world.pos.z += this->unk33C.z; + Math_ApproachZeroF(&this->unk338, 1.0f, 1.0f); + Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 50.0f, 40.0f, 0x45); + func_809EFE50(&this->dyna.actor, play); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider1.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + } + + switch (this->drawDmgEffState) { + case 0: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->unk17A = 0; + this->drawDmgEffAlpha = 0.0f; + break; + + case 1: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + // fallthrough + case 2: + if (this->unk17A == 0) { + Math_ApproachZeroF(&this->drawDmgEffAlpha, 1.0f, 0.02f); + if (this->drawDmgEffAlpha == 0.0f) { + this->drawDmgEffState = 0; + } + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 0.1f, 0.5f); + } + break; + + case 10: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + this->dmgEffFrozenSteamScale = 2.0f; + // fallthrough + case 11: + if (this->unk17A == 0) { + func_809EE4E0(this, play); + this->drawDmgEffState = 0; + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 1.0f, 0.25f); + Math_ApproachF(&this->dmgEffFrozenSteamScale, 1.0f, 0.1f, 0.1f); + } + break; + + case 20: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->unk17A = 80; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffState++; + this->drawDmgEffScale = 0.0f; + break; + + case 21: + if (this->unk17A == 0) { + Math_ApproachZeroF(&this->drawDmgEffScale, 1.0f, 0.03f); + + if (this->drawDmgEffScale == 0.0f) { + this->drawDmgEffState = 0; + this->drawDmgEffAlpha = 0.0f; + } + } else { + Math_ApproachF(&this->drawDmgEffScale, 1.0f, 0.5f, 0.5f); + } + break; + } +} + +s8 D_809F1CB8[] = { -1, -1, 0, 1, 2, 3, 4, 5, 6, -1, -1, 0 }; + +s32 func_809F1050(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + s8 temp_v1; + + if (limbIndex == KREG(32)) { + if (!(this->unk160 & 3)) { + *dList = NULL; + } + + rot->x += KREG(33) * 0x100; + rot->y += KREG(34) * 0x100; + rot->z += KREG(35) * 0x100; + } + + if ((this->dyna.actor.params == BIO_DEKU_BABA_TYPE_1) && (limbIndex == 9)) { + *dList = NULL; + } + + if (limbIndex == 2) { + rot->x += this->unk19C; + } + + temp_v1 = D_809F1CB8[limbIndex]; + if (temp_v1 >= 0) { + rot->x = rot->x + this->unk19E[temp_v1].x; + rot->y = rot->y + this->unk19E[temp_v1].y; + rot->z = rot->z + this->unk19E[temp_v1].z; + } + + return false; +} + +Vec3f D_809F1CC4 = { 0.0f, -1400.0f, 600.0f }; + +void func_809F1170(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + MtxF mf; + Vec3f spherePos0; + Vec3f spherePos1; + + if (limbIndex == 4) { + Matrix_MultVec3f(&D_809F1CC4, &this->unk324); + + if (this->actionFunc == func_809EFAB4) { + Matrix_MultVec3f(&D_809F1CC4, &this->dyna.actor.focus.pos); + } + + Matrix_Get(&mf); + Matrix_MtxFToYXZRot(&mf, &this->unk330, false); + this->unk330.x += 0xF00; + } + + if (limbIndex == 2) { + Matrix_MultZero(&spherePos0); + func_809EE668(0, &this->collider2, &spherePos0); + } + + if (limbIndex == 3) { + Matrix_MultVecY(-500.0f, &spherePos1); + func_809EE668(1, &this->collider2, &spherePos1); + + if (this->actionFunc == func_809EEDE8) { + Matrix_MultVecY(1500.0f, &this->dyna.actor.focus.pos); + } + } +} + +s32 func_809F1284(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; +} + +Vec3f D_809F1CD0 = { 1600.0f, -300.0f, 0.0f }; +Vec3f D_809F1CDC = { 700.0f, 0.0f, 0.0f }; + +Vec3f D_809F2110; // bss + +void func_809F12A0(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex == 1) { + Matrix_MultVec3f(&D_809F1CD0, &D_809F2110); + func_809EE668(0, &this->collider1, &D_809F2110); + + if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + Matrix_MultVec3f(&D_809F1CDC, &thisx->focus.pos); + } + + if (this->drawDmgEffState != 0) { + Matrix_MultVec3f(&D_809F1CDC, &this->limbPos[0]); + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) { + this->limbPos[0].y -= 15.0f; + } + } + } +} + +void func_809F135C(PlayState* play, s32 limbIndex, Actor* thisx) { + Boss05* this = THIS; + + if ((limbIndex == 2) || (limbIndex == 3)) { + Matrix_Scale(this->unk35C, 1.0f, this->unk35C, MTXMODE_APPLY); + } + + if (limbIndex == 1) { + Matrix_Scale(this->unk360, this->unk360, this->unk360, MTXMODE_APPLY); + } + + if ((limbIndex >= 4) && (limbIndex < 20)) { + Matrix_Scale(this->unk364, this->unk364, this->unk364, MTXMODE_APPLY); + } +} + +s32 func_809F1404(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + if ((limbIndex >= 3) && (limbIndex < 9)) { + *dList = NULL; + } + + return false; +} + +s32 func_809F1430(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + if ((limbIndex == 1) || (limbIndex == 2) || (limbIndex == 9)) { + *dList = NULL; + } + + return false; +} + +void func_809F1464(PlayState* play, s32 limbIndex, Actor* thisx) { + Boss05* this = THIS; + + if ((limbIndex >= 3) && (limbIndex < 9)) { + Matrix_Scale(this->unk198, this->unk198, this->unk198, MTXMODE_APPLY); + } +} + +s32 D_809F1CE8[] = { 2, 3, 1, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19 }; + +s32 func_809F14AC(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex != D_809F1CE8[this->dyna.actor.params - BIO_DEKU_BABA_TYPE_10]) { + *dList = NULL; + } else if (this->unk15C >= 2) { + rot->x += this->unk160 * 0x3000; + rot->y += this->unk160 * 0x1A00; + rot->z += this->unk160 * 0x2000; + } + return false; +} + +void func_809F1550(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss05* this = THIS; + + if (limbIndex != D_809F1CE8[this->dyna.actor.params - BIO_DEKU_BABA_TYPE_10]) { + Matrix_MultZero(&this->unk324); + } +} + +void Boss05_Draw(Actor* thisx, PlayState* play) { + s32 pad; + Boss05* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + if (this->actionFunc == func_809EEDE8) { + SkelAnime_DrawFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1050, func_809F1170, &this->dyna.actor); + + if ((this->unk16C % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + Matrix_Translate(this->unk324.x, this->unk324.y, this->unk324.z, MTXMODE_NEW); + Matrix_RotateYS(this->unk330.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk330.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk330.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_2) { + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->unk176, MTXMODE_APPLY); + Matrix_RotateXS(this->unk178, MTXMODE_APPLY); + Matrix_RotateYS(-this->unk176, MTXMODE_APPLY); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1404, NULL, &this->dyna.actor); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_3) { + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime10.skeleton, this->skelAnime10.jointTable, + this->skelAnime10.dListCount, func_809F1430, func_809F1170, func_809F1464, + &this->dyna.actor); + + Matrix_Translate(this->unk324.x, this->unk324.y, this->unk324.z, MTXMODE_NEW); + Matrix_RotateYS(this->unk330.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk330.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk330.z, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + + Actor_DrawDamageEffects(play, &this->dyna.actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->dmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } else if (this->dyna.actor.params == BIO_DEKU_BABA_TYPE_4) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + if ((this->unk16C % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F1284, func_809F12A0, func_809F135C, + &this->dyna.actor); + + Actor_DrawDamageEffects(play, &this->dyna.actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->dmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } else if (this->dyna.actor.params >= BIO_DEKU_BABA_TYPE_10) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_06006240)); + + SkelAnime_DrawFlexOpa(play, this->skelAnime20.skeleton, this->skelAnime20.jointTable, + this->skelAnime20.dListCount, func_809F14AC, func_809F1550, &this->dyna.actor); + } + + POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Boss_05/z_boss_05.h b/src/overlays/actors/ovl_Boss_05/z_boss_05.h index 8f46476ea..51cafa079 100644 --- a/src/overlays/actors/ovl_Boss_05/z_boss_05.h +++ b/src/overlays/actors/ovl_Boss_05/z_boss_05.h @@ -7,11 +7,60 @@ struct Boss05; typedef void (*Boss05ActionFunc)(struct Boss05*, PlayState*); +typedef enum { + /* 0 */ BIO_DEKU_BABA_TYPE_0, + /* 0 */ BIO_DEKU_BABA_TYPE_1, + /* 0 */ BIO_DEKU_BABA_TYPE_2, + /* 0 */ BIO_DEKU_BABA_TYPE_3, + /* 0 */ BIO_DEKU_BABA_TYPE_4, + /* 0 */ BIO_DEKU_BABA_TYPE_10 = 10, // Fragments? +} BioDekuBabaType; + typedef struct Boss05 { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x2C]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ u8 unk15C; /* inferred */ + /* 0x15E */ s16 unk15E; /* inferred */ + /* 0x160 */ s16 unk160; /* inferred */ + /* 0x162 */ s16 unk162[3]; // timers + /* 0x168 */ s16 unk168; // timer + /* 0x16A */ s16 unk16A; // timer + /* 0x16C */ s16 unk16C; // timer /* 0x170 */ Boss05ActionFunc actionFunc; - /* 0x174 */ char unk_174[0x394]; + /* 0x174 */ u8 unk174; + /* 0x176 */ s16 unk176; + /* 0x178 */ s16 unk178; + /* 0x17A */ s16 unk17A; // timer + /* 0x17C */ f32 drawDmgEffScale; + /* 0x180 */ f32 dmgEffFrozenSteamScale; + /* 0x184 */ f32 drawDmgEffAlpha; + /* 0x188 */ u8 drawDmgEffState; // A bit more than just type, possibly we should name it as an internal type? + /* 0x189 */ u8 drawDmgEffType; + /* 0x18C */ Vec3f limbPos[1]; + /* 0x198 */ f32 unk198; + /* 0x19C */ s16 unk19C; + /* 0x19E */ Vec3s unk19E[7]; + /* 0x1C8 */ ColliderJntSph collider2; + /* 0x1E8 */ ColliderJntSphElement colliderElements2[2]; + /* 0x268 */ SkelAnime skelAnime10; + /* 0x2AC */ Vec3s jointTable10[10]; + /* 0x2E8 */ Vec3s morphTable10[10]; + /* 0x324 */ Vec3f unk324; // pos used for spawning and drawing + /* 0x330 */ Vec3s unk330; // rotation used for spawning and drawing + /* 0x338 */ f32 unk338; + /* 0x33C */ Vec3f unk33C; + /* 0x348 */ s16 unk348; + /* 0x34C */ Vec3f unk34C; + /* 0x35C */ f32 unk358; + /* 0x35C */ f32 unk35C; + /* 0x360 */ f32 unk360; + /* 0x364 */ f32 unk364; + /* 0x368 */ ColliderJntSph collider1; + /* 0x388 */ ColliderJntSphElement colliderElements1[1]; + /* 0x3C8 */ SkelAnime skelAnime20; + /* 0x40C */ Vec3s jointTable20[20]; + /* 0x484 */ Vec3s morphTable20[20]; + /* 0x4FC */ f32 lastAnimFrame; + /* 0x500 */ Vec3s unk500; } Boss05; // size = 0x508 #endif // Z_BOSS_05_H diff --git a/src/overlays/actors/ovl_Boss_06/z_boss_06.c b/src/overlays/actors/ovl_Boss_06/z_boss_06.c index 5ae65a343..887c3fcc6 100644 --- a/src/overlays/actors/ovl_Boss_06/z_boss_06.c +++ b/src/overlays/actors/ovl_Boss_06/z_boss_06.c @@ -267,7 +267,7 @@ void func_809F24C8(Boss06* this, PlayState* play) { this->subCamAt.z = 2860.0f; if (this->unk_1CA == 75) { - D_809F4970->unk_148 = 1; + D_809F4970->unk148 = 1; } sp4E = 17; break; diff --git a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c index c02184a4c..070c09b56 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c @@ -7,33 +7,61 @@ #include "z_boss_hakugin.h" #include "z64quake.h" #include "z64rumble.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h" +#include "overlays/actors/ovl_En_Hakurock/z_en_hakurock.h" +#include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h" +#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h" + +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BossHakugin*)thisx) -void BossHakugin_Init(Actor* thisx, PlayState* play); +#define GOHT_LIMB_FLAG(limbIndex) (1 << ((limbIndex)-1)) + +void BossHakugin_Init(Actor* thisx, PlayState* play2); void BossHakugin_Destroy(Actor* thisx, PlayState* play); void BossHakugin_Update(Actor* thisx, PlayState* play); +void func_80B0E548(Actor* thisx, PlayState* play2); void BossHakugin_Draw(Actor* thisx, PlayState* play); +void func_80B0E5A4(Actor* thisx, PlayState* play); + +void func_80B058C0(BossHakugin* this); +void func_80B05EE0(BossHakugin* this, PlayState* play); +void BossHakugin_GenShadowTex(u8* tex, BossHakugin* this); +void BossHakugin_DrawShadowTex(u8* tex, BossHakugin* this, PlayState* play); +void func_80B0D9CC(BossHakugin* this); +void func_80B0DFA8(BossHakugin* this); void func_80B08018(BossHakugin* this, PlayState* play); +void func_80B08124(BossHakugin* this); void func_80B0813C(BossHakugin* this, PlayState* play); void func_80B082AC(BossHakugin* this, PlayState* play); +void func_80B08550(BossHakugin* this, PlayState* play); void func_80B0863C(BossHakugin* this, PlayState* play); +void func_80B08848(BossHakugin* this, PlayState* play); void func_80B08960(BossHakugin* this, PlayState* play); +void func_80B08C1C(BossHakugin* this); void func_80B08CB8(BossHakugin* this, PlayState* play); +void func_80B09178(BossHakugin* this); void func_80B091D8(BossHakugin* this, PlayState* play); void func_80B094E0(BossHakugin* this, PlayState* play); void func_80B098BC(BossHakugin* this, PlayState* play); +void func_80B09A94(BossHakugin* this, PlayState* play); void func_80B09C78(BossHakugin* this, PlayState* play); +void func_80B09DFC(BossHakugin* this); void func_80B09E20(BossHakugin* this, PlayState* play); +void func_80B09E84(BossHakugin* this); void func_80B09EDC(BossHakugin* this, PlayState* play); +void func_80B09F7C(BossHakugin* this); void func_80B0A2A4(BossHakugin* this, PlayState* play); +void func_80B0A5EC(BossHakugin* this); void func_80B0A638(BossHakugin* this, PlayState* play); +void func_80B0A87C(BossHakugin* this); void func_80B0A8C4(BossHakugin* this, PlayState* play); -#if 0 ActorInit Boss_Hakugin_InitVars = { /**/ ACTOR_BOSS_HAKUGIN, /**/ ACTORCAT_BOSS, @@ -46,122 +74,299 @@ ActorInit Boss_Hakugin_InitVars = { /**/ BossHakugin_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[19] = { -static ColliderJntSphElementInit D_80B0E700[19] = { +static ColliderJntSphElementInit sJntSphElementsInit[19] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 16, { { 1300, 200, 0 }, 30 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_HEAD, { { 1300, 200, 0 }, 30 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 15, { { 1400, 300, 0 }, 35 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_THORAX, { { 1400, 300, 0 }, 35 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 2, { { 1600, -400, 0 }, 26 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_PELVIS, { { 1600, -400, 0 }, 26 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 6, { { 1700, 200, 400 }, 18 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_RIGHT_UPPER_LEG, { { 1700, 200, 400 }, 18 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 8, { { 1000, 0, 0 }, 10 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_RIGHT_LOWER_LEG, { { 1000, 0, 0 }, 10 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 9, { { 500, 0, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_RIGHT_HOOF, { { 500, 0, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 11, { { 1700, 200, -400 }, 18 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_LEFT_UPPER_LEG, { { 1700, 200, -400 }, 18 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 13, { { 1000, 0, 0 }, 10 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_LEFT_LOWER_LEG, { { 1000, 0, 0 }, 10 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 14, { { 500, 0, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_FRONT_LEFT_HOOF, { { 500, 0, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 21, { { 800, 0, 400 }, 15 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_RIGHT_THIGH, { { 800, 0, 400 }, 15 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 22, { { 500, 200, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_RIGHT_SHIN, { { 500, 200, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 24, { { 300, 0, 0 }, 8 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_RIGHT_PASTERN, { { 300, 0, 0 }, 8 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 25, { { 500, 100, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_RIGHT_HOOF, { { 500, 100, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 28, { { 800, 0, -400 }, 15 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_LEFT_THIGH, { { 800, 0, -400 }, 15 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 29, { { 500, 200, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_LEFT_SHIN, { { 500, 200, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 31, { { 300, 0, 0 }, 8 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_LEFT_PASTERN, { { 300, 0, 0 }, 8 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 32, { { 500, 100, 0 }, 9 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_BACK_LEFT_HOOF, { { 500, 100, 0 }, 9 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 16, { { 2400, -400, -2900 }, 12 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_HEAD, { { 2400, -400, -2900 }, 12 }, 270 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_HITMARK, OCELEM_ON, }, - { 16, { { 2400, -400, 2900 }, 12 }, 270 }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_HITMARK, + OCELEM_ON, + }, + { GOHT_LIMB_HEAD, { { 2400, -400, 2900 }, 12 }, 270 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B0E9AC = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_80B0E700, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// static ColliderTrisElementInit sTrisElementsInit[1] = { -static ColliderTrisElementInit D_80B0E9BC[1] = { +static ColliderTrisElementInit sTrisElementsInit[1] = { { - { ELEMTYPE_UNK5, { 0x20000000, 0x03, 0x08 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x20000000, 0x03, 0x08 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { { { 22.0f, 0.0f, 100.0f }, { 0.0f, 0.0f, -100.0f }, { -22.0f, 0.0f, 100.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B0E9F8 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, }, - ARRAY_COUNT(sTrisElementsInit), D_80B0E9BC, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + ARRAY_COUNT(sTrisElementsInit), + sTrisElementsInit, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80B0EA08 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_2, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK5, { 0x20000000, 0x00, 0x08 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_NONE, OCELEM_NONE, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK5, + { 0x20000000, 0x00, 0x08 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_NONE, + OCELEM_NONE, + }, { 1, { { 0, 0, 0 }, 23 }, 100 }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B0EA34 = { - { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x02, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x02, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 170, 40, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B0EA60 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -196,192 +401,2806 @@ static DamageTable D_80B0EA60 = { /* Powder Keg */ DMG_ENTRY(1, 0xC), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80B0EA80 = { 30, 80, 100, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 30, 80, 100, MASS_IMMOVABLE }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B0EAD8[] = { - ICHAIN_S8(hintId, 27, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 27, ICHAIN_CONTINUE), - ICHAIN_U8(targetMode, TARGET_MODE_5, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), +TexturePtr D_80B0EA88 = gGohtMetalPlateWithCirclePatternTex; + +static s8 sLimbToBodyParts[GOHT_LIMB_MAX] = { + BODYPART_NONE, // GOHT_LIMB_NONE + BODYPART_NONE, // GOHT_LIMB_ROOT + GOHT_BODYPART_PELVIS, // GOHT_LIMB_PELVIS + BODYPART_NONE, // GOHT_LIMB_THORAX_ROOT + BODYPART_NONE, // GOHT_LIMB_THORAX_WRAPPER + BODYPART_NONE, // GOHT_LIMB_FRONT_RIGHT_LEG_ROOT + GOHT_BODYPART_FRONT_RIGHT_UPPER_LEG, // GOHT_LIMB_FRONT_RIGHT_UPPER_LEG + BODYPART_NONE, // GOHT_LIMB_FRONT_RIGHT_LOWER_LEG_ROOT + GOHT_BODYPART_FRONT_RIGHT_LOWER_LEG, // GOHT_LIMB_FRONT_RIGHT_LOWER_LEG + GOHT_BODYPART_FRONT_RIGHT_HOOF, // GOHT_LIMB_FRONT_RIGHT_HOOF + BODYPART_NONE, // GOHT_LIMB_FRONT_LEFT_LEG_ROOT + GOHT_BODYPART_FRONT_LEFT_UPPER_LEG, // GOHT_LIMB_FRONT_LEFT_UPPER_LEG + BODYPART_NONE, // GOHT_LIMB_FRONT_LEFT_LOWER_LEG_ROOT + GOHT_BODYPART_FRONT_LEFT_LOWER_LEG, // GOHT_LIMB_FRONT_LEFT_LOWER_LEG + GOHT_BODYPART_FRONT_LEFT_HOOF, // GOHT_LIMB_FRONT_LEFT_HOOF + GOHT_BODYPART_THORAX, // GOHT_LIMB_THORAX + GOHT_BODYPART_HEAD, // GOHT_LIMB_HEAD + BODYPART_NONE, // GOHT_LIMB_JAW_ROOT + BODYPART_NONE, // GOHT_LIMB_JAW + BODYPART_NONE, // GOHT_LIMB_BACK_RIGHT_LEG_ROOT + BODYPART_NONE, // GOHT_LIMB_BACK_RIGHT_LEG_WRAPPER + GOHT_BODYPART_BACK_RIGHT_THIGH, // GOHT_LIMB_BACK_RIGHT_THIGH + GOHT_BODYPART_BACK_RIGHT_SHIN, // GOHT_LIMB_BACK_RIGHT_SHIN + BODYPART_NONE, // GOHT_LIMB_BACK_RIGHT_PASTERN_ROOT + BODYPART_NONE, // GOHT_LIMB_BACK_RIGHT_PASTERN + GOHT_BODYPART_BACK_RIGHT_HOOF, // GOHT_LIMB_BACK_RIGHT_HOOF + BODYPART_NONE, // GOHT_LIMB_BACK_LEFT_LEG_ROOT + BODYPART_NONE, // GOHT_LIMB_BACK_LEFT_LEG_WRAPPER + GOHT_BODYPART_BACK_LEFT_THIGH, // GOHT_LIMB_BACK_LEFT_THIGH + GOHT_BODYPART_BACK_LEFT_SHIN, // GOHT_LIMB_BACK_LEFT_SHIN + BODYPART_NONE, // GOHT_LIMB_BACK_LEFT_PASTERN_ROOT + BODYPART_NONE, // GOHT_LIMB_BACK_LEFT_PASTERN + GOHT_BODYPART_BACK_LEFT_HOOF, // GOHT_LIMB_BACK_LEFT_HOOF }; -#endif +s32 D_80B0EAB0[5] = { + GOHT_LIMB_BACK_LEFT_THIGH, GOHT_LIMB_BACK_RIGHT_PASTERN, GOHT_LIMB_JAW_ROOT, + GOHT_LIMB_FRONT_LEFT_LOWER_LEG, GOHT_LIMB_FRONT_RIGHT_UPPER_LEG, +}; + +Color_RGBA8 D_80B0EAC4 = { 250, 250, 250, 255 }; +Color_RGBA8 D_80B0EAC8 = { 180, 180, 180, 255 }; +Color_RGB8 D_80B0EACC = { 0, 150, 255 }; +Color_RGB8 D_80B0EAD0 = { 0, 255, 255 }; + +void BossHakugin_Init(Actor* thisx, PlayState* play2) { + static s32 sTextureDesegmented = false; + static InitChainEntry sInitChain[] = { + ICHAIN_S8(hintId, 27, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 27, ICHAIN_CONTINUE), + ICHAIN_U8(targetMode, TARGET_MODE_5, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), + }; + PlayState* play = play2; + BossHakugin* this = THIS; + Actor** actorPtr; + s32 pad; + s32 i; + + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(play, &this->skelAnime, &gGohtSkel, &gGohtRunAnim, this->jointTable, this->morphTable, + GOHT_LIMB_MAX); + if (!sTextureDesegmented) { + sTextureDesegmented = true; + D_80B0EA88 = Lib_SegmentedToVirtual(D_80B0EA88); + } + + Collider_InitAndSetJntSph(play, &this->unk_0484, &this->actor, &sJntSphInit, this->unk_04A4); + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + Collider_InitAndSetTris(play, &this->unk_2618[i].unk_14, &this->actor, &sTrisInit, &this->unk_2618[i].unk_34); + } + + Collider_InitAndSetSphere(play, &this->unk_37B8, &this->actor, &sSphereInit); + this->unk_37B8.dim.worldSphere.radius = 40; + Collider_InitAndSetCylinder(play, &this->unk_0964, &this->actor, &sCylinderInit); + this->unk_0964.dim.pos.x = (this->actor.world.pos.x - 50.0f); + this->unk_0964.dim.pos.y = this->actor.world.pos.y; + this->unk_0964.dim.pos.z = this->actor.world.pos.z; + this->unk_0964.dim.radius = 150; + this->unk_0964.dim.height = 300; + this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); + Lights_PointNoGlowSetInfo(&this->lightInfo, 0, 0, 0, 255, 255, 180, -1); + this->unk_01B4 = -1; + + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE)) { + func_80B05EE0(this, play); + Actor_Kill(&this->actor); + return; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_09B0); i++) { + actorPtr = &this->unk_09B0[i]; // fake? + *actorPtr = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_HAKUROCK, 0.0f, 0.0f, 0.0f, 0, 0, + 0, EN_HAKUROCK_TYPE_BOULDER); + } + + for (i = 0; i < ARRAY_COUNT(this->unk_09D0); i++) { + this->unk_09D0[i] = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_HAKUROCK, 0.0f, 0.0f, 0.0f, + 0, 0, 0, EN_HAKUROCK_TYPE_UNK_2); + } + + for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { + this->unk_09F8[i].unk_18 = -1; + } + + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->unk_01A0 = this->actor.shape.rot.y; + this->unk_01B0 = 0xFFFFFFFF; + + if (CHECK_EVENTINF(EVENTINF_53)) { + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_BOSS | SEQ_FLAG_ASYNC); + this->actor.world.pos.x = 0.0f; + func_80B08C1C(this); + } else if (CHECK_EVENTINF(EVENTINF_62)) { + this->unk_0193 = 255; + this->unk_01D4 = 2.7f; + func_80B058C0(this); + Animation_PlayOnce(&this->skelAnime, &gGohtThawAndBreakWallAnim); + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + func_80B08124(this); + } else { + this->unk_0193 = 255; + this->unk_01D4 = 2.7f; + func_80B058C0(this); + func_80B09E84(this); + } +} + +void BossHakugin_Destroy(Actor* thisx, PlayState* play) { + BossHakugin* this = THIS; + s32 pad; + s32 i; + + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); + Collider_DestroyJntSph(play, &this->unk_0484); + Collider_DestroyCylinder(play, &this->unk_0964); + + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + Collider_DestroyTris(play, &this->unk_2618[i].unk_14); + } + + Collider_DestroySphere(play, &this->unk_37B8); + AudioSfx_StopByPos(&this->unk_0458); + AudioSfx_StopByPos(&this->unk_0464); +} + +s32 func_80B0573C(Vec3f* arg0) { + f32 magnitude = Math3D_Vec3fMagnitude(arg0); + + if (magnitude < 0.0001f) { + return false; + } + + Math_Vec3f_Scale(arg0, 1.0f / magnitude); + return true; +} + +void func_80B057A4(Vec3f* arg0, Vec3f* arg1, f32 arg2) { + Vec3f sp34; + Vec3f sp28; + f32 temp_fa0 = (arg0->x * arg1->x) + (arg0->y * arg1->y) + (arg0->z * arg1->z); + f32 var_fv1; + + if (fabsf(temp_fa0) < 1.0f) { + var_fv1 = Math_FAcosF(temp_fa0); + } else if (temp_fa0 >= 1.0f) { + var_fv1 = 0.0f; + } else { + var_fv1 = M_PI; + } + + if (var_fv1 < arg2) { + arg2 = var_fv1; + } + + if (!(arg2 < (M_PI / 180.0f))) { + Math3D_CrossProduct(arg0, arg1, &sp34); + if (func_80B0573C(&sp34)) { + Matrix_RotateAxisF(arg2, &sp34, MTXMODE_NEW); + Matrix_MultVec3f(arg0, &sp28); + Math_Vec3f_Copy(arg0, &sp28); + } + } +} + +void func_80B058C0(BossHakugin* this) { + s32 i = 0; + Actor* last; + Actor* now = this->unk_09D0[i++]; + + now->params = 4; + now->world.pos.x = -500.0f; + now->world.pos.y = this->actor.world.pos.y; + now->world.pos.z = -1266.6666667f; // 3800 / 3 + now->shape.rot.y = this->actor.shape.rot.y + 0x4000; + + while (i < 6) { + last = now; + now = this->unk_09D0[i++]; + + now->params = 4; + now->world.pos.x = last->world.pos.x; + now->world.pos.y = this->actor.world.pos.y; + now->world.pos.z = last->world.pos.z - 133.333333f; // 4000 / 3 + now->shape.rot.y = last->shape.rot.y; + } + + while (i < ARRAY_COUNT(this->unk_09D0)) { + last = (i < 8) ? this->unk_09D0[i - 6] : this->unk_09D0[i - 4]; + now = this->unk_09D0[i++]; + + now->params = 4; + now->world.pos.x = this->actor.world.pos.x; + now->world.pos.y = this->actor.world.pos.y; + now->world.pos.z = last->world.pos.z; + now->shape.rot.y = this->actor.shape.rot.y - 0x4000; + } +} + +void func_80B05A64(BossHakugin* this, PlayState* play, s16 speed, s32 y, s16 duration) { + s16 quakeIndex; + + if (y > 0) { + quakeIndex = Quake_Request(play->cameraPtrs[play->activeCamId], QUAKE_TYPE_3); + Quake_SetSpeed(quakeIndex, speed); + Quake_SetPerturbations(quakeIndex, y, 0, 0, 0); + Quake_SetDuration(quakeIndex, duration); + Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100); + } +} + +void func_80B05B04(BossHakugin* this, PlayState* play) { + Vec3f sp34; + s32 var_v0; + f32 sp2C; + + if (((this->actionFunc == func_80B0813C) || (this->actionFunc == func_80B08018)) && (Rand_ZeroOne() < 0.1f)) { + sp2C = Rand_ZeroOne(); + var_v0 = (Rand_ZeroOne() < 0.5f) ? -1 : 1; + sp34.x = (var_v0 * (15.0f + (sp2C * 15.0f)) * 4.0f) + this->actor.world.pos.x; + + sp34.y = (((Rand_ZeroOne() * 90.0f) + 10.0f) * 2.7f) + this->actor.world.pos.y; + + sp2C = Rand_ZeroOne(); + var_v0 = (Rand_ZeroOne() < 0.5f) ? -1 : 1; + sp34.z = (var_v0 * (15.0f + (sp2C * 15.0f)) * 4.0f) + this->actor.world.pos.z; + + EffectSsKirakira_SpawnDispersed(play, &sp34, &gZeroVec3f, &gZeroVec3f, &D_80B0EAC4, &D_80B0EAC8, 2000, 5); + } +} + +void func_80B05CBC(BossHakugin* this, Player* player) { + if (!this->unk_0194 && (player->stateFlags3 & PLAYER_STATE3_80000) && + !(player->actor.bgCheckFlags & BGCHECKFLAG_GROUND) && (player->actor.velocity.y > 5.0f)) { + player->actor.velocity.y *= 1.3f; + player->linearVelocity *= 1.3f; + this->unk_0194 = true; + } else if (player->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + this->unk_0194 = false; + } +} + +void func_80B05D4C(BossHakugin* this) { + Vec3f* var_t0 = &this->actor.world.pos; + s32 i; + s16 var_t1 = 0; + + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + if (this->unk_2618[i].unk_0C == 255) { + var_t0 = &this->unk_2618[i].unk_00; + var_t1 = 5000; + break; + } + } + if (i == ARRAY_COUNT(this->unk_2618)) { + if (this->unk_01C8 > 0.0f) { + var_t0 = &this->unk_0380; + var_t1 = (this->unk_01C8 / 30.0f) * 5000.0f; + } else if ((this->unk_0192 == 3) || (this->unk_0192 == 2)) { + var_t0 = &this->unk_3734[0]; + var_t1 = 5000; + } else if (this->unk_0192 == 4) { + var_t0 = &this->unk_3734[this->unk_01AA]; + var_t1 = (10 - this->unk_01AA) * 500.0f; + } + } + Lights_PointNoGlowSetInfo(&this->lightInfo, var_t0->x, var_t0->y, var_t0->z, D_80B0EACC.r, D_80B0EACC.g, + D_80B0EACC.b, var_t1); +} + +void func_80B05EE0(BossHakugin* this, PlayState* play) { + s16 atan = Math_Atan2S_XY(this->actor.world.pos.z, this->actor.world.pos.x); + Vec3f warpPos; + Vec3f heartPos; + f32 sp50; + f32 sin; + f32 cos; + + if (atan > 0x4000) { + warpPos.x = 1400.0f; + warpPos.y = 0.0f; + warpPos.z = -1400.0f; + } else if (atan < -0x4000) { + warpPos.x = -1400.0f; + warpPos.y = 0.0f; + warpPos.z = -1400.0f; + } else if (atan > 0) { + warpPos.x = 1400.0f; + warpPos.y = -320.0f; + warpPos.z = 1400.0f; + } else { + warpPos.x = -1400.0f; + warpPos.y = -160.0f; + warpPos.z = 1400.0f; + } + + sp50 = this->unk_01B4 * 300.0f; + sin = Math_SinS(this->unk_019E); + cos = Math_CosS(this->unk_019E); + heartPos.x = ((100.0f * sin) + warpPos.x) + (sp50 * cos); + heartPos.z = ((100.0f * cos) + warpPos.z) - (sp50 * sin); + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, warpPos.x, warpPos.y, warpPos.z, 0, 0, 0, + 1); + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, heartPos.x, warpPos.y, heartPos.z, 0, 0, 0, + BHEART_PARAM_NORMAL); +} + +void func_80B0607C(BossHakugin* this, PlayState* play) { + CollisionPoly* sp8C = NULL; + CollisionPoly* sp88 = NULL; + s32 sp84; + s16 sp82; + s16 sp80; + s16 var_v0; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + Vec3f sp4C; + f32 sp48; + + sp58.x = this->actor.world.pos.x + (Math_SinS(this->unk_01A0) * (5.0f * this->actor.speed)); + sp58.y = this->actor.world.pos.y + 450.0f; + sp58.z = this->actor.world.pos.z + (Math_CosS(this->unk_01A0) * (5.0f * this->actor.speed)); + + sp4C.x = sp58.x - Math_CosS(this->unk_01A0) * 1000.0f; + sp4C.y = sp58.y; + sp4C.z = sp58.z + (Math_SinS(this->unk_01A0) * 1000.0f); + + if (BgCheck_EntityLineTest1(&play->colCtx, &sp58, &sp4C, &sp70, &sp8C, 1, 1, 0, 1, &sp84)) { + sp82 = + Math_Atan2S_XY(sp8C->normal.z * COLPOLY_NORMAL_FRAC, sp8C->normal.x * COLPOLY_NORMAL_FRAC) - this->unk_01A0; + this->unk_01BC = Math_Vec3f_DistXZ(&sp58, &sp70); + } else { + sp82 = 0; + this->unk_01BC = 30000.0f; + } + sp4C.x = (2.0f * sp58.x) - sp4C.x; + sp4C.z = (2.0f * sp58.z) - sp4C.z; + if (BgCheck_EntityLineTest1(&play->colCtx, &sp58, &sp4C, &sp64, &sp88, 1, 1, 0, 1, &sp84)) { + sp80 = + Math_Atan2S_XY(sp88->normal.z * COLPOLY_NORMAL_FRAC, sp88->normal.x * COLPOLY_NORMAL_FRAC) - this->unk_01A0; + this->unk_01C0 = Math_Vec3f_DistXZ(&sp58, &sp64); + } else { + sp80 = 0; + this->unk_01C0 = 30000.0f; + } + if (this->unk_01B4 == 1) { + this->unk_01C0 -= 50.0f; + } else { + this->unk_01BC -= 50.0f; + } + if (this->unk_01BC <= 89.100006f) { + sp48 = (this->unk_01B4 == 1) ? 89.100006f : 139.1f; + this->actor.world.pos.x = + (sp70.x + (sp48 * Math_CosS(this->unk_01A0))) - (Math_SinS(this->unk_01A0) * (5.0f * this->actor.speed)); + this->actor.world.pos.z = + (sp70.z - (sp48 * Math_SinS(this->unk_01A0))) - (Math_CosS(this->unk_01A0) * (5.0f * this->actor.speed)); + } else if (this->unk_01C0 <= 89.100006f) { + sp48 = (this->unk_01B4 == 1) ? 139.1f : 89.100006f; + this->actor.world.pos.x = + (sp64.x - (sp48 * Math_CosS(this->unk_01A0))) - (Math_SinS(this->unk_01A0) * (5.0f * this->actor.speed)); + this->actor.world.pos.z = + (sp64.z + (sp48 * Math_SinS(this->unk_01A0))) - (Math_CosS(this->unk_01A0) * (5.0f * this->actor.speed)); + } + if ((this->unk_01C0 < 30000.0f) && (this->unk_01BC < 30000.0f)) { + var_v0 = (s16)(sp82 + sp80) >> 1; + if (((this->unk_01B4 == 1) && (var_v0 < 0)) || ((this->unk_01B4 == -1) && (var_v0 > 0))) { + this->unk_01A0 += var_v0; + } + } +} + +void func_80B06558(BossHakuginUnkStruct_2618* arg0) { + s32 i; + Vec3f sp38[3]; + + Matrix_SetTranslateRotateYXZ(arg0->unk_00.x, arg0->unk_00.y, arg0->unk_00.z, &arg0->unk_0E); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + for (i = 0; i < 3; i++) { + Matrix_MultVec3f(&sTrisElementsInit[0].dim.vtx[i], &sp38[i]); + } + Collider_SetTrisVertices(&arg0->unk_14, 0, &sp38[0], &sp38[1], &sp38[2]); +} + +void func_80B06600(BossHakugin* this, Vec3f* arg1, PlayState* play) { + s32 i; + Player* player = GET_PLAYER(play); + CollisionPoly* spD4; + Vec3f spC8; + Vec3f spBC; + Vec3f spB0; + Vec3f spA4; + Vec3f sp98; + Vec3f sp8C; + BossHakuginUnkStruct_2618* effect; + s32 sp84; + + Math_Vec3f_Copy(&spC8, arg1); + spBC.x = player->actor.world.pos.x - (Math_SinS(this->actor.shape.rot.y) * 50.0f); + spBC.y = player->actor.world.pos.y + 40.0f; + spBC.z = player->actor.world.pos.z - (Math_CosS(this->actor.shape.rot.y) * 50.0f); + Actor_OffsetOfPointInActorCoords(&this->actor, &sp98, &spBC); + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_COMMON_THUNDER_THR); + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + effect = &this->unk_2618[i]; + Actor_OffsetOfPointInActorCoords(&this->actor, &sp8C, &spC8); + if (sp98.z < sp8C.z) { + effect->unk_0E.y = this->actor.shape.rot.y + ((s32)Rand_Next() >> 0x13); + } else { + effect->unk_0E.y = Math_Vec3f_Yaw(&spC8, &spBC) + ((s32)Rand_Next() >> 0x13); + } + effect->unk_0E.x = Math_Vec3f_Pitch(&spC8, &spBC) + ((s32)Rand_Next() >> 0x13); + effect->unk_0E.z = 0; + effect->unk_00.x = spC8.x + (80.0f * Math_CosS(effect->unk_0E.x) * Math_SinS(effect->unk_0E.y)); + effect->unk_00.y = spC8.y - (80.0f * Math_SinS(effect->unk_0E.x)); + effect->unk_00.z = spC8.z + (80.0f * Math_CosS(effect->unk_0E.x) * Math_CosS(effect->unk_0E.y)); + spB0.x = (2.0f * effect->unk_00.x) - spC8.x; + spB0.y = (2.0f * effect->unk_00.y) - spC8.y; + spB0.z = (2.0f * effect->unk_00.z) - spC8.z; + if (BgCheck_EntityLineTest1(&play->colCtx, &spC8, &spB0, &spA4, &spD4, 0, 1, 0, 1, &sp84)) { + effect->unk_0E.x -= 0x2000; + effect->unk_00.x = spC8.x + (80.0f * Math_CosS(effect->unk_0E.x) * Math_SinS(effect->unk_0E.y)); + effect->unk_00.y = spC8.y - (80.0f * Math_SinS(effect->unk_0E.x)); + effect->unk_00.z = spC8.z + (80.0f * Math_CosS(effect->unk_0E.x) * Math_CosS(effect->unk_0E.y)); + spC8.x = (2.0f * effect->unk_00.x) - spC8.x; + spC8.y = (2.0f * effect->unk_00.y) - spC8.y; + spC8.z = (2.0f * effect->unk_00.z) - spC8.z; + } else { + Math_Vec3f_Copy(&spC8, &spB0); + } + effect->unk_0C = 255 + 20 * (i + 1); + func_80B06558(effect); + effect->unk_0E.z = (s32)Rand_Next() >> 0x10; + } +} + +void func_80B0696C(BossHakugin* this, Vec3f* arg1) { + s32 i; + BossHakuginEffect* temp_s0; + + for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { + temp_s0 = &this->unk_09F8[i]; + if (temp_s0->unk_18 < 0) { + s16 sp2E; + s16 sp2C; + f32 sp28; + + Math_Vec3f_Copy(&temp_s0->unk_0, arg1); + sp2C = Rand_S16Offset(0x1000, 0x3000); + sp2E = this->actor.shape.rot.y + ((s32)Rand_Next() >> 0x12) + 0x8000; + sp28 = Rand_ZeroFloat(5.0f) + 7.0f; + temp_s0->unk_C.x = sp28 * Math_CosS(sp2C) * Math_SinS(sp2E); + temp_s0->unk_C.y = sp28 * Math_SinS(sp2C); + temp_s0->unk_C.z = sp28 * Math_CosS(sp2C) * Math_CosS(sp2E); + temp_s0->unk_0.x = arg1->x + (Rand_ZeroFloat(3.0f) * temp_s0->unk_C.x); + temp_s0->unk_0.y = arg1->y + (Rand_ZeroFloat(3.0f) * temp_s0->unk_C.y); + temp_s0->unk_0.z = arg1->z + (Rand_ZeroFloat(3.0f) * temp_s0->unk_C.z); + temp_s0->unk_24 = (Rand_ZeroFloat(6.0f) + 15.0f) * 0.0001f; + temp_s0->unk_18 = 40; + temp_s0->unk_1A = 0; + break; + } + } +} + +void func_80B06B20(BossHakugin* this, Vec3f* arg1) { + Actor* sp1C; + s32 i; + + if (((this->unk_044C.z < -200.0f) && (this->actor.speed > 10.0f) && (this->unk_018D == 0) && + (Rand_ZeroOne() < 0.4f))) { + this->unk_018D = 4; + } else { + if (this->unk_018D > 0) { + this->unk_018D--; + } + return; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_09B0); i++) { + sp1C = this->unk_09B0[i]; + + if (sp1C->params == 0) { + Math_Vec3f_Copy(&sp1C->world.pos, arg1); + sp1C->params = 1; + break; + } + } +} + +void func_80B06C08(BossHakugin* this) { + s32 i; + + if ((this->unk_018E == 0) && (this->actor.colChkInfo.health < 20) && (Rand_ZeroOne() < 0.35f)) { + this->unk_018E = 4; + } else { + if (this->unk_018E > 0) { + this->unk_018E--; + } + return; + } + for (i = 0; i < ARRAY_COUNT(this->unk_09D0); i++) { + Actor* tmp = this->unk_09D0[i]; + + if (tmp->params == 0) { + tmp->params = 2; + return; + } + } +} + +void func_80B06D38(BossHakugin* this, PlayState* play) { + EnBom* sp44; + s16 temp_a1; + + if ((this->actor.speed > 10.0f) && ((s32)this->actor.colChkInfo.health < 10) && (this->unk_018F == 0) && + (Rand_ZeroOne() < 0.35f)) { + this->unk_018F = 4; + } else { + if (this->unk_018F > 0) { + this->unk_018F--; + } + return; + } + sp44 = (EnBom*)Actor_Spawn( + &play->actorCtx, play, ACTOR_EN_BOM, + this->unk_0484.elements[1].dim.worldSphere.center.x - (100.0f * Math_SinS(this->actor.shape.rot.y)), + this->unk_0484.elements[1].dim.worldSphere.center.y + 100.0f, + this->unk_0484.elements[1].dim.worldSphere.center.z - (Math_CosS(this->actor.shape.rot.y) * 100.0f), 0, 0, 0, + 0); + if (sp44 != NULL) { + temp_a1 = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - 0x8000; + if (temp_a1 > 0x2000) { + sp44->actor.world.rot.y = this->actor.shape.rot.y + 0xA000; + } else if (temp_a1 < -0x2000) { + sp44->actor.world.rot.y = this->actor.shape.rot.y + 0x6000; + } else { + sp44->actor.world.rot.y = this->actor.yawTowardsPlayer; + } + + sp44->timer = (Rand_Next() >> 0x1C) + 17; + sp44->actor.velocity.y = 2.0f; + sp44->actor.speed = this->actor.xzDistToPlayer * 0.01f; + sp44->actor.speed = CLAMP(sp44->actor.speed, 6.0f, 12.0f); + + Actor_SetScale(&sp44->actor, 0.02f); + } +} + +void func_80B06F48(BossHakugin* this, PlayState* play) { + BossHakuginFhgFlashUnkStruct* iter; + BossHakuginFhgFlashUnkStruct* iter2; + BossHakuginFhgFlashUnkStruct* iter3; + Vec3f spA0; + s32 sp9C = this->unk_0191 + 3; + s32 var_s4; + s32 i; + s32 j; + s32 pad; + + if (sp9C >= ARRAY_COUNT(this->unk_3158[0])) { + sp9C = 0; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_3158); i++) { + if (((15 - (3 * i)) < this->actor.colChkInfo.health) || !(GOHT_LIMB_FLAG(D_80B0EAB0[i]) & this->unk_01B0)) { + break; + } + + iter3 = &this->unk_3158[i][sp9C]; + iter2 = &this->unk_3158[i][this->unk_0191]; + + Math_Vec3f_Diff(&iter3->unk_00, &iter2->unk_00, &spA0); + + spA0.y -= 3.5f; + + var_s4 = Math3D_Vec3fMagnitude(&spA0) / 10.0f; + if (var_s4 > 1) { + if (var_s4 > 3) { + var_s4 = 3; + } + Math_Vec3f_Scale(&spA0, 1.0f / var_s4); + } else { + var_s4 = 1; + } + + for (j = 0; j < var_s4; j++) { + iter = &this->unk_3158[i][this->unk_0191 + j]; + + iter->unk_00.x = Rand_CenteredFloat(20.0f) + (iter2->unk_00.x + (spA0.x * j)); + iter->unk_00.y = Rand_CenteredFloat(20.0f) + (iter2->unk_00.y + (spA0.y * j)); + iter->unk_00.z = Rand_CenteredFloat(20.0f) + (iter2->unk_00.z + (spA0.z * j)); + iter->unk_0C = 0.01f; + iter->unk_10 = 150; + iter->unk_12 = 5 - j; + } + + if ((play->gameplayFrames % 2) != 0) { + EffectSsFhgFlash_SpawnShock(play, &this->actor, &this->unk_3158[i][this->unk_0191].unk_00, 250, + i + FHGFLASH_SHOCK_GOHT_2); + } + } + + sp9C = this->unk_0191 - 3; + if (sp9C < 0) { + this->unk_0191 = 12; + } else { + this->unk_0191 = sp9C; + } +} + +s32 func_80B0728C(BossHakugin* this) { + s16 rand = (Rand_Next() >> 0x12) + 0x4000; + + this->unk_0198 += rand; + if (this->unk_01A8 == 5) { + if (Math_SmoothStepToS(&this->unk_01A6, -0x900, 4, 0x200, 0x80) == 0) { + this->unk_01A8--; + } + + this->unk_01C8 = (this->unk_01A6 + 0x480) * -0.026041666f; // 30 / 0x480 + this->unk_01C8 = CLAMP_MIN(this->unk_01C8, 0.001f); + + this->unk_01D0 = (this->unk_01A6 - 0x700) * -0.00021059783f; // 0.62 / 0xB80 + this->unk_01D0 = CLAMP_MAX(this->unk_01D0, 0.62f); + + if (this->unk_01D0 > 0.0f) { + this->unk_01CC = -100.0f - (((0.62f / this->unk_01D0) - 1.0f) * 200.0f); + } else { + this->unk_01CC = -200.0f; + } + + } else if (this->unk_01A8 > 0) { + this->unk_01A8--; + } else if (Math_ScaledStepToS(&this->unk_01A6, 0x700, 0x380)) { + this->unk_01D0 = (0x700 - this->unk_01A6) / 4096.0f * 0.62f; + return true; + } + + return false; +} + +void func_80B07450(BossHakugin* this, PlayState* play) { + Vec3f velocity; + Vec3f pos; + f32 temp; + s32 i; + + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_FOOTSTEP_OLD); + Math_Vec3f_Copy(&pos, &this->bodyPartsPos[sLimbToBodyParts[GOHT_LIMB_FRONT_LEFT_HOOF]]); + if (this->actor.xzDistToPlayer < 1500.0f) { + temp = (1500.0f - this->actor.xzDistToPlayer) * (1.0f / 1500.0f); + func_80B05A64(this, play, 17000, 6.5f * temp, 10); + } + + func_80B06C08(this); + } else if (Animation_OnFrame(&this->skelAnime, 2.0f)) { + Math_Vec3f_Copy(&pos, &this->bodyPartsPos[sLimbToBodyParts[GOHT_LIMB_BACK_LEFT_HOOF]]); + func_80B06B20(this, &pos); + } else if (Animation_OnFrame(&this->skelAnime, 3.0f)) { + Math_Vec3f_Copy(&pos, &this->bodyPartsPos[sLimbToBodyParts[GOHT_LIMB_FRONT_RIGHT_HOOF]]); + func_80B06D38(this, play); + } else if (Animation_OnFrame(&this->skelAnime, 11.0f)) { + Math_Vec3f_Copy(&pos, &this->bodyPartsPos[sLimbToBodyParts[GOHT_LIMB_BACK_RIGHT_HOOF]]); + func_80B06B20(this, &pos); + } else { + return; + } + + velocity.x = Math_SinS(this->actor.shape.rot.y) * -1.0f; + velocity.y = 1.0f; + velocity.z = Math_CosS(this->actor.shape.rot.y) * -1.0f; + pos.x += 40.0f * velocity.x; + pos.y += 5.0f; + pos.z += 40.0f * velocity.z; + func_800B12F0(play, &pos, &velocity, &gZeroVec3f, Rand_S16Offset(650, 100), Rand_S16Offset(20, 10), 30); + for (i = 0; i < 4; i++) { + func_80B0696C(this, &pos); + } +} + +void func_80B07700(BossHakugin* this, PlayState* play, s32 arg2) { + Vec3f vel; + Vec3f pos; + + if (arg2 != 0) { + vel.y = (this->unk_019C - 30) * (1 / 70.0f); + } else { + vel.y = 0.1f; + } + + vel.x = Rand_CenteredFloat(2.0f) * vel.y; + vel.z = Rand_CenteredFloat(2.0f) * vel.y; + + pos.x = ((vel.x >= 0.0f ? 1.0f : -1.0f) * (Rand_ZeroFloat(20.0f) + 5.0f) * 4.0f) + this->unk_0964.dim.pos.x; + pos.z = ((vel.z >= 0.0f ? 1.0f : -1.0f) * (Rand_ZeroFloat(20.0f) + 5.0f) * 4.0f) + this->unk_0964.dim.pos.z; + if (arg2 != 0) { + pos.y = this->unk_0964.dim.pos.y + (this->unk_0964.dim.height * vel.y); + } else { + pos.y = (Rand_ZeroFloat(this->unk_0964.dim.height) * 0.8f) + this->unk_0964.dim.pos.y; + } + vel.y += 0.8f; + + EffectSsIceSmoke_Spawn(play, &pos, &vel, &gZeroVec3f, 600); +} + +s32 func_80B0791C(BossHakugin* this, PlayState* play) { + Player* sp34 = GET_PLAYER(play); + s16 var_v1; + s32 var_v0_2; + f32 sp28; + f32 sp24; + + if (this->unk_044C.z > 0.0f) { + return false; + } + var_v1 = this->unk_01A0 - Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)); + var_v0_2 = ABS_ALT(var_v1); + + if (var_v0_2 < 0x4000) { + if (var_v0_2 < 0x1800) { + this->unk_018C = 0; + } + return false; + } + if (this->unk_018C == 1) { + return false; + } + sp24 = this->actor.world.pos.x * this->unk_01B4; + sp28 = this->actor.world.pos.z * this->unk_01B4; + if (((sp34->actor.world.pos.x > 1200.0f) && (sp34->actor.world.pos.z < 1200.0f) && + (sp34->actor.world.pos.z > -1200.0f) && (this->actor.world.pos.x < 0.0f) && (sp28 > 1200.0f)) || + ((sp34->actor.world.pos.x < -1200.0f) && (sp34->actor.world.pos.z < 1200.0f) && + (sp34->actor.world.pos.z > -1200.0f) && (this->actor.world.pos.x > 0.0f) && (sp28 < -1200.0f)) || + ((sp34->actor.world.pos.z > 1200.0f) && (sp34->actor.world.pos.x < 1200.0f) && + (sp34->actor.world.pos.x > -1200.0f) && (this->actor.world.pos.z < 0.0f) && (sp24 < -1200.0f)) || + ((sp34->actor.world.pos.z < -1200.0f) && (sp34->actor.world.pos.x < 1200.0f) && + (sp34->actor.world.pos.x > -1200.0f) && (this->actor.world.pos.z > 0.0f) && (sp24 > 1200.0f))) { + return true; + } + return false; +} + +void func_80B07B88(BossHakugin* this, PlayState* play) { + if (this->unk_0196 == 10) { + this->unk_0196 = 0; + this->unk_01E4 = 0.0f; + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, GOHT_BODYPART_MAX, 3, 0.7f, 0.5f); + } +} + +void func_80B07BFC(BossHakugin* this, PlayState* play, s32 arg2) { + if (this->actor.colChkInfo.damageEffect == 0x2) { + this->unk_0196 = 0; + this->unk_01E4 = 3.0f; + this->unk_01DC = 2.5f; + } else if (this->actor.colChkInfo.damageEffect == 0x4) { + this->unk_0196 = 20; + this->unk_01E4 = 3.0f; + this->unk_01DC = 2.5f; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->unk_0484.elements[arg2].info.bumper.hitPos.x, + this->unk_0484.elements[arg2].info.bumper.hitPos.y, + this->unk_0484.elements[arg2].info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_PARAMS(CLEAR_TAG_LARGE_LIGHT_RAYS)); + } else if (this->actor.colChkInfo.damageEffect == 0x3) { + this->unk_0196 = 10; + this->unk_01DC = 2.5f; + this->unk_01E0 = 3.75f; + this->unk_01E4 = 1.0f; + } else if (this->actor.colChkInfo.damageEffect == 0xD) { + this->unk_0196 = 21; + this->unk_01DC = 2.5f; + this->unk_01E4 = 3.0f; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->unk_0484.elements[arg2].info.bumper.hitPos.x, + this->unk_0484.elements[arg2].info.bumper.hitPos.y, + this->unk_0484.elements[arg2].info.bumper.hitPos.z, 0, 0, 3, + CLEAR_TAG_PARAMS(CLEAR_TAG_LARGE_LIGHT_RAYS)); + } +} + +void func_80B07DA4(BossHakugin* this, PlayState* play, f32 arg2, s16 arg3) { + Camera* camera = Play_GetCamera(play, this->unk_01AC); + Vec3f sp38; + Vec3f sp2C; + + Math_Vec3f_Diff(&camera->at, &camera->eye, &sp38); + Math_Vec3f_StepTo(&camera->eye, &this->unk_038C, arg2); + + if (func_80B0573C(&sp38)) { + sp2C.x = Math_CosS(this->unk_037A.x) * Math_SinS(this->unk_037A.y); + sp2C.y = Math_SinS(this->unk_037A.x); + sp2C.z = Math_CosS(this->unk_037A.x) * Math_CosS(this->unk_037A.y); + func_80B057A4(&sp38, &sp2C, BINANG_TO_RAD(arg3)); + } + + camera->at.x = camera->eye.x + (50.0f * sp38.x); + camera->at.y = camera->eye.y + (50.0f * sp38.y); + camera->at.z = camera->eye.z + (50.0f * sp38.z); + Play_SetCameraAtEye(play, this->unk_01AC, &camera->at, &camera->eye); +} + +void func_80B07EEC(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Vec3f sp20; + + Animation_PlayOnce(&this->skelAnime, &gGohtThawAndBreakWallAnim); + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + this->unk_01AC = CutsceneManager_GetCurrentSubCamId(this->actor.csId); + sp20.x = player->actor.focus.pos.x; + sp20.y = player->actor.focus.pos.y; + sp20.z = player->actor.focus.pos.z; + this->unk_038C.x = (Math_SinS(player->actor.shape.rot.y) * 70.0f) + player->actor.focus.pos.x; + this->unk_038C.y = player->actor.focus.pos.y + 20.0f; + this->unk_038C.z = (Math_CosS(player->actor.shape.rot.y) * 70.0f) + player->actor.focus.pos.z; + Play_SetCameraAtEye(play, this->unk_01AC, &sp20, &this->unk_038C); + this->unk_037A.x = Math_Atan2S_XY(70.0f, -20.0f); + this->unk_037A.y = player->actor.shape.rot.y + 0x8000; + func_800B7298(play, &this->actor, PLAYER_CSACTION_21); + this->unk_019C = 0; + this->actionFunc = func_80B08018; +} + +void func_80B08018(BossHakugin* this, PlayState* play) { + static Vec3f D_80B0EAE8 = { 492.0f, 28.0f, -1478.0f }; + + this->unk_019C++; + if (this->unk_019C == 30) { + this->unk_038C.x = 417.0f; + this->unk_038C.y = 40.0f; + this->unk_038C.z = -1417.0f; + Play_SetCameraAtEye(play, this->unk_01AC, &D_80B0EAE8, &this->unk_038C); + func_800BE33C(&this->unk_038C, &D_80B0EAE8, &this->unk_037A, true); + } else if (this->unk_019C == 50) { + this->unk_037A.x = 0x1500; + } else if (this->unk_019C == 120) { + CutsceneManager_Stop(this->actor.csId); + SET_EVENTINF(EVENTINF_62); + func_80B08124(this); + return; + } + + if (this->unk_019C > 30) { + func_80B07DA4(this, play, 5.0f, 0xC0); + } +} + +void func_80B08124(BossHakugin* this) { + this->unk_019C = 0; + this->actionFunc = func_80B0813C; +} + +void func_80B0813C(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (!(player->stateFlags2 & PLAYER_STATE2_4000)) { + DECR(this->unk_019C); + } + + if ((this->unk_0964.base.acFlags & AC_HIT) && (this->unk_0964.info.acHitInfo->toucher.dmgFlags == DMG_FIRE_ARROW)) { + this->unk_0964.base.atFlags &= ~AT_HIT; + this->unk_0964.base.acFlags &= ~AC_HIT; + this->unk_0964.base.ocFlags1 &= ~OC1_HIT; + func_80B09E84(this); + return; + } + + if (this->unk_0964.base.atFlags & AT_HIT) { + this->unk_019C = 40; + this->unk_0964.base.atFlags &= ~AT_HIT; + } + + if (this->unk_019C == 0) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_0964.base); + } + + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_0964.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_0964.base); + this->unk_01A4 = 20; +} + +void func_80B0825C(BossHakugin* this) { + this->unk_019C = 100; + this->unk_01AC = CutsceneManager_GetCurrentSubCamId(this->actor.csId); + Play_EnableMotionBlur(140); + this->actionFunc = func_80B082AC; +} + +void func_80B082AC(BossHakugin* this, PlayState* play) { + Vec3f eye; + Vec3f at; + s32 temp_v1; + + this->unk_019C--; + if ((this->unk_019C >= 30) && ((this->unk_019C % 2) != 0)) { + func_80B07700(this, play, 1); + } else if ((this->unk_019C % 4) == 0) { + func_80B07700(this, play, 0); + } + + if (this->unk_019C == 99) { + at.x = 479.0f; + at.y = 181.0f; + at.z = -1637.0f; + eye.x = 328.0f; + eye.y = 164.0f; + eye.z = -1693.0f; + Play_SetCameraAtEye(play, this->unk_01AC, &at, &eye); + } else if (this->unk_019C == 75) { + at.x = 693.0f; + at.y = 162.0f; + at.z = -1550.0f; + eye.x = 638.0f; + eye.y = 200.0f; + eye.z = -1407.0f; + Play_SetCameraAtEye(play, this->unk_01AC, &at, &eye); + } else if (this->unk_019C == 50) { + at.x = 825.0f; + at.y = 123.0f; + at.z = -1637.0f; + eye.x = 734.0f; + eye.y = 145.0f; + eye.z = -1762.0f; + Play_SetCameraAtEye(play, this->unk_01AC, &at, &eye); + } else if (this->unk_019C == 25) { + at.x = 711.0f; + at.y = 76.0f; + at.z = -1602.0f; + eye.x = 634.0f; + eye.y = 54.0f; + eye.z = -1735.0f; + Play_SetCameraAtEye(play, this->unk_01AC, &at, &eye); + } + + this->unk_01D4 -= 0.027f; + temp_v1 = (s32)(this->unk_019C * 5.1f) + 50; + this->unk_0193 = CLAMP_MAX(temp_v1, 255); + + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + if (this->unk_019C == 0) { + this->unk_0193 = 0; + func_80B08550(this, play); + } +} + +void func_80B08550(BossHakugin* this, PlayState* play) { + static Vec3f D_80B0EAF4 = { 894.0f, 176.0f, -1600.0f }; + static Vec3f D_80B0EB00 = { 972.0f, 176.0f, -1600.0f }; + Player* player = GET_PLAYER(play); + + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_STEAM_DEMO_UP_OLD); + Play_SetCameraAtEye(play, this->unk_01AC, &D_80B0EAF4, &D_80B0EB00); + this->unk_037A.x = -0x1F00; + this->unk_037A.y = -0x4000; + this->unk_019C = 70; + this->unk_038C.x = 680.0f; + this->unk_038C.y = 370.0f; + this->unk_038C.z = -1600.0f; + player->actor.world.pos.x = 250.0f; + player->actor.world.pos.z = -1560.0f; + player->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000; + player->currentYaw = player->actor.world.rot.y = player->actor.shape.rot.y; + func_800B7298(play, &this->actor, PLAYER_CSACTION_131); + this->actionFunc = func_80B0863C; +} + +void func_80B0863C(BossHakugin* this, PlayState* play) { + static Vec3f D_80B0EB0C = { 377.0f, 140.0f, -1600.0f }; + static Vec3f D_80B0EB18 = { 282.0f, 108.0f, -1600.0f }; + s32 i; + + this->unk_019C--; + if (this->unk_019C > 0) { + func_80B07DA4(this, play, 7.0f, 0xC0); + } else if (this->unk_019C == 0) { + Play_SetCameraAtEye(play, this->unk_01AC, &D_80B0EB0C, &D_80B0EB18); + this->unk_037A.y = 0x4000; + this->unk_037A.x = Math_Atan2S_XY(95.0f, 32.0f); + this->unk_038C.x = 232.0f; + this->unk_038C.y = 43.0f; + this->unk_038C.z = -1600.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_STEAMS_DEMO_OLD); + } else { + func_80B07DA4(this, play, 1.0f, 0xC0); + + if (Animation_OnFrame(&this->skelAnime, 20.0f)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_STEAM_DEMO_UP_OLD); + } + + if (Animation_OnFrame(&this->skelAnime, 45.0f)) { + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_BOSS | SEQ_FLAG_ASYNC); + } + + if (Animation_OnFrame(&this->skelAnime, 65.0f)) { + TitleCard_InitBossName(&play->state, &play->actorCtx.titleCtxt, Lib_SegmentedToVirtual(&gGohtTitleCardTex), + 160, 180, 128, 40); + } + + if (Animation_OnFrame(&this->skelAnime, 86.0f)) { + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_ICEB_CRY_OLD); + } + + if (Animation_OnFrame(&this->skelAnime, 90.0f)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_LAST1_DEMO_BREAK); + for (i = 6; i < ARRAY_COUNT(this->unk_09D0); i++) { + this->unk_09D0[i]->params = 0; + } + } + + if (SkelAnime_Update(&this->skelAnime)) { + func_80B08848(this, play); + return; + } + } + + if (((this->unk_019C + 12) >= 0) && ((this->unk_019C % 4) == 0)) { + func_80B07700(this, play, 0); + } +} + +void func_80B08848(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Vec3f sp30; + + this->unk_038C.x = player->actor.world.pos.x - 150.0f; + this->unk_038C.y = player->actor.world.pos.y + 30.0f; + this->unk_038C.z = player->actor.world.pos.z - 30.0f; + sp30.x = this->actor.world.pos.x - 100.0f; + sp30.y = this->actor.world.pos.y + 100.0f; + sp30.z = this->actor.world.pos.z; + func_800BE33C(&this->unk_038C, &sp30, &this->unk_037A, true); + Animation_Change(&this->skelAnime, &gGohtRunAnim, 1.5f, 0.0f, 0.0f, ANIMMODE_LOOP, -3.0f); + this->unk_019C = 0; + this->actor.speed = 5.0f; + func_800B7298(play, &this->actor, PLAYER_CSACTION_END); + player->stateFlags1 |= PLAYER_STATE1_20; + play->actorCtx.unk268 = true; + this->actionFunc = func_80B08960; +} + +void func_80B08960(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Camera* camera = Play_GetCamera(play, this->unk_01AC); + Vec3f at; + f32 var_fv0; + s32 i; + + Math_ScaledStepToS(&this->unk_01A6, 0x800, 0x80); + Math_StepToF(&this->actor.speed, 25.0f, 0.5f); + this->skelAnime.playSpeed = (this->actor.speed / 32.0f) + 0.5f; + func_80B07450(this, play); + this->unk_018D = 10; + SkelAnime_Update(&this->skelAnime); + this->unk_019C++; + if (this->unk_019C < 8) { + func_80B07DA4(this, play, 25.0f, 0x120); + } else if (this->unk_019C == 22) { + this->unk_038C.x = camera->eye.x; + this->unk_038C.y = camera->eye.y; + this->unk_038C.z = camera->eye.z + 450.0f; + } else if (this->unk_019C == 62) { + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + CutsceneManager_Stop(this->actor.csId); + player->stateFlags1 &= ~PLAYER_STATE1_20; + SET_EVENTINF(EVENTINF_53); + Play_DisableMotionBlur(); + func_80B08C1C(this); + return; + } else if (this->unk_019C > 22) { + at.x = this->actor.world.pos.x; + at.y = this->actor.world.pos.y + 150.0f; + at.z = this->actor.world.pos.z; + Math_Vec3f_StepTo(&camera->eye, &this->unk_038C, 35.0f); + Play_SetCameraAtEye(play, this->unk_01AC, &at, &camera->eye); + + if (this->unk_019C == 42) { + Actor_PlaySfx(&this->actor, NA_SE_EN_LAST1_DEMO_WALL); + for (i = 0; i < 6; i++) { + this->unk_09D0[i]->params = 0; + } + } + } + + if (this->unk_0484.base.atFlags & AT_HIT) { + func_800B8D50(play, &this->actor, 10.0f, 0, 6.0f, 0); + } else { + play->actorCtx.unk268 = true; + } + + if (this->unk_019C > 4) { + var_fv0 = (this->unk_019C - 4) * 5.0f; + var_fv0 = CLAMP_MAX(var_fv0, 60.0f); + func_800B6F20(play, &play->actorCtx.unk_26C, var_fv0, -0x4000); + } +} + +void func_80B08C1C(BossHakugin* this) { + Animation_Change(&this->skelAnime, &gGohtRunAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -5.0f); + this->unk_01A2 = 0; + this->unk_01C8 = 0.0f; + this->unk_019E = Rand_CenteredFloat(3072.0f); + this->unk_019C = 40; + this->unk_01C4 = 16.0f; + this->actionFunc = func_80B08CB8; +} + +void func_80B08CB8(BossHakugin* this, PlayState* play) { + s16 temp_a0; + + if (this->unk_01A4 == 0) { + this->unk_0484.base.atFlags |= AT_ON; + } + if (this->unk_0192 == 1) { + if (func_80B0728C(this)) { + Math_Vec3f_Copy(&this->unk_3734[0], &this->unk_0380); + this->unk_01B8 = this->actor.speed + 100.0f; + this->unk_37AC.x = Math_CosS(0xA00) * Math_SinS(this->actor.shape.rot.y); + this->unk_37AC.y = Math_SinS(0xA00); + this->unk_37AC.z = Math_CosS(0xA00) * Math_CosS(this->actor.shape.rot.y); + this->unk_0192 = 2; + this->unk_01C8 = 0.0f; + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_COMMON_E_BALL_THR); + this->unk_37B8.base.atFlags |= AT_ON; + } + } else { + Math_ScaledStepToS(&this->unk_01A6, 0, 0x100); + } + if (func_80B0791C(this, play)) { + func_80B09A94(this, play); + } else { + if (this->unk_019A > 55) { + this->unk_019A = 0; + this->unk_019C = 40; + this->unk_01C4 = 27.0f; + } + if ((this->unk_019C == 40) && + (Math_SmoothStepToF(&this->actor.speed, this->unk_01C4, 0.15f, 1.0f, 0.1f) < 0.05f)) { + this->unk_019C -= 1; + } else { + if (this->unk_019C != 40) { + this->unk_019C--; + if (this->unk_019C == 0) { + if (this->actor.xzDistToPlayer > 1500.0f) { + this->unk_01C4 = 12.5f; + } else if (this->unk_044C.z > 0.0f) { + this->unk_01C4 = 21.0f; + } else { + this->unk_01C4 = 14.5f; + } + this->unk_01C4 += (30 - this->actor.colChkInfo.health) * (1.0f / 30.0f); + this->unk_019C = 40; + } + } + } + this->skelAnime.playSpeed = (this->actor.speed / 32.0f) + 0.5f; + SkelAnime_Update(&this->skelAnime); + func_80B07450(this, play); + if ((this->unk_01BC < (this->unk_01C0 * 0.5f)) || (this->unk_01BC < 89.100006f)) { + this->unk_019E = (Rand_ZeroFloat(0.4f) + 0.6f) * 1536.0f; + } else if ((this->unk_01C0 < (this->unk_01BC * 0.5f)) || (this->unk_01C0 < 89.100006f)) { + this->unk_019E = -((Rand_ZeroFloat(0.4f) + 0.6f) * 1536.0f); + } else if ((this->unk_01A2 == this->unk_019E) && (Rand_ZeroOne() < 0.005f)) { + if (this->unk_019E > 0) { + this->unk_019E = -((Rand_ZeroFloat(0.4f) + 0.6f) * 1536.0f); + } else { + this->unk_019E = ((Rand_ZeroFloat(0.4f) + 0.6f) * 1536.0f); + } + } + Math_SmoothStepToS(&this->unk_01A2, this->unk_019E, 5, 0x800, 0x10); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_01A0 + this->unk_01A2, 5, 0x800, 0x10); + + temp_a0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->unk_018C != 1) && (this->actor.xzDistToPlayer > 750.0f) && (this->actor.xzDistToPlayer < 1650.0f) && + (ABS_ALT(temp_a0) < 0x3000)) { + func_80B09178(this); + } + } +} + +void func_80B09178(BossHakugin* this) { + Animation_Change(&this->skelAnime, &gGohtRunAnim, 1.5f, 0.0f, 0.0f, 0, -3.0f); + this->actionFunc = func_80B091D8; +} + +void func_80B091D8(BossHakugin* this, PlayState* play) { + s16 var_v0; + + Math_ScaledStepToS(&this->unk_01A6, 0x800, 0x100); + Math_StepToF(&this->actor.speed, 25.0f, 2.0f); + SkelAnime_Update(&this->skelAnime); + func_80B07450(this, play); + if ((this->unk_044C.z < 0.0f) || (this->unk_0484.base.atFlags & AT_HIT)) { + func_80B08C1C(this); + } else { + if ((this->unk_01C0 < 89.100006f) || (this->unk_01BC < 89.100006f)) { + this->unk_019E = this->unk_01A0; + } else { + if (((this->unk_044C.x > 0.0f) && (this->unk_044C.x < this->unk_01C0)) || + ((this->unk_044C.x <= 0.0f) && (-this->unk_044C.x < this->unk_01BC))) { + var_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + var_v0 = CLAMP(var_v0, -0x3000, 0x3000); + this->unk_019E = this->actor.shape.rot.y + var_v0; + } else { + this->unk_019E = + ((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y) >> 1) + this->actor.shape.rot.y; + } + } + + var_v0 = (this->unk_019E - this->unk_01A0); + if (var_v0 > 0x1800) { + this->unk_019E = this->unk_01A0 + 0x1800; + } else if (var_v0 < -0x1800) { + this->unk_019E = this->unk_01A0 - 0x1800; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_019E, 5, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } +} + +void func_80B093C0(BossHakugin* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGohtFallDownAnim, -3.0f); + this->unk_0484.base.atFlags &= ~AT_ON; + this->unk_0484.base.acFlags &= ~AC_HARD; + this->unk_01A6 = 0; + this->unk_0195 = false; + this->unk_01C8 = 0.0f; + if (this->unk_0192 == 1) { + Math_Vec3f_Copy(&this->unk_3734[0], &this->unk_0380); + this->unk_01B8 = this->actor.speed + 100.0f; + this->unk_37AC.x = Math_CosS(0xA00) * Math_SinS(this->actor.shape.rot.y); + this->unk_37AC.y = Math_SinS(0xA00); + this->unk_37AC.z = Math_CosS(0xA00) * Math_CosS(this->actor.shape.rot.y); + this->unk_0192 = 2; + this->unk_01C8 = 0.0f; + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_COMMON_E_BALL_THR); + this->unk_37B8.base.atFlags |= AT_ON; + } + this->unk_019C = 60; + this->actor.speed = 20.0f; + this->actionFunc = func_80B094E0; +} + +void func_80B094E0(BossHakugin* this, PlayState* play) { + CollisionPoly* spBC; + Vec3f spB0; + Vec3f spA4; + s32 i; + s32 sp9C; + + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); + if (SkelAnime_Update(&this->skelAnime)) { + if (!this->unk_0195) { + this->unk_0195 = true; + func_80B05A64(this, play, 17000, 7, 10); + } + + if (this->actor.speed > 5.0f) { + + for (i = 0; i < 2; i++) { + s16 temp1 = this->actor.shape.rot.y + (u32)(0xF000 * i - 0x7800); // TODO: seems fake + s16 temp2; + f32 temp_fs1; + + spB0.x = 2.0f * Math_SinS(temp1); + spB0.y = 1.0f; + spB0.z = 2.0f * Math_CosS(temp1); + + temp2 = this->actor.shape.rot.y + (u32)(0x8000 * i - 0x4000); + temp_fs1 = Rand_ZeroFloat(190.0f); + spA4.x = this->actor.world.pos.x + (80.0f * Math_SinS(temp2)) + + (Math_SinS(this->actor.shape.rot.y) * temp_fs1); + spA4.z = this->actor.world.pos.z + (80.0f * Math_CosS(temp2)) + + (Math_CosS(this->actor.shape.rot.y) * temp_fs1); + spA4.y = this->actor.world.pos.y + 300.0f; + spA4.y = BgCheck_EntityRaycastFloor5_2(play, &play->colCtx, &spBC, &sp9C, &this->actor, &spA4) + 10.0f; + func_800B12F0(play, &spA4, &spB0, &gZeroVec3f, Rand_S16Offset(750, 100), 10, 30); + } + } + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_01A0, 5, 0x800, 0x10); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->actor.speed < 0.1f) { + this->unk_019C--; + this->actor.world.pos.x = this->actor.home.pos.x + Rand_CenteredFloat(5.0f); + this->actor.world.pos.y = this->actor.home.pos.y + Rand_CenteredFloat(5.0f); + this->actor.world.pos.z = this->actor.home.pos.z + Rand_CenteredFloat(5.0f); + if (this->unk_019C == 0) { + this->unk_0484.base.acFlags |= AC_HARD; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + func_80B08C1C(this); + this->unk_01A4 = 20; + } + } else if (Math_StepToF(&this->actor.speed, 5.0f, 0.3f)) { + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); + this->actor.speed = 0.0f; + } +} + +void func_80B09840(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + Animation_MorphToPlayOnce(&this->skelAnime, &gGohtStationaryAnim, -10.0f); + player->actor.parent = &this->actor; + this->unk_0484.base.atFlags &= ~AT_ON; + this->unk_0484.base.ocFlags1 &= ~OC1_ON; + this->unk_019C = 10; + this->actionFunc = func_80B098BC; +} + +void func_80B098BC(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s16 sp32; + f32 sp2C; + + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->actor.speed, 0.0f, 2.0f); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_01A0, 5, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->unk_019C < 10) { + this->unk_019C--; + if (this->unk_019C == 0) { + this->unk_0484.base.atFlags |= AT_ON; + this->unk_0484.base.ocFlags1 |= OC1_ON; + func_80B08C1C(this); + } + } else { + if (Math_ScaledStepToS(&this->unk_01A6, -0x800, 0x1C0)) { + player->av2.actionVar2 = 100; + player->actor.parent = NULL; + player->invincibilityTimer = 0; + player->actor.shape.rot.x = 0; + func_800B8D50(play, &this->actor, 10.0f, (this->actor.shape.rot.y + 0x8000), 15.0f, 0x10); + player->actor.world.pos.y += 30.0f; + this->unk_019C--; + } else { + player->av2.actionVar2 = 0; + sp32 = -this->unk_0374.z + 0x1F40; + player->actor.shape.rot.x = -this->unk_0374.z + 0x8FC0; + + sp2C = Math_CosS(sp32); + player->actor.world.pos.x = this->actor.focus.pos.x - (Math_SinS(this->unk_01A0) * (20.0f * sp2C)); + player->actor.world.pos.y = this->actor.focus.pos.y - (Math_SinS(sp32) * 20.0f); + player->actor.world.pos.z = this->actor.focus.pos.z - (Math_CosS(this->unk_01A0) * (20.0f * sp2C)); + } + } +} + +void func_80B09A94(BossHakugin* this, PlayState* play) { + f32 var_fv1; + s16 atan; + + if (this->actionFunc != func_80B09E20) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGohtStationaryAnim, -5.0f); + this->actor.speed = 0.0f; + atan = Math_Atan2S_XY(this->actor.world.pos.z, this->actor.world.pos.x); + if (atan < -0x4000) { + this->actor.world.pos.x = -1200.0f; + this->actor.shape.rot.y = 0x4000; + this->actor.world.pos.z = -1200.0f; + } else if (atan < 0) { + this->actor.world.pos.x = -1200.0f; + this->actor.shape.rot.y = -0x8000; + this->actor.world.pos.z = 1200.0f; + } else if (atan < 0x4000) { + this->actor.world.pos.x = 1200.0f; + this->actor.shape.rot.y = -0x4000; + this->actor.world.pos.z = 1200.0f; + } else { + this->actor.world.pos.x = 1200.0f; + this->actor.shape.rot.y = 0; + this->actor.world.pos.z = -1200.0f; + } + if (this->unk_01B4 == 1) { + var_fv1 = -1.0f; + this->actor.shape.rot.y -= 0x4000; + } else { + var_fv1 = 1.0f; + } + this->unk_01A0 = this->actor.shape.rot.y + (this->unk_01B4 * 0x6000); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.pos.x += var_fv1 * 300.0f * Math_CosS(this->actor.shape.rot.y); + this->actor.world.pos.z -= var_fv1 * 300.0f * Math_SinS(this->actor.shape.rot.y); + this->actor.world.pos.y += 500.0f; + this->actor.world.pos.y = + BgCheck_EntityRaycastFloor1(&play->colCtx, &this->actor.floorPoly, &this->actor.world.pos); + this->unk_018C = 0; + } + this->unk_01A6 = 0x700; + this->unk_019C = 150; + this->unk_01CC = -100.0f; + this->actionFunc = func_80B09C78; +} + +void func_80B09C78(BossHakugin* this, PlayState* play) { + f32 temp_fv1; + f32 sp1C; + + SkelAnime_Update(&this->skelAnime); + temp_fv1 = fabsf(this->unk_044C.x); + sp1C = temp_fv1; + Math_StepToF(&this->unk_01C8, 0.0f, 6.0f); + if ((this->unk_044C.z < 0.0f) || (this->actor.xzDistToPlayer < 750.0f) || (this->unk_018C == 1)) { + func_80B08C1C(this); + return; + } + + if ((this->unk_2618[0].unk_0C == 0) && (this->unk_01C8 < 0.1f) && (temp_fv1 < 400.0f) && + (this->unk_044C.z > 0.0f)) { + func_80B09DFC(this); + return; + } + + if ((temp_fv1 > 400.0f) && ((play->gameplayFrames & 0xF) == 0xF)) { + func_80B06C08(this); + return; + } + + if (this->unk_019C > 0) { + this->unk_019C--; + } else { + this->unk_01B4 = -this->unk_01B4; + this->unk_01A0 = this->actor.shape.rot.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80B08C1C(this); + } +} + +void func_80B09DFC(BossHakugin* this) { + this->unk_01A8 = 5; + this->unk_01C8 = 0.0f; + this->actionFunc = func_80B09E20; +} + +void func_80B09E20(BossHakugin* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_COMMON_THUNDER - SFX_FLAG); + if (func_80B0728C(this)) { + func_80B06600(this, &this->unk_0380, play); + func_80B09A94(this, play); + } +} + +void func_80B09E84(BossHakugin* this) { + CutsceneManager_Queue(this->actor.csId); + if (this->actionFunc == func_80B0813C) { + this->unk_019C = 1; + } else { + this->unk_019C = 0; + } + + this->actionFunc = func_80B09EDC; +} + +void func_80B09EDC(BossHakugin* this, PlayState* play) { + if (CutsceneManager_IsNext(this->actor.csId)) { + CutsceneManager_StartWithPlayerCs(this->actor.csId, &this->actor); + if (this->actor.colChkInfo.health == 0) { + func_80B09F7C(this); + } else if (this->unk_019C == 1) { + func_80B0825C(this); + } else { + func_80B07EEC(this, play); + } + } else { + CutsceneManager_Queue(this->actor.csId); + } +} + +void func_80B09F7C(BossHakugin* this) { + f32 temp_fv0_2; + + Animation_Change(&this->skelAnime, &gGohtRunAnim, 1.3f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -3.0f); + this->unk_01AC = CutsceneManager_GetCurrentSubCamId(this->actor.csId); + + if ((this->actor.world.pos.z >= 0.0f) && (this->actor.world.pos.x >= 0.0f)) { + this->unk_019E = -0x4000; + } else { + if ((this->actor.world.pos.z >= 0.0f) && (this->actor.world.pos.x < 0.0f)) { + this->unk_019E = -0x8000; + } else if ((this->actor.world.pos.x >= 0.0f) && (this->actor.world.pos.z < 0.0f)) { + this->unk_019E = 0; + } else { + this->unk_019E = 0x4000; + } + } + + if (this->unk_01B4 == 1) { + this->unk_019E -= 0x4000; + } + + temp_fv0_2 = this->unk_01B4; + if ((this->unk_019E > 0x6000) || (this->unk_019E < -0x6000)) { + this->unk_038C.x = temp_fv0_2 * -1200.0f; + this->unk_038C.y = (temp_fv0_2 * 80.0f) + -240.0f + 60.0f; + this->unk_038C.z = 1200.0f; + } else if ((this->unk_019E < 0x2000) && (this->unk_019E > -0x2000)) { + this->unk_038C.x = temp_fv0_2 * 1200.0f; + this->unk_038C.y = 60.0f; + this->unk_038C.z = -1200.0f; + } else if (this->unk_019E >= 0x2000) { + this->unk_038C.x = -1200.0f; + this->unk_038C.y = (80.0f * temp_fv0_2) + -80.0f + 60.0f; + this->unk_038C.z = temp_fv0_2 * -1200.0f; + } else { + this->unk_038C.x = 1200.0f; + this->unk_038C.y = (-160.0f * temp_fv0_2) + -160.0f + 60.0f; + this->unk_038C.z = temp_fv0_2 * 1200.0f; + } + + this->unk_01C8 = 0.0f; + this->unk_01A6 = 0; + Play_EnableMotionBlur(140); + this->unk_01A2 = Rand_S16Offset(0x800, 0x800) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1); + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 1); + this->actor.home.rot.y = this->actor.shape.rot.y; + this->unk_019C = 18; + if ((this->unk_0192 == 2) || (this->unk_0192 == 3)) { + this->unk_0192 = 4; + this->unk_01AA = 0; + } + + this->unk_01AE = Rand_ZeroFloat(6144.0f); + this->unk_0374.y = 0; + this->unk_0374.z = 0; + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + this->actor.speed = CLAMP_MIN(this->actor.speed, 16.0f); + this->actionFunc = func_80B0A2A4; +} + +void func_80B0A2A4(BossHakugin* this, PlayState* play) { + Vec3f at; + f32 absPosX; + f32 absPosZ; + s32 absRotY; + + Math_StepToF(&this->actor.speed, 15.0f, 2.0f); + SkelAnime_Update(&this->skelAnime); + this->unk_018D = 10; + this->unk_018E = 10; + this->unk_018F = 10; + func_80B07450(this, play); + Math_SmoothStepToS(&this->actor.home.rot.y, this->unk_01A0, 5, 0x800, 0x100); + this->unk_019C--; + this->actor.shape.rot.y = + (s32)(Math_SinF(this->unk_019C * (M_PI / 18.0f)) * this->unk_01A2) + this->actor.home.rot.y; + + if (this->unk_019C == 0) { + if (this->unk_01A2 > 0) { + this->unk_01A2 = -Rand_S16Offset(0x800, 0x800); + } else { + this->unk_01A2 = Rand_S16Offset(0x800, 0x800); + } + this->unk_019C = 18; + this->unk_01AE = Rand_ZeroFloat(6144.0f); + } + + this->unk_0374.z = (8192.0f * Math_SinS(this->unk_01AE)) * Math_SinF(this->unk_019C * (M_PI / 9)); + this->unk_0374.y = (8192.0f * Math_CosS(this->unk_01AE)) * Math_SinF(this->unk_019C * (M_PI / 9)); + this->actor.shape.rot.z = Math_SinF(this->unk_019C * (M_PI / 18)) * -(this->unk_01A2 * 0.3f); + this->actor.world.rot.y = this->actor.shape.rot.y; + at.x = (Math_SinS(this->actor.shape.rot.y) * 100.0f) + this->actor.world.pos.x; + at.y = this->actor.world.pos.y + 200.0f; + at.z = (Math_CosS(this->actor.shape.rot.y) * 100.0f) + this->actor.world.pos.z; + Play_SetCameraAtEye(play, this->unk_01AC, &at, &this->unk_038C); + + if (this->unk_019E == this->unk_01A0) { + absPosX = fabsf(this->actor.world.pos.x); + absPosZ = fabsf(this->actor.world.pos.z); + absRotY = ABS_ALT(this->actor.shape.rot.y); + + if (((absPosX > 1289.1f) && (absPosZ < 1110.9f) && ((absRotY < 0x2000) || (absRotY > 0x6000))) || + ((absPosZ > 1289.1f) && (absPosX < 1110.9f) && (absRotY > 0x2000) && (absRotY < 0x6000))) { + func_80B0A5EC(this); + } + } +} + +void func_80B0A5EC(BossHakugin* this) { + if (this->unk_01B4 == 1) { + this->unk_019E -= 0x4000; + } else { + this->unk_019E += 0x4000; + } + + this->actor.speed = 15.0f; + this->actionFunc = func_80B0A638; +} + +void func_80B0A638(BossHakugin* this, PlayState* play) { + Vec3f at; + Vec3f eyeTarget; + s32 var_v0; + s16 temp_a0; + + SkelAnime_Update(&this->skelAnime); + at.x = (Math_SinS(this->actor.shape.rot.y) * 100.0f) + this->actor.world.pos.x; + at.y = this->actor.world.pos.y + 200.0f; + at.z = (Math_CosS(this->actor.shape.rot.y) * 100.0f) + this->actor.world.pos.z; + temp_a0 = this->actor.shape.rot.y - (this->unk_01B4 * 0x6000); + eyeTarget.x = (Math_SinS(temp_a0) * 400.0f) + this->actor.world.pos.x; + eyeTarget.y = this->actor.world.pos.y + 100.0f; + eyeTarget.z = Math_CosS(temp_a0) * 400.0f + this->actor.world.pos.z; + Math_Vec3f_StepTo(&this->unk_038C, &eyeTarget, 25.0f); + Play_SetCameraAtEye(play, this->unk_01AC, &at, &this->unk_038C); + this->unk_018D = 10; + this->unk_018E = 10; + this->unk_018F = 10; + func_80B07450(this, play); + + if ((Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_019E, 0x300)) && + ((this->unk_01BC <= 189.00002f) || (this->unk_01C0 <= 189.00002f))) { + func_80B0A87C(this); + } else { + if (((this->unk_01B4 == 1) && (this->unk_01BC <= 189.00002f)) || + ((this->unk_01B4 == -1) && (this->unk_01C0 <= 189.00002f))) { + var_v0 = ABS_ALT(this->unk_019E); + if (var_v0 < 0x2000) { + this->actor.world.pos.z = -1389.0f; + } else if (var_v0 > 0x6000) { + this->actor.world.pos.z = 1389.0f; + } else if (this->unk_019E > 0) { + this->actor.world.pos.x = -1389.0f; + } else { + this->actor.world.pos.x = 1389.0f; + } + } + } + + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80B0A87C(BossHakugin* this) { + this->unk_019C = 0; + this->actor.speed = 0.0f; + this->skelAnime.playSpeed = 0.5f; + func_80B0D9CC(this); + this->actionFunc = func_80B0A8C4; +} + +typedef struct { + s32 unk_00; + u32 unk_04; +} BossHakuginStruct_B0A8C4; + +static s32 D_80B0EB24[5] = { 0, 15, 26, 33, 36 }; + +static BossHakuginStruct_B0A8C4 D_80B0EB38[] = { + { 0, GOHT_LIMB_FLAG(GOHT_LIMB_HEAD) | GOHT_LIMB_FLAG(GOHT_LIMB_JAW) }, + { 4, GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_RIGHT_UPPER_LEG) | GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_RIGHT_LOWER_LEG) | + GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_RIGHT_HOOF) }, + { 7, GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_LEFT_UPPER_LEG) | GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_LEFT_LOWER_LEG) | + GOHT_LIMB_FLAG(GOHT_LIMB_FRONT_LEFT_HOOF) }, + { 14, GOHT_LIMB_FLAG(GOHT_LIMB_BACK_LEFT_SHIN) | GOHT_LIMB_FLAG(GOHT_LIMB_BACK_LEFT_PASTERN) | + GOHT_LIMB_FLAG(GOHT_LIMB_BACK_LEFT_HOOF) }, + { 10, GOHT_LIMB_FLAG(GOHT_LIMB_BACK_RIGHT_SHIN) | GOHT_LIMB_FLAG(GOHT_LIMB_BACK_RIGHT_PASTERN) | + GOHT_LIMB_FLAG(GOHT_LIMB_BACK_RIGHT_HOOF) }, + { 1, GOHT_LIMB_FLAG(GOHT_LIMB_PELVIS) | GOHT_LIMB_FLAG(GOHT_LIMB_THORAX) | + GOHT_LIMB_FLAG(GOHT_LIMB_BACK_RIGHT_THIGH) | GOHT_LIMB_FLAG(GOHT_LIMB_BACK_LEFT_THIGH) }, +}; + +void func_80B0A8C4(BossHakugin* this, PlayState* play) { + EnBom* bomb; + Vec3s* test; + Camera* camera; + Vec3f eyeTarget; + s16 temp_s0; + s32 sp60; + s32 i; + BossHakuginStruct_B0A8C4* unkStruct; + + camera = Play_GetCamera(play, this->unk_01AC); + SkelAnime_Update(&this->skelAnime); + sp60 = this->unk_019C / 6; + temp_s0 = this->actor.shape.rot.y + (0x6000 * this->unk_01B4); + eyeTarget.x = (Math_SinS(temp_s0) * 500.0f) + this->actor.world.pos.x; + eyeTarget.y = this->actor.world.pos.y + 250.0f; + eyeTarget.z = (Math_CosS(temp_s0) * 500.0f) + this->actor.world.pos.z; + Math_Vec3f_StepTo(&this->unk_038C, &eyeTarget, 25.0f); + Play_SetCameraAtEye(play, this->unk_01AC, &camera->at, &this->unk_038C); + if (sp60 == 30) { + Camera* camera2 = Play_GetCamera(play, 0); + + Play_DisableMotionBlur(); + CutsceneManager_Stop(this->actor.csId); + Play_SetCameraAtEye(play, this->unk_01AC, &camera2->at, &camera2->eye); + func_80B05EE0(this, play); + func_80B0DFA8(this); + this->actor.draw = func_80B0E5A4; + this->actor.update = func_80B0E548; + } else if (((this->unk_019C % 6) == 0) && (sp60 < 6)) { + unkStruct = &D_80B0EB38[sp60]; + test = &this->unk_0484.elements[unkStruct->unk_00].dim.worldSphere.center; + bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, test->x, test->y, test->z, 1, 0, 0, 0); + if (bomb != NULL) { + bomb->timer = 0; + } + this->unk_01B0 &= ~unkStruct->unk_04; + if (sp60 == 5) { + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_CLEAR_BOSS | SEQ_FLAG_ASYNC); + } + } + + if (((this->unk_019C + 3) % 6) == 0) { + sp60 = (this->unk_019C + 3) / 6 - 1; + if (sp60 < 4) { + for (i = D_80B0EB24[sp60]; i < D_80B0EB24[sp60 + 1]; i++) { + this->unk_09F8[i].unk_C.y = Rand_ZeroFloat(5.0f) + 5.0f; + } + } + if (sp60 < 6) { + if (sp60 & 1) { + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_LAST1_DEMO_WALL); + } else { + Audio_PlaySfx_AtPos(&this->unk_0458, NA_SE_EN_LAST1_DEMO_BREAK); + } + } + //! FAKE: + if (1) {} + } + + this->unk_019C++; +} + +void func_80B0AC30(BossHakugin* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if ((this->unk_0484.base.atFlags & AT_HIT) && + ((this->actionFunc == func_80B091D8) || !(player->stateFlags3 & PLAYER_STATE3_80000))) { + if ((this->actionFunc == func_80B091D8) && (this->unk_0484.elements->info.toucherFlags & TOUCH_HIT) && + !(this->unk_0484.base.atFlags & AT_BOUNCED) && (play->grabPlayer(play, player))) { + func_80B09840(this, play); + } else if (player->stateFlags3 & PLAYER_STATE3_1000) { + player->unk_B08 = player->linearVelocity = -5.0f; + player->unk_B0C += player->unk_B08 * 0.05f; + player->actor.velocity.y = 10.0f; + player->unk_B8C = 4; + player->actor.shape.rot.y = player->actor.home.rot.y = player->currentYaw = player->actor.world.rot.y; + + } else if (!(this->unk_0484.base.atFlags & AT_BOUNCED)) { + s16 var_a3 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + if (var_a3 > 0) { + var_a3 = this->actor.shape.rot.y + (s32)(var_a3 / 2.0f) + 0x4000; + } else { + var_a3 = this->actor.shape.rot.y + (s32)(var_a3 / 2.0f) - 0x4000; + } + func_800B8D50(play, &this->actor, 5.0f, var_a3, 6.0f, 0); + } + } +} + +s32 func_80B0ADFC(BossHakugin* this, PlayState* play) { + if (this->unk_0484.base.acFlags & AC_HIT) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_04A4); i++) { + if (this->unk_0484.elements[i].info.bumperFlags & BUMP_HIT) { + break; + } + } + if (i == ARRAY_COUNT(this->unk_04A4)) { + return false; + } + // DMG_DEKU_NUT | DMG_DEKU_STICK | DMG_ZORA_BOOMERANG | DMG_NORMAL_ARROW | DMG_HOOKSHOT | DMG_ICE_ARROW + // | DMG_LIGHT_ARROW | DMG_DEKU_SPIN | DMG_DEKU_BUBBLE | DMG_DEKU_LAUNCH | DMG_ZORA_BARRIER + if ((this->unk_0196 == 10) && (this->unk_0484.elements[i].info.acHitInfo->toucher.dmgFlags & 0x000DB0B3)) { + return false; + } + func_80B07B88(this, play); + if (this->actionFunc == func_80B094E0) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 15); + func_80B07BFC(this, play, i); + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(play, &this->actor); + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_DEAD_OLD); + func_80B09E84(this); + } else { + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_DAMAGE_OLD); + } + this->unk_01A4 = 15; + return true; + } + if (((this->actor.colChkInfo.damageEffect == 0xF) || (this->actor.colChkInfo.damageEffect == 0xE) || + (this->actor.colChkInfo.damageEffect == 2) || (this->actor.colChkInfo.damageEffect == 3) || + (this->actor.colChkInfo.damageEffect == 4) || (this->actor.colChkInfo.damageEffect == 0xD) || + (this->actor.colChkInfo.damageEffect == 0xC)) && + ((this->actionFunc == func_80B08CB8) || (this->actionFunc == func_80B09E20) || + (this->actionFunc == func_80B09C78) || (this->actionFunc == func_80B091D8))) { + Player* player = GET_PLAYER(play); + + if (this->actor.colChkInfo.damageEffect == 0xF) { + player->pushedSpeed = 15.0f; + if ((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y) > 0) { + player->pushedYaw = this->actor.shape.rot.y + 0x4000; + } else { + player->pushedYaw = this->actor.shape.rot.y - 0x4000; + } + } + this->unk_01A4 = 15; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 15); + this->unk_019A += 35; + func_80B07BFC(this, play, i); + this->actor.colChkInfo.damage = this->unk_0484.elements[i].info.acHitInfo->toucher.damage; + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(play, &this->actor); + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_DEAD_OLD); + func_80B09E84(this); + } else { + if ((this->actor.colChkInfo.damageEffect == 0xC) || + ((this->actor.colChkInfo.damageEffect == 0xF) && (this->actionFunc != func_80B091D8) && + ((this->unk_0484.elements[0].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[1].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[2].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[3].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[6].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[9].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[13].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[17].info.bumperFlags & BUMP_HIT) || + (this->unk_0484.elements[18].info.bumperFlags & BUMP_HIT)))) { + func_80B093C0(this); + } else if ((this->unk_0192 == 0) && (this->unk_01AA == 0) && (this->actionFunc == func_80B08CB8) && + (this->actor.colChkInfo.damageEffect == 0xF)) { + this->unk_01A8 = 5; + this->unk_0192 = 1; + } + Actor_PlaySfx(&this->actor, NA_SE_EN_ICEB_DAMAGE_OLD); + } + return true; + } else { + s32 j; + + this->unk_01A4 = 20; + for (j = 0; j < ARRAY_COUNT(this->unk_04A4); j++) { + Vec3f sp40; + ColliderInfo* hurtbox = &this->unk_0484.elements[j].info; + + if ((hurtbox->bumperFlags & BUMP_HIT) && (hurtbox->acHitInfo != NULL) && + !(hurtbox->acHitInfo->toucherFlags & TOUCH_SFX_NONE)) { + Math_Vec3s_ToVec3f(&sp40, &hurtbox->bumper.hitPos); + EffectSsHitmark_SpawnFixedScale(play, 3, &sp40); + CollisionCheck_SpawnShieldParticlesMetalSound(play, &sp40, &this->actor.projectedPos); + break; + } + } + } + } + + return false; +} + +void func_80B0B238(BossHakugin* this) { + BossHakuginEffect* temp_s0; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { + temp_s0 = &this->unk_09F8[i]; + + if (temp_s0->unk_18 >= 0) { + temp_s0->unk_18--; + temp_s0->unk_C.y += -1.0f; + Math_Vec3f_Sum(&temp_s0->unk_0, &temp_s0->unk_C, &temp_s0->unk_0); + if (temp_s0->unk_0.y < -500.0f) { + temp_s0->unk_18 = -1; + } else { + temp_s0->unk_1C.x += (s16)(0x700 + (Rand_Next() >> 0x17)); + temp_s0->unk_1C.y += (s16)(0x900 + (Rand_Next() >> 0x17)); + temp_s0->unk_1C.z += (s16)(0xB00 + (Rand_Next() >> 0x17)); + } + } + } +} + +void func_80B0B34C(BossHakugin* this) { + BossHakuginEffect* effect; + s32 i; + + for (i = 0; i < 36; i++) { + effect = &this->unk_09F8[i]; + Math_StepToF(&effect->unk_0.y, effect->unk_C.x, effect->unk_C.y); + if (effect->unk_C.y > 0.0f) { + effect->unk_C.y = effect->unk_C.y + 6.0f; + } + } +} + +void func_80B0B3F4(BossHakugin* this) { + s32 i; + s32 j; + + for (i = 0; i < ARRAY_COUNT(this->unk_3158); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_3158[0]); j++) { + BossHakuginFhgFlashUnkStruct* effect = &this->unk_3158[i][j]; + + if (effect->unk_10 > 0) { + effect->unk_12--; + effect->unk_00.y += 3.5f; + effect->unk_0C += 0.003f; + if (effect->unk_12 < 0) { + effect->unk_10 -= 15; + if (effect->unk_10 < 0) { + effect->unk_10 = 0; + } + } + } + } + } +} + +void func_80B0B548(BossHakugin* this, PlayState* play) { + BossHakuginUnkStruct_2618* unk_str; + s16 rand; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + unk_str = &this->unk_2618[i]; + + if (unk_str->unk_14.base.atFlags & AT_HIT) { + Player* player = GET_PLAYER(play); + + this->unk_018C = 1; + Player_PlaySfx(player, NA_SE_EN_COMMON_E_BALL_HIT); + unk_str->unk_14.base.atFlags &= ~AT_HIT; + } + if (unk_str->unk_0C > 0) { + unk_str->unk_0C -= 20; + if (unk_str->unk_0C <= 0) { + unk_str->unk_0C = 0; + } else if (unk_str->unk_0C <= 255) { + rand = (s32)Rand_Next() >> 0x10; + unk_str->unk_0E.z = rand; + if (unk_str->unk_0C > 60) { + CollisionCheck_SetAT(play, &play->colChkCtx, &unk_str->unk_14.base); + } + } + } + } +} + +void func_80B0B660(BossHakugin* this, PlayState* play) { + Player* spA4 = GET_PLAYER(play); + CollisionPoly* spA0 = NULL; + Vec3f sp94; + Vec3f sp88; + Vec3f sp7C; + Vec3f sp70; + Vec3f* sp6C; + Vec3f* var_s0; + s32 var_s0_2; + f32 sp60; + s32 sp5C; + s32 sp58 = false; + s16 temp_v1; + + sp6C = &this->unk_3734[0]; + + if (this->unk_0192 == 2) { + if (Math_StepToF(&this->unk_01B8, 50.0f, 3.5f)) { + this->unk_0192 = 3; + } + } else if (this->unk_0192 == 3) { + sp60 = BINANG_TO_RAD(Math3D_Vec3fDistSq(sp6C, &spA4->actor.world.pos) * (1.0f / SQ(120.0f)) * 32.0f); + if (sp60 > M_PI / 4.0f) { + sp60 = M_PI / 4.0f; + } + Math_Vec3f_Diff(&spA4->actor.world.pos, sp6C, &sp70); + if (func_80B0573C(&sp70)) { + func_80B057A4(&this->unk_37AC, &sp70, sp60); + } + } else if (this->unk_0192 != 4) { + return; + } + Audio_PlaySfx_AtPos(&this->unk_0464, NA_SE_EN_COMMON_E_BALL - SFX_FLAG); + if (this->unk_01AA < 10) { + this->unk_01AA++; + } + if ((this->unk_0192 == 4) && (this->unk_01AA == 9)) { + this->unk_0192 = 0; + this->unk_01AA = 0; + } else { + var_s0 = &this->unk_3734[9]; + while (var_s0 != sp6C) { + Math_Vec3f_Copy(var_s0, var_s0 - 1); + var_s0--; + } + this->unk_0198 += (s16)(0x4000 + (Rand_Next() >> 0x12)); + if (this->unk_0192 != 4) { + if (this->unk_37B8.base.atFlags & AT_HIT) { + this->unk_0192 = 4; + this->unk_01AA = 0; + this->unk_37B8.base.atFlags &= ~AT_HIT; + this->unk_37B8.base.atFlags &= ~AT_ON; + sp58 = true; + Audio_PlaySfx_AtPos(&this->unk_0464, NA_SE_EN_COMMON_E_BALL_HIT); + } + sp88.x = sp6C->x + (this->unk_01B8 * this->unk_37AC.x); + sp88.y = sp6C->y + (this->unk_01B8 * this->unk_37AC.y); + sp88.z = sp6C->z + (this->unk_01B8 * this->unk_37AC.z); + if (BgCheck_EntityLineTest1(&play->colCtx, sp6C, &sp88, &sp94, &spA0, 1, 1, 1, 1, &sp5C)) { + var_s0_2 = 0; + Math_Vec3f_Copy(sp6C, &sp94); + + if ((spA0->normal.y > -0x6665) && (spA0->normal.y < 0x3FFF)) { + temp_v1 = + Math_Vec3f_Yaw(sp6C, &spA4->actor.world.pos) - + Math_Atan2S_XY(spA0->normal.z * COLPOLY_NORMAL_FRAC, spA0->normal.x * COLPOLY_NORMAL_FRAC); + var_s0_2 = (ABS_ALT(temp_v1) > 0x4000) ? 1 : 0LL; // TODO: make less fake + } + if ((this->unk_0192 == 3) && (var_s0_2 || (spA0->normal.y >= 0x4000))) { + this->unk_0192 = 4; + this->unk_01AA = 0; + if (!sp58) { + Audio_PlaySfx_AtPos(&this->unk_0464, NA_SE_EN_COMMON_E_BALL_HIT); + } + } else { + sp7C.x = spA0->normal.x * COLPOLY_NORMAL_FRAC; + sp7C.y = spA0->normal.y * COLPOLY_NORMAL_FRAC; + sp7C.z = spA0->normal.z * COLPOLY_NORMAL_FRAC; + func_80179F64(&this->unk_37AC, &sp7C, &sp70); + Math_Vec3f_Copy(&this->unk_37AC, &sp70); + } + } else { + Math_Vec3f_Copy(sp6C, &sp88); + } + this->unk_37B8.dim.worldSphere.center.x = sp6C->x; + this->unk_37B8.dim.worldSphere.center.y = sp6C->y; + this->unk_37B8.dim.worldSphere.center.z = sp6C->z; + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_37B8.base); + } + } +} + +void BossHakugin_Update(Actor* thisx, PlayState* play) { + s32 pad; + BossHakugin* this = (BossHakugin*)thisx; + Vec3s sp70; + Player* player = GET_PLAYER(play); + + this->unk_0190 = false; + DECR(this->unk_019A); + + if ((this->actionFunc != func_80B09EDC) && !func_80B0ADFC(this, play)) { + func_80B0AC30(this, play); + } + func_80B0607C(this, play); + Actor_OffsetOfPointInActorCoords(&this->actor, &this->unk_044C, &player->actor.world.pos); + this->actionFunc(this, play); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(play, &this->actor, 450.0f, 89.100006f, 0.0f, + UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_4 | UPDBGCHECKINFO_FLAG_8 | + UPDBGCHECKINFO_FLAG_10); + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &sp70); + Math_ScaledStepToS(&this->actor.shape.rot.x, sp70.x, 0x100); + Math_ScaledStepToS(&this->actor.shape.rot.z, sp70.z, 0x100); + if (this->actionFunc == func_80B0A8C4) { + func_80B0B34C(this); + } else { + func_80B0B238(this); + } + func_80B0B3F4(this); + func_80B0B548(this, play); + func_80B0B660(this, play); + func_80B05B04(this, play); + func_80B05CBC(this, player); + func_80B05D4C(this); + if ((this->unk_0484.base.atFlags & AT_ON) && (this->actor.colorFilterTimer == 0)) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_0484.base); + } else { + this->unk_0484.base.atFlags &= ~AT_HIT; + } + if (this->unk_01A4 == 0) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_0484.base); + } else { + this->unk_0484.base.acFlags &= ~AC_HIT; + this->unk_01A4--; + } + if (this->unk_0484.base.ocFlags1 & OC1_ON) { + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_0484.base); + } else { + this->unk_0484.base.ocFlags1 &= ~OC1_HIT; + } + if (this->unk_01E4 > 0.0f) { + if (this->unk_0196 != 10) { + Math_StepToF(&this->unk_01E4, 0.0f, 0.05f); + this->unk_01DC = (this->unk_01E4 + 1.0f) * 1.25f; + this->unk_01DC = CLAMP_MAX(this->unk_01DC, 2.5f); + } else if (!Math_StepToF(&this->unk_01E0, 2.5f, 5.0f / 12.0f)) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } else { + func_80B07B88(this, play); + } + } + + if (player->actor.floorHeight < -400.0f) { + CollisionPoly* sp68 = NULL; + Vec3f sp5C; + Vec3f sp50; + s32 sp4C; + + if ((fabsf(player->actor.world.pos.z) < 1200.0f) && (fabsf(player->actor.world.pos.x) < 1200.0f)) { + s16 temp_v0_5 = Math_Atan2S_XY(player->actor.world.pos.z, player->actor.world.pos.x); + + sp50.x = Math_SinS(temp_v0_5) * 2000.0f; + sp50.z = Math_CosS(temp_v0_5) * 2000.0f; + } else { + if (player->actor.world.pos.z > 1200.0f) { + sp50.z = 1500.0f; + } else if (player->actor.world.pos.z < -1200.0f) { + sp50.z = -1500.0f; + } else { + sp50.z = player->actor.world.pos.z; + } + if (player->actor.world.pos.x > 1200.0f) { + sp50.x = 1500.0f; + } else if (player->actor.world.pos.x < -1200.0f) { + sp50.x = -1500.0f; + } else { + sp50.x = player->actor.world.pos.x; + } + } + sp50.y = 100.0f; + + if (BgCheck_EntityLineTest1(&play->colCtx, &sp50, &player->actor.world.pos, &sp5C, &sp68, true, true, false, + true, &sp4C)) { + Math_Vec3f_Copy(&player->actor.world.pos, &sp5C); + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + Math_Vec3f_Copy(&player->actor.prevPos, &player->actor.world.pos); + player->actor.floorHeight = player->actor.world.pos.y; + player->actor.world.pos.y = player->actor.world.pos.y + 1.0f; + } else { + player->actor.world.pos.x = 0.0f; + player->actor.world.pos.y = 1.0f; + player->actor.world.pos.z = -1200.0f; + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + Math_Vec3f_Copy(&player->actor.prevPos, &player->actor.world.pos); + player->actor.floorHeight = player->actor.world.pos.y; + } + } +} + +s32 BossHakugin_OverrideLimbDraw(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + static s32 D_80B0EB68 = 4; + static s32 D_80B0EB6C = GOHT_LIMB_FRONT_RIGHT_UPPER_LEG; + BossHakugin* this = THIS; + + if (this->actionFunc == func_80B0A8C4) { + if (limbIndex == GOHT_LIMB_ROOT) { + pos->y -= this->actor.shape.yOffset; + } + if (!(this->unk_01B0 & GOHT_LIMB_FLAG(limbIndex))) { + *dList = NULL; + } + } + + if (!this->unk_0190 && (limbIndex == D_80B0EB6C)) { + Matrix_MultZero(&this->unk_3158[D_80B0EB68][this->unk_0191].unk_00); + D_80B0EB68--; + if (D_80B0EB68 < 0) { + D_80B0EB68 = 4; + } + D_80B0EB6C = D_80B0EAB0[D_80B0EB68]; + } + + if (limbIndex == GOHT_LIMB_HEAD) { + rot->z += this->unk_01A6; + if (this->actionFunc == func_80B0A2A4) { + rot->z += this->unk_0374.z; + rot->y += this->unk_0374.y; + } + } else if (limbIndex == GOHT_LIMB_THORAX_WRAPPER) { + rot->z += (s16)(this->unk_01A6 * 2); + } else if ((limbIndex == GOHT_LIMB_FRONT_LEFT_LEG_ROOT) || (limbIndex == GOHT_LIMB_FRONT_RIGHT_LEG_ROOT)) { + rot->z -= (s16)(this->unk_01A6 * 3); + } + + return false; +} + +void BossHakugin_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + BossHakugin* this = THIS; + s8 bodyPartIndex; + s32 i; + f32 cos; + s16 angle; + + Collider_UpdateSpheres(limbIndex, &this->unk_0484); + bodyPartIndex = sLimbToBodyParts[limbIndex]; + if (bodyPartIndex > BODYPART_NONE) { + for (i = 0; i < ARRAY_COUNT(this->unk_04A4); i++) { + if (this->unk_0484.elements[i].dim.limb == limbIndex) { + Math_Vec3s_ToVec3f(&this->bodyPartsPos[bodyPartIndex], + &this->unk_0484.elements[i].dim.worldSphere.center); + break; + } + } + if (i == ARRAY_COUNT(this->unk_04A4)) { + Matrix_MultZero(&this->bodyPartsPos[bodyPartIndex]); + } + } + if (limbIndex == GOHT_LIMB_HEAD) { + Matrix_MultVecX(3500.0f, &this->actor.focus.pos); + this->actor.focus.rot.y = this->actor.shape.rot.y; + if (this->actionFunc != func_80B0A2A4) { + Matrix_MtxFToYXZRot(Matrix_GetCurrent(), &this->unk_0374, false); + } + + if (this->unk_01C8 > 0.0f) { + angle = 0x12C0 - this->unk_0374.z; + cos = Math_CosS(angle); + this->unk_0380.x = this->actor.focus.pos.x - (Math_SinS(this->actor.shape.rot.y) * (60.0f * cos)); + this->unk_0380.y = this->actor.focus.pos.y - (Math_SinS(angle) * 60.0f); + this->unk_0380.z = this->actor.focus.pos.z - (Math_CosS(this->actor.shape.rot.y) * (60.0f * cos)); + } + } +} + +void func_80B0C398(BossHakugin* this, PlayState* play) { + BossHakuginEffect* effect; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, gGohtRockMaterialDL); + for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { + effect = &this->unk_09F8[i]; + if ((effect->unk_18 >= 0) && (effect->unk_1A == 0)) { + Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); + Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGohtRockModelDL); + } + } + + gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteMaterialDL); + for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { + effect = &this->unk_09F8[i]; + if ((effect->unk_18 >= 0) && (effect->unk_1A == 1)) { + Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); + Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteModelDL); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80B0C570(BossHakugin* this, PlayState* play) { + BossHakuginFhgFlashUnkStruct* iter; + s32 i; + s32 j; + s16 camYaw; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamMaterialDL); + camYaw = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000; + gDPSetEnvColor(POLY_XLU_DISP++, 1, 1, 1, 128); + + for (i = 0; i < ARRAY_COUNT(this->unk_3158); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_3158[0]); j++) { + iter = &this->unk_3158[i][j]; + if (iter->unk_10 > 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, iter->unk_10); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, iter->unk_12 * 3, iter->unk_12 * 15, 32, 64, 1, 0, 0, + 32, 32)); + Matrix_Translate(iter->unk_00.x, iter->unk_00.y, iter->unk_00.z, MTXMODE_NEW); + Matrix_RotateYS(camYaw, MTXMODE_APPLY); + Matrix_Scale(iter->unk_0C, iter->unk_0C, 1.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamModelDL); + } + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80B0C7B0(BossHakugin* this, PlayState* play) { + s32 pad; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + if (this->unk_01C8 > 0.0f) { + gDPSetEnvColor(POLY_XLU_DISP++, D_80B0EAD0.r, D_80B0EAD0.g, D_80B0EAD0.b, 0); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningMaterialDL); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + + for (i = -1; i <= 1; i += 2) { + Matrix_SetTranslateRotateYXZ(this->unk_0380.x, this->unk_0380.y, this->unk_0380.z, &this->unk_0374); + Matrix_RotateYS(0x1400 * i, MTXMODE_APPLY); + Matrix_RotateXS(0xC00 * i, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_0198, MTXMODE_APPLY); + Matrix_Scale(0.62f, 0.62f, this->unk_01D0, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, this->unk_01CC * i, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL); + + Matrix_RotateZS(0x4000, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL); + } + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, D_80B0EACC.r, D_80B0EACC.g, D_80B0EACC.b, 0); + Matrix_Translate(this->unk_0380.x, this->unk_0380.y, this->unk_0380.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_Scale(this->unk_01C8, this->unk_01C8, this->unk_01C8, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_0198, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbModelDL); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80B0CAF0(BossHakugin* this, PlayState* play) { + BossHakuginUnkStruct_2618* iter; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, D_80B0EAD0.r, D_80B0EAD0.g, D_80B0EAD0.b, 0); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningMaterialDL); + + for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { + iter = &this->unk_2618[i]; + + if ((iter->unk_0C > 0) && (iter->unk_0C <= 255)) { + Matrix_SetTranslateRotateYXZ(iter->unk_00.x, iter->unk_00.y, iter->unk_00.z, &iter->unk_0E); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, iter->unk_0C); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL); + + Matrix_RotateZS(0x4000, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80B0CCD8(BossHakugin* this, PlayState* play2) { + s32 pad[4]; + PlayState* play = play2; + s32 end; + f32 scale; + s32 i; + s16 rotZ; + s32 alpha; + Vec3f* pos; + + if (this->unk_0192 == 4) { + i = 9; + end = this->unk_01AA; + } else if (this->unk_01AA != 0) { + i = this->unk_01AA - 1; + end = 0; + } else { + return; + } -extern ColliderJntSphElementInit D_80B0E700[19]; -extern ColliderJntSphInit D_80B0E9AC; -extern ColliderTrisElementInit D_80B0E9BC[1]; -extern ColliderTrisInit D_80B0E9F8; -extern ColliderSphereInit D_80B0EA08; -extern ColliderCylinderInit D_80B0EA34; -extern DamageTable D_80B0EA60; -extern CollisionCheckInfoInit D_80B0EA80; -extern InitChainEntry D_80B0EAD8[]; - -extern UNK_TYPE D_06002054; -extern UNK_TYPE D_0600319C; -extern UNK_TYPE D_06010488; -extern UNK_TYPE D_06011208; -extern UNK_TYPE D_06012ED0; -extern UNK_TYPE D_060134D0; -extern UNK_TYPE D_06013828; -extern UNK_TYPE D_06014040; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/BossHakugin_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/BossHakugin_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0573C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B057A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B058C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B05A64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B05B04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B05CBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B05D4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B05EE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0607C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06558.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06600.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0696C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06B20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06C08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06D38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B06F48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0728C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07450.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07700.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0791C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07B88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07BFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B07EEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08018.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0813C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0825C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B082AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08550.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0863C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08848.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08960.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08C1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B08CB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09178.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B091D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B093C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B094E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09840.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B098BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09A94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09C78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09DFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09E20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09E84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09EDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B09F7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0A2A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0A5EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0A638.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0A87C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0A8C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0AC30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0ADFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0B238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0B34C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0B3F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0B548.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0B660.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/BossHakugin_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0C000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0C1BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0C398.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0C570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0C7B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0CAF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0CCD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0CF24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/BossHakugin_Draw.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0D2B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0D69C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0D750.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0D9CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0DFA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0E548.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_Hakugin/func_80B0E5A4.s") + scale = 30.0f - ((i - 1) * 1.5f); + alpha = 215 - (i * 15); + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gDPSetEnvColor(POLY_XLU_DISP++, D_80B0EACC.r, D_80B0EACC.g, D_80B0EACC.b, 0); + + rotZ = this->unk_0198; + + gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbMaterialDL); + + for (; i >= end; i--) { + pos = &this->unk_3734[i]; + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, alpha); + Matrix_Translate(pos->x, pos->y, pos->z, MTXMODE_NEW); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_RotateZS(rotZ, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbModelDL); + + scale += 1.5f; + alpha += 15; + rotZ += 0x1000; + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80B0CF24(BossHakugin* this, PlayState* play) { + s32 pad; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + func_800B8118(&this->actor, play, 0); + Matrix_Translate(this->unk_0964.dim.pos.x, this->unk_0964.dim.pos.y, this->unk_0964.dim.pos.z, MTXMODE_NEW); + Matrix_Scale(4.0f, this->unk_01D4, 4.0f, MTXMODE_APPLY); + Matrix_RotateYS(0xF00, MTXMODE_APPLY); + Matrix_RotateXS(0x500, MTXMODE_APPLY); + Matrix_RotateZS(-0x500, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, play->gameplayFrames & 0xFF, 32, 16, 1, 0, + (play->gameplayFrames * 2) & 0xFF, 64, 32)); // check + gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, this->unk_0193); + gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void BossHakugin_Draw(Actor* thisx, PlayState* play) { + s32 pad; + BossHakugin* this = THIS; + u8* tex = GRAPH_ALLOC(play->state.gfxCtx, GOHT_SHADOW_TEX_SIZE); + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, D_80B0EA88); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + BossHakugin_OverrideLimbDraw, BossHakugin_PostLimbDraw, &this->actor); + + CLOSE_DISPS(play->state.gfxCtx); + + Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, GOHT_BODYPART_MAX, this->unk_01DC, this->unk_01E0, + this->unk_01E4, this->unk_0196); + + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->unk_0380, &this->unk_0458); + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->unk_3734[0], &this->unk_0464); + + if (!this->unk_0190) { + func_80B06F48(this, play); + } + this->unk_0190 = true; + + if (this->actor.colorFilterTimer != 0) { + func_800AE5A0(play); + } + + if (this->actionFunc == func_80B0A8C4) { + func_80B0E5A4(&this->actor, play); + } else { + func_80B0C398(this, play); + } + + func_80B0C570(this, play); + func_80B0C7B0(this, play); + func_80B0CAF0(this, play); + func_80B0CCD8(this, play); + + if (this->unk_0193 > 0) { + func_80B0CF24(this, play); + } + + if (this->actionFunc != func_80B0A8C4) { + BossHakugin_GenShadowTex(tex, this); + BossHakugin_DrawShadowTex(tex, this, play); + } +} + +s32 D_80B0EB70[6] = { 1, 2, 3, 3, 2, 1 }; +s32 D_80B0EB88[7] = { 2, 3, 4, 4, 4, 3, 2 }; +s32 D_80B0EBA4[8] = { 2, 3, 4, 4, 4, 4, 3, 2 }; +s32 D_80B0EBC4[14] = { 2, 4, 5, 6, 7, 8, 8, 8, 8, 7, 6, 5, 4, 2 }; + +static s32 sParentShadowBodyParts[GOHT_BODYPART_MAX] = { + GOHT_BODYPART_THORAX, // GOHT_BODYPART_PELVIS + BODYPART_NONE, // GOHT_BODYPART_THORAX + GOHT_BODYPART_THORAX, // GOHT_BODYPART_HEAD + GOHT_BODYPART_THORAX, // GOHT_BODYPART_FRONT_RIGHT_UPPER_LEG + GOHT_BODYPART_FRONT_RIGHT_UPPER_LEG, // GOHT_BODYPART_FRONT_RIGHT_LOWER_LEG + GOHT_BODYPART_FRONT_RIGHT_LOWER_LEG, // GOHT_BODYPART_FRONT_RIGHT_HOOF + GOHT_BODYPART_THORAX, // GOHT_BODYPART_FRONT_LEFT_UPPER_LEG + GOHT_BODYPART_FRONT_LEFT_UPPER_LEG, // GOHT_BODYPART_FRONT_LEFT_LOWER_LEG + GOHT_BODYPART_FRONT_LEFT_LOWER_LEG, // GOHT_BODYPART_FRONT_LEFT_HOOF + GOHT_BODYPART_PELVIS, // GOHT_BODYPART_BACK_RIGHT_THIGH + GOHT_BODYPART_BACK_RIGHT_THIGH, // GOHT_BODYPART_BACK_RIGHT_SHIN + GOHT_BODYPART_BACK_RIGHT_SHIN, // GOHT_BODYPART_BACK_RIGHT_HOOF + GOHT_BODYPART_PELVIS, // GOHT_BODYPART_BACK_LEFT_THIGH + GOHT_BODYPART_BACK_LEFT_THIGH, // GOHT_BODYPART_BACK_LEFT_SHIN + GOHT_BODYPART_BACK_LEFT_SHIN // GOHT_BODYPART_BACK_LEFT_HOOF +}; + +static u8 sShadowSizes[GOHT_BODYPART_MAX] = { + 1, // GOHT_BODYPART_PELVIS + 2, // GOHT_BODYPART_THORAX + 1, // GOHT_BODYPART_HEAD + 0, // GOHT_BODYPART_FRONT_RIGHT_UPPER_LEG + 3, // GOHT_BODYPART_FRONT_RIGHT_LOWER_LEG + 3, // GOHT_BODYPART_FRONT_RIGHT_HOOF + 0, // GOHT_BODYPART_FRONT_LEFT_UPPER_LEG + 3, // GOHT_BODYPART_FRONT_LEFT_LOWER_LEG + 3, // GOHT_BODYPART_FRONT_LEFT_HOOF + 0, // GOHT_BODYPART_BACK_RIGHT_THIGH + 3, // GOHT_BODYPART_BACK_RIGHT_SHIN + 3, // GOHT_BODYPART_BACK_RIGHT_HOOF + 0, // GOHT_BODYPART_BACK_LEFT_THIGH + 3, // GOHT_BODYPART_BACK_LEFT_SHIN + 3 // GOHT_BODYPART_BACK_LEFT_HOOF +}; + +void BossHakugin_FillShadowTex(BossHakugin* this, u8* tex, f32 weight) { + s32 index; + s32 i; + s32 baseX; + s32 baseY; + s32 addY; + s32 x; + s32 y = BODYPART_NONE; + Vec3f lerp; + Vec3f* parentBodyPartPos; + Vec3f* bodyPartPos; + Vec3f pos; + Vec3f startVec; + + for (i = 0; i < GOHT_BODYPART_MAX; i++) { + if ((weight == 0.0f) || (y = sParentShadowBodyParts[i]) > BODYPART_NONE) { + bodyPartPos = &this->bodyPartsPos[i]; + if (weight > 0.0f) { + parentBodyPartPos = &this->bodyPartsPos[y]; + + VEC3F_LERPIMPDST(&lerp, bodyPartPos, parentBodyPartPos, weight); + + pos.x = lerp.x - this->actor.world.pos.x; + pos.y = lerp.y - this->actor.world.pos.y + 76.0f + 30.0f + 30.0f + 600.0f; + pos.z = lerp.z - this->actor.world.pos.z; + } else { + pos.x = bodyPartPos->x - this->actor.world.pos.x; + pos.y = bodyPartPos->y - this->actor.world.pos.y + 76.0f + 30.0f + 30.0f + 600.0f; + pos.z = bodyPartPos->z - this->actor.world.pos.z; + } + Matrix_MultVec3f(&pos, &startVec); + + startVec.x *= 0.07f; + startVec.y *= 0.07f; + + baseX = (u16)(s32)(startVec.x + 32.0f); + baseY = (u16)((s32)startVec.y * 64); + + if (sShadowSizes[i] == 2) { + for (y = 0, addY = -0x180; y < ARRAY_COUNT(D_80B0EBC4); y++, addY += 0x40) { + for (x = -D_80B0EBC4[y]; x < D_80B0EBC4[y]; x++) { + index = baseX + x + baseY + addY; + if ((index >= 0) && (index < GOHT_SHADOW_TEX_SIZE)) { + tex[index] = 255; + } + } + } + } else if (sShadowSizes[i] == 1) { + for (y = 0, addY = -0x100; y < ARRAY_COUNT(D_80B0EBA4); y++, addY += 0x40) { + for (x = -D_80B0EBA4[y]; x < D_80B0EBA4[y]; x++) { + index = baseX + x + baseY + addY; + if ((index >= 0) && (index < GOHT_SHADOW_TEX_SIZE)) { + tex[index] = 255; + } + } + } + } else if (sShadowSizes[i] == 0) { + for (y = 0, addY = -0xC0; y < ARRAY_COUNT(D_80B0EB88); y++, addY += 0x40) { + for (x = -D_80B0EB88[y]; x < D_80B0EB88[y]; x++) { + index = baseX + x + baseY + addY; + if ((index >= 0) && (index < GOHT_SHADOW_TEX_SIZE)) { + tex[index] = 255; + } + } + } + } else { + for (y = 0, addY = -0x80; y < ARRAY_COUNT(D_80B0EB70); y++, addY += 0x40) { + for (x = -D_80B0EB70[y]; x < D_80B0EB70[y]; x++) { + index = baseX + x + baseY + addY; + if ((index >= 0) && (index < GOHT_SHADOW_TEX_SIZE)) { + tex[index] = 255; + } + } + } + } + } + } +} + +void BossHakugin_GenShadowTex(u8* tex, BossHakugin* this) { + s32* iter = (s32*)tex; + s16 i; + + for (i = 0; i < (s32)(GOHT_SHADOW_TEX_SIZE / sizeof(s32)); i++, iter++) { + *iter = 0; + } + + Matrix_RotateXFNew(1.0f); + + for (i = 0; i <= 5; i++) { + BossHakugin_FillShadowTex(this, tex, i / 5.0f); + } +} + +void BossHakugin_DrawShadowTex(u8* tex, BossHakugin* this, PlayState* play) { + s32 pad[2]; + f32 alpha; + GraphicsContext* gfxCtx = play->state.gfxCtx; + MtxF mtx; + + OPEN_DISPS(gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + alpha = (400.0f - this->actor.world.pos.y) * (1.0f / 400.0f); + alpha = CLAMP_MIN(alpha, 0.0f); + alpha = CLAMP_MAX(alpha, 1.0f); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (s8)(alpha * 80.0f)); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0); + + if (this->actor.floorPoly != NULL) { + func_800C0094(this->actor.floorPoly, this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + &mtx); + Matrix_Put(&mtx); + } + + Matrix_Scale(4.25f, 1.0f, 4.25f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gShadowMaterialDL); + gDPLoadTextureBlock(POLY_OPA_DISP++, tex, G_IM_FMT_I, G_IM_SIZ_8b, GOHT_SHADOW_TEX_WIDTH, GOHT_SHADOW_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD); + gSPDisplayList(POLY_OPA_DISP++, gShadowModelDL); + + CLOSE_DISPS(gfxCtx); +} + +void func_80B0D9CC(BossHakugin* this) { + s32 var_s3; + Vec3f spC8; + s32 var_s1 = 15; + BossHakuginEffect* var_s0 = this->unk_09F8; + s32 var_v1; + s32 temp_a0; + f32 spB4 = Math_SinS(this->actor.shape.rot.y) * 65.0f; + f32 spB0 = Math_CosS(this->actor.shape.rot.y) * 65.0f; + f32 spAC = Math_SinS(this->actor.shape.rot.z) * 65.0f; + f32 temp1; + f32 temp2; + f32 temp3; + f32 temp4; + f32 temp5; + s32 pad; + + for (var_s3 = 4; var_s3 > 0; var_s3--, var_s1 -= 4) { + temp4 = (30.0f / 13.0f) * spB4; + temp5 = (30.0f / 13.0f) * spB0; + + spC8.x = this->actor.world.pos.x - (var_s3 * spB4) + temp4; + spC8.y = this->actor.world.pos.y + (85.0f * (4 - var_s3)) + 20.0f; + spC8.z = this->actor.world.pos.z - (var_s3 * spB0) + temp5; + + var_s0->unk_24 = ((var_s3 * 4.5f) + 22.0f) * 0.001f; + Math_Vec3f_Copy(&var_s0->unk_0, &spC8); + + temp_a0 = var_s1 >> 1; + if (temp_a0 == 0) { + break; + } + var_s0++; + + temp1 = var_s3 / (f32)temp_a0; + temp2 = (spB0 + spB4) * temp1; + temp3 = (spB0 - spB4) * temp1; + + for (var_v1 = 0; var_v1 < temp_a0; var_v1++, var_s0++) { + var_s0->unk_0.x = spC8.x + temp2 * (temp_a0 - var_v1); + var_s0->unk_0.y = spC8.y + var_s3 * spAC; + var_s0->unk_0.z = spC8.z + temp3 * (temp_a0 - var_v1); + var_s0->unk_24 = ((var_s3 * 4.5f) + 22.0f) * 0.001f; + } + + temp4 = (spB4 - spB0) * temp1; + temp5 = (spB0 + spB4) * temp1; + + for (var_v1 = 0; var_v1 < temp_a0; var_v1++, var_s0++) { + var_s0->unk_0.x = spC8.x + temp4 * (temp_a0 - var_v1); + var_s0->unk_0.y = spC8.y - var_s3 * spAC; + var_s0->unk_0.z = spC8.z + temp5 * (temp_a0 - var_v1); + var_s0->unk_24 = ((var_s3 * 4.5f) + 22.0f) * 0.001f; + } + } + + for (var_s3 = 0; var_s3 < 36; var_s3++) { + var_s0 = &this->unk_09F8[var_s3]; + + var_s0->unk_24 += Rand_ZeroFloat(5.0f) * 0.001f; + var_s0->unk_1C.x = (s32)Rand_Next() >> 0x10; + var_s0->unk_1C.y = (s32)Rand_Next() >> 0x10; + var_s0->unk_1C.z = (s32)Rand_Next() >> 0x10; + var_s0->unk_C.x = var_s0->unk_0.y; + var_s0->unk_C.y = 0.0f; + var_s0->unk_0.y += 850.0f; + } +} + +void func_80B0DFA8(BossHakugin* this) { + s32 i; + BossHakuginEffect* effect; + ColliderJntSphElement* element; + + for (i = 0; i < 36 / 2; i++) { + effect = &this->unk_09F8[i << 1]; + element = &this->unk_0484.elements[i]; + + element->dim.worldSphere.center.x = effect->unk_0.x; + element->dim.worldSphere.center.y = effect->unk_0.y; + element->dim.worldSphere.center.z = effect->unk_0.z; + element->dim.worldSphere.radius = effect->unk_24 * 3000.0f; + element->info.bumper.dmgFlags = 0xF3CFBBFF; + element->info.bumperFlags &= ~BUMP_NO_HITMARK; + + element->info.elemType = ELEMTYPE_UNK0; + } + for (; i < ARRAY_COUNT(this->unk_04A4); i++) { + this->unk_0484.elements[i].info.bumperFlags &= ~BUMP_ON; + this->unk_0484.elements[i].info.ocElemFlags &= ~OCELEM_ON; + } + + this->unk_0484.base.colType = COLTYPE_HARD; +} + +void func_80B0E548(Actor* thisx, PlayState* play2) { + BossHakugin* this = THIS; + PlayState* play = play2; + + func_80B0DFA8(this); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_0484.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_0484.base); +} + +void func_80B0E5A4(Actor* thisx, PlayState* play) { + BossHakugin* this = THIS; + s32 i; + BossHakuginEffect* effect; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, gGohtRockMaterialDL); + + for (i = 0; i < 36; i++) { + effect = &this->unk_09F8[i]; + + Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); + Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGohtRockModelDL); + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h index 10a01989a..cd38dc044 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h @@ -2,9 +2,14 @@ #define Z_BOSS_HAKUGIN_H #include "global.h" +#include "objects/object_boss_hakugin/object_boss_hakugin.h" struct BossHakugin; +#define GOHT_SHADOW_TEX_WIDTH 64 +#define GOHT_SHADOW_TEX_HEIGHT 64 +#define GOHT_SHADOW_TEX_SIZE ((s32)sizeof(u8[GOHT_SHADOW_TEX_HEIGHT][GOHT_SHADOW_TEX_WIDTH])) + typedef void (*BossHakuginActionFunc)(struct BossHakugin*, PlayState*); typedef struct BossHakuginEffect { @@ -18,22 +23,104 @@ typedef struct BossHakuginEffect { #define BOSS_HAKUGIN_EFFECT_COUNT 180 +typedef struct BossHakuginUnkStruct_2618 { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ Vec3s unk_0E; + /* 0x14 */ ColliderTris unk_14; + /* 0x34 */ ColliderTrisElement unk_34; +} BossHakuginUnkStruct_2618; // size = 0x90 + typedef struct BossHakuginFhgFlashUnkStruct { /* 0x00 */ Vec3f unk_00; - /* 0x0C */ char unk_0C[0x8]; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ s16 unk_10; + /* 0x12 */ s16 unk_12; } BossHakuginFhgFlashUnkStruct; // size = 0x14 +typedef enum GohtBodyPart { + /* 0 */ GOHT_BODYPART_PELVIS, + /* 1 */ GOHT_BODYPART_THORAX, + /* 2 */ GOHT_BODYPART_HEAD, + /* 3 */ GOHT_BODYPART_FRONT_RIGHT_UPPER_LEG, + /* 4 */ GOHT_BODYPART_FRONT_RIGHT_LOWER_LEG, + /* 5 */ GOHT_BODYPART_FRONT_RIGHT_HOOF, + /* 6 */ GOHT_BODYPART_FRONT_LEFT_UPPER_LEG, + /* 7 */ GOHT_BODYPART_FRONT_LEFT_LOWER_LEG, + /* 8 */ GOHT_BODYPART_FRONT_LEFT_HOOF, + /* 9 */ GOHT_BODYPART_BACK_RIGHT_THIGH, + /* 10 */ GOHT_BODYPART_BACK_RIGHT_SHIN, + /* 11 */ GOHT_BODYPART_BACK_RIGHT_HOOF, + /* 12 */ GOHT_BODYPART_BACK_LEFT_THIGH, + /* 13 */ GOHT_BODYPART_BACK_LEFT_SHIN, + /* 14 */ GOHT_BODYPART_BACK_LEFT_HOOF, + /* 15 */ GOHT_BODYPART_MAX +} GohtBodyPart; + typedef struct BossHakugin { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_0144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ BossHakuginActionFunc actionFunc; - /* 0x018C */ char unk_018C[0x5]; - /* 0x0191 */ u8 unk_191; - /* 0x018C */ char unk_0192[0x866]; - /* 0x09F8 */ BossHakuginEffect unk_9F8[BOSS_HAKUGIN_EFFECT_COUNT]; - /* 0x2618 */ char unk_2618[0x8E8]; - /* 0x2F00 */ BossHakuginFhgFlashUnkStruct unk_2F00[7][15]; - /* 0x3734 */ char unk_3734[0xDC]; + /* 0x018C */ u8 unk_018C; + /* 0x018D */ u8 unk_018D; + /* 0x018E */ u8 unk_018E; + /* 0x018F */ u8 unk_018F; + /* 0x0190 */ u8 unk_0190; // boolean? + /* 0x0191 */ u8 unk_0191; + /* 0x0192 */ u8 unk_0192; + /* 0x0193 */ u8 unk_0193; + /* 0x0194 */ u8 unk_0194; + /* 0x0194 */ u8 unk_0195; + /* 0x0196 */ u8 unk_0196; + /* 0x0198 */ s16 unk_0198; + /* 0x019A */ s16 unk_019A; + /* 0x019C */ s16 unk_019C; + /* 0x019E */ s16 unk_019E; + /* 0x01A0 */ s16 unk_01A0; + /* 0x01A2 */ s16 unk_01A2; + /* 0x01A4 */ s16 unk_01A4; + /* 0x01A6 */ s16 unk_01A6; + /* 0x01A8 */ s16 unk_01A8; // Counter of some kind? + /* 0x01AA */ s16 unk_01AA; + /* 0x01AC */ s16 unk_01AC; + /* 0x01AE */ s16 unk_01AE; + /* 0x01B0 */ u32 unk_01B0; + /* 0x01B4 */ s32 unk_01B4; + /* 0x01B8 */ f32 unk_01B8; + /* 0x01BC */ f32 unk_01BC; + /* 0x01C0 */ f32 unk_01C0; + /* 0x01C4 */ f32 unk_01C4; + /* 0x01C8 */ f32 unk_01C8; + /* 0x01CC */ f32 unk_01CC; + /* 0x01D0 */ f32 unk_01D0; + /* 0x01D4 */ f32 unk_01D4; + /* 0x01D8 */ char unk_01D8[0x4]; // probably unused float + /* 0x01DC */ f32 unk_01DC; + /* 0x01E0 */ f32 unk_01E0; + /* 0x01E4 */ f32 unk_01E4; + /* 0x01E8 */ Vec3s jointTable[GOHT_LIMB_MAX]; + /* 0x02AE */ Vec3s morphTable[GOHT_LIMB_MAX]; + /* 0x0374 */ Vec3s unk_0374; + /* 0x037A */ Vec3s unk_037A; + /* 0x0380 */ Vec3f unk_0380; + /* 0x038C */ Vec3f unk_038C; + /* 0x0398 */ Vec3f bodyPartsPos[GOHT_BODYPART_MAX]; + /* 0x044C */ Vec3f unk_044C; + /* 0x0458 */ Vec3f unk_0458; + /* 0x0464 */ Vec3f unk_0464; + /* 0x0470 */ LightNode* lightNode; + /* 0x0474 */ LightInfo lightInfo; + /* 0x0484 */ ColliderJntSph unk_0484; + /* 0x04A4 */ ColliderJntSphElement unk_04A4[19]; + /* 0x0964 */ ColliderCylinder unk_0964; + /* 0x09B0 */ Actor* unk_09B0[8]; + /* 0x09D0 */ Actor* unk_09D0[10]; + /* 0x09F8 */ BossHakuginEffect unk_09F8[BOSS_HAKUGIN_EFFECT_COUNT]; + /* 0x2618 */ BossHakuginUnkStruct_2618 unk_2618[20]; + /* 0x3158 */ BossHakuginFhgFlashUnkStruct unk_3158[5][15]; + /* 0x3734 */ Vec3f unk_3734[10]; + /* 0x37AC */ Vec3f unk_37AC; + /* 0x37B8 */ ColliderSphere unk_37B8; } BossHakugin; // size = 0x3810 #endif // Z_BOSS_HAKUGIN_H diff --git a/src/overlays/actors/ovl_En_Death/z_en_death.c b/src/overlays/actors/ovl_En_Death/z_en_death.c index 0eb9268f7..80b294063 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.c +++ b/src/overlays/actors/ovl_En_Death/z_en_death.c @@ -6,6 +6,9 @@ #include "z_en_death.h" #include "z64rumble.h" +#include "overlays/actors/ovl_Arrow_Light/z_arrow_light.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "prevent_bss_reordering2.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_IGNORE_QUAKE) @@ -15,119 +18,212 @@ void EnDeath_Init(Actor* thisx, PlayState* play); void EnDeath_Destroy(Actor* thisx, PlayState* play); void EnDeath_Update(Actor* thisx, PlayState* play); void EnDeath_Draw(Actor* thisx, PlayState* play); - -void func_808C589C(EnDeath* this, PlayState* play); -void func_808C5AB8(EnDeath* this, PlayState* play); -void func_808C5CB4(EnDeath* this, PlayState* play); -void func_808C5E90(EnDeath* this, PlayState* play); -void func_808C6070(EnDeath* this, PlayState* play); -void func_808C64DC(EnDeath* this, PlayState* play); -void func_808C66A8(EnDeath* this, PlayState* play); -void func_808C682C(EnDeath* this, PlayState* play); -void func_808C692C(EnDeath* this, PlayState* play); -void func_808C6AB0(EnDeath* this, PlayState* play); -void func_808C6CDC(EnDeath* this, PlayState* play); -void func_808C6F6C(EnDeath* this, PlayState* play); -void func_808C72AC(EnDeath* this, PlayState* play); -void func_808C74F8(EnDeath* this, PlayState* play); -void func_808C7888(EnDeath* this, PlayState* play); -void func_808C7AAC(EnDeath* this, PlayState* play); +void EnDeath_IntroCutscenePart1(EnDeath* this, PlayState* play); +void EnDeath_IntroCutscenePart2(EnDeath* this, PlayState* play); +void EnDeath_IntroCutscenePart3(EnDeath* this, PlayState* play); +void EnDeath_IntroCutscenePart4(EnDeath* this, PlayState* play); +void EnDeath_IntroCutscenePart5(EnDeath* this, PlayState* play); +void EnDeath_ApproachPlayer(EnDeath* this, PlayState* play); +void EnDeath_SwingAttack(EnDeath* this, PlayState* play); +void EnDeath_EndSwingAttack(EnDeath* this, PlayState* play); +void EnDeath_BlockProjectile(EnDeath* this, PlayState* play); +void EnDeath_SpinAttack(EnDeath* this, PlayState* play); +void EnDeath_Damaged(EnDeath* this, PlayState* play); +void EnDeath_DeathCutscenePart1(EnDeath* this, PlayState* play); +void EnDeath_DeathCutscenePart2(EnDeath* this, PlayState* play); +void EnDeath_DeathCutscenePart3(EnDeath* this, PlayState* play); +void EnDeath_DeathCutscenePart4(EnDeath* this, PlayState* play); +void EnDeath_Dead(EnDeath* this, PlayState* play); void func_808C7B88(EnDeath* this, PlayState* play); void func_808C7C88(EnDeath* this, PlayState* play); -void func_808C7D34(EnDeath* this, PlayState* play); -void func_808C7DCC(EnDeath* this, PlayState* play); +void EnDeath_PlayCutscene(EnDeath* this, PlayState* play); +void EnDeath_BeginWithoutCutscene(EnDeath* this, PlayState* play); -#if 0 -ActorInit En_Death_InitVars = { - /**/ ACTOR_EN_DEATH, - /**/ ACTORCAT_ENEMY, - /**/ FLAGS, - /**/ OBJECT_DEATH, - /**/ sizeof(EnDeath), - /**/ EnDeath_Init, - /**/ EnDeath_Destroy, - /**/ EnDeath_Update, - /**/ EnDeath_Draw, +void EnDeath_SetupIntroCutscenePart2(EnDeath* this, PlayState* play); +void EnDeath_SetupIntroCutscenePart3(EnDeath* this); +void EnDeath_SetupIntroCutscenePart4(EnDeath* this, PlayState* play); +void EnDeath_SetupIntroCutscenePart5(EnDeath* this, PlayState* play); +void EnDeath_SetupApproachPlayer(EnDeath* this); +void EnDeath_SetupSwingAttack(EnDeath* this); +void EnDeath_SetupEndSwingAttack(EnDeath* this); +void EnDeath_SetupBlockProjectile(EnDeath* this); +void EnDeath_SetupSpinAttack(EnDeath* this); +void EnDeath_SetupDeathCutscenePart2(EnDeath* this, PlayState* play); +void EnDeath_SetupDeathCutscenePart3(EnDeath* this); +void EnDeath_SetupDead(EnDeath* this, PlayState* play); +void func_808C7AEC(EnDeath* this); +void func_808C7C04(EnDeath* this); +void EnDeath_SetupPlayCutscene(EnDeath* this); +void EnDeath_SetupBeginWithoutCutscene(EnDeath* this); +void EnDeath_SetupDeathCutscenePart4(EnDeath* this); + +const ActorInit En_Death_InitVars = { + ACTOR_EN_DEATH, + ACTORCAT_ENEMY, + FLAGS, + OBJECT_DEATH, + sizeof(EnDeath), + (ActorFunc)EnDeath_Init, + (ActorFunc)EnDeath_Destroy, + (ActorFunc)EnDeath_Update, + (ActorFunc)EnDeath_Draw, }; // static ColliderSphereInit sSphereInit = { static ColliderSphereInit D_808C98E0 = { - { COLTYPE_HIT3, AT_NONE, AC_NONE | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + COLTYPE_HIT3, + AT_NONE, + AC_NONE | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 1, { { 0, 0, 0 }, 22 }, 100 }, }; // static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_808C990C = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 35, 90, 20, { 0, 0, 0 } }, }; // static ColliderTrisElementInit sTrisElementsInit[2] = { static ColliderTrisElementInit D_808C9938[2] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x04, 0x20 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x04, 0x20 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, }; // static ColliderTrisInit sTrisInit = { static ColliderTrisInit D_808C99B0 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, }, - ARRAY_COUNT(sTrisElementsInit), D_808C9938, // sTrisElementsInit, + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + 2, + D_808C9938, // sTrisElementsInit, }; // static ColliderQuadInit sQuadInit = { static ColliderQuadInit D_808C99C0 = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_2, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x20 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, BUMP_NONE, OCELEM_NONE, }, + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x20 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; +typedef enum { + DMGEFF_NONE = 0, + DMGEFF_FIRE_ARROW = 2, + DMGEFF_ICE_ARROW = 3, + DMGEFF_LIGHT_ARROW = 4, + DMGEFF_EXPLOSIVES = 15 +} EnDeathDamageEffect; + // static DamageTable sDamageTable = { static DamageTable D_808C9A10 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(1, 0x0), - /* Goron punch */ DMG_ENTRY(1, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x0), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* Sword beam */ DMG_ENTRY(0, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0xF), + /* Deku Nut */ DMG_ENTRY(0, DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(1, DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DMGEFF_EXPLOSIVES), + /* Zora boomerang */ DMG_ENTRY(1, DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(0, DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(1, DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal shield */ DMG_ENTRY(0, DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DMGEFF_EXPLOSIVES), }; // sColChkInfoInit static CollisionCheckInfoInit2 D_808C9A30 = { 20, 28, 90, 20, 100 }; +static EffectBlureInit2 D_808C9A3C = { + 0, 8, 0, { 100, 50, 100, 200 }, { 100, 0, 0, 64 }, { 100, 0, 0, 20 }, { 50, 0, 0, 0 }, 8, + 0, 2, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, +}; + // static InitChainEntry sInitChain[] = { static InitChainEntry D_808C9A60[] = { ICHAIN_VEC3F(scale, 0, ICHAIN_CONTINUE), @@ -136,144 +232,1531 @@ static InitChainEntry D_808C9A60[] = { ICHAIN_U8(targetMode, TARGET_MODE_5, ICHAIN_STOP), }; -#endif +void EnDeath_Init(Actor* thisx, PlayState* play) { + EnDeath* this = THIS; + PlayState* play2 = play; + f32 yOffset = 15.0f; + s16 yRot = 0; + s32 i; -extern ColliderSphereInit D_808C98E0; -extern ColliderCylinderInit D_808C990C; -extern ColliderTrisElementInit D_808C9938[2]; -extern ColliderTrisInit D_808C99B0; -extern ColliderQuadInit D_808C99C0; -extern DamageTable D_808C9A10; -extern CollisionCheckInfoInit2 D_808C9A30; -extern InitChainEntry D_808C9A60[]; + Actor_ProcessInitChain(&this->actor, D_808C9A60); + ActorShape_Init(&this->actor.shape, 5500.0f, ActorShadow_DrawCircle, 80.0f); -extern UNK_TYPE D_06000E64; -extern UNK_TYPE D_060015B4; -extern UNK_TYPE D_06001834; -extern UNK_TYPE D_06001F80; -extern UNK_TYPE D_06002DE8; -extern UNK_TYPE D_0600352C; -extern UNK_TYPE D_06003CAC; -extern UNK_TYPE D_06006F88; -extern UNK_TYPE D_060073D0; -extern UNK_TYPE D_06009988; -extern UNK_TYPE D_06009F10; -extern UNK_TYPE D_0600B284; -extern UNK_TYPE D_0600B508; -extern UNK_TYPE D_0600CB2C; + SkelAnime_InitFlex(play2, &this->skelAnime, &gGomessSkel, &gGomessFloatAnim, this->jointTable, + this->morphTable, GOMESS_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/EnDeath_Init.s") + Collider_InitAndSetSphere(play2, &this->coreCollider, &this->actor, &D_808C98E0); + Collider_InitAndSetCylinder(play2, &this->bodyCollider, &this->actor, &D_808C990C); + Collider_InitAndSetQuad(play2, &this->unk_788, &this->actor, &D_808C99C0); + Collider_InitAndSetTris(play2, &this->unk_860, &this->actor, &D_808C99B0, this->unk_880); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/EnDeath_Destroy.s") + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5310.s") + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &D_808C9A10, &D_808C9A30); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5394.s") + Effect_Add(play2, &this->effectIndex, EFFECT_BLURE2, 0, 0, &D_808C9A3C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5428.s") + if (!(gSaveContext.eventInf[6] & 8)) { + this->actor.world.pos.y += 400.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C54F0.s") + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i] = (EnMinideath*)Actor_SpawnAsChild( + &play2->actorCtx, &this->actor, play2, ACTOR_EN_MINIDEATH, this->actor.world.pos.x, + this->actor.world.pos.y + yOffset, this->actor.world.pos.z, 0, yRot, 0, i); + if (this->miniDeaths[i] == NULL) { + Actor_Kill(&this->actor); + } + yRot += 0x3A00; + yOffset += 4.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C566C.s") + for (i = 0; i < ARRAY_COUNT(this->miniDeaths) - 1; i++) { + this->miniDeaths[i]->actor.child = &this->miniDeaths[i + 1]->actor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C571C.s") + this->bodyMatAnim = Lib_SegmentedToVirtual(&gGomessBodyMatAnim); + this->coreMatAnim = Lib_SegmentedToVirtual(&gGomessCoreMatAnim); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C589C.s") + if (gSaveContext.eventInf[6] & 8) { + // Watched intro cutscene + this->unk_18E = true; + Actor_SetScale(&this->actor, 0.01f); + this->unk_191 = 0x17; + this->actor.params = 20; + this->scytheScale = 1.0f; + EnDeath_SetupBeginWithoutCutscene(this); + } else { + // Start intro cutscene + this->unk_192 = true; + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + EnDeath_SetupPlayCutscene(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C597C.s") +void EnDeath_Destroy(Actor* thisx, PlayState* play) { + EnDeath* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5AB8.s") + Collider_DestroySphere(play, &this->coreCollider); + Collider_DestroyCylinder(play, &this->bodyCollider); + Collider_DestroyQuad(play, &this->unk_788); + Collider_DestroyTris(play, &this->unk_860); + AudioSfx_StopByPos(&this->scytheScreenPos); + Effect_Destroy(play, this->effectIndex); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5C0C.s") +void EnDeath_DimLights(PlayState* play) { + EnvLightSettings* lightSettings; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5CB4.s") + play->envCtx.lightSettingOverride = 20; + play->envCtx.lightSetting = 20; + play->envCtx.prevLightSetting = 20; + play->envCtx.lightBlend = 1.0f; + lightSettings = &play->envCtx.lightSettingsList[20]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5D6C.s") + for (i = 0; i != 3; i++) { + lightSettings->light1Dir[i] = play->envCtx.lightSettings.light1Dir[i]; + lightSettings->light2Dir[i] = play->envCtx.lightSettings.light2Dir[i]; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5E90.s") +void EnDeath_Float(EnDeath* this) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_SHARP_FLOAT - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C5F58.s") + if (this->floatTimer == 0) { + this->floatTimer = 40; + } + this->floatTimer--; + this->actor.world.pos.y = this->actor.home.pos.y + (1.0f - Math_CosS(this->floatTimer * 0x666)) * 7.5f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6070.s") +s32 EnDeath_ProjectileApproaching(EnDeath* this, PlayState* play) { + Actor* projectileActor = + func_800BC270(play, &this->actor, 80.0f, 0x10000 | 0x2000 | 0x1000 | 0x800 | 0x80 | 0x20 | 0x10); + s16 ret; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C645C.s") + if (projectileActor != NULL && + (ret = Actor_WorldYawTowardActor(&this->actor, projectileActor) - this->actor.shape.rot.y, + ABS_ALT(ret) < 0x2000) && + (ret = Actor_WorldPitchTowardPoint(projectileActor, &this->actor.focus.pos) - projectileActor->world.rot.x, + ABS_ALT(ret) < 0x3000)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C64DC.s") +void EnDeath_UpdateSpinAttackTris(EnDeath* this) { + f32 sinRotY = Math_SinS(this->actor.shape.rot.y); + f32 cosRotY = Math_CosS(this->actor.shape.rot.y); + Vec3f sp54; + Vec3f sp48; + Vec3f sp3C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6620.s") + sp3C.x = this->actor.world.pos.x - 70.0f * cosRotY + 75.0f * sinRotY; + sp3C.y = this->actor.world.pos.y + -10.0f; + sp3C.z = this->actor.world.pos.z + 70.0f * sinRotY + 75.0f * cosRotY; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C66A8.s") + sp48.x = this->actor.world.pos.x + 70.0f * cosRotY + 65.0f * sinRotY; + sp48.y = sp3C.y + 150.0f; + sp48.z = this->actor.world.pos.z - 70.0f * sinRotY + 65.0f * cosRotY; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C67C8.s") + sp54.x = sp3C.x; + sp54.x += -10.0f * sinRotY; + sp54.y = sp48.y; + sp54.z = sp3C.z; + sp54.z += -10.0f * cosRotY; + Collider_SetTrisVertices(&this->unk_860, 0, &sp3C, &sp48, &sp54); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C682C.s") + sp54.x = sp48.x; + sp54.x += 10.0f * sinRotY; + sp54.y = sp3C.y; + sp54.z = sp48.z; + sp54.z += 10.0f * cosRotY; + Collider_SetTrisVertices(&this->unk_860, 1, &sp3C, &sp54, &sp48); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C68B8.s") +f32 EnDeath_UpdateCoreVelocityAndRotation(EnDeath* this) { + f32 tmp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C692C.s") + this->coreVelocity = this->actor.world.pos.y - this->actor.home.pos.y; + this->coreVelocity = CLAMP_MIN(this->coreVelocity, 0.0f); + this->coreVelocity *= 0.02f; + this->coreVelocity = SQ(this->coreVelocity) * 3.0f + 80.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6A08.s") + tmp = 22.5f / (this->coreVelocity * (2 * M_PI)); + this->coreRotation += (s16)(65536.0f * tmp); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6AB0.s") +void EnDeath_SetupIntroCutscenePart1(EnDeath* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Vec3f eye; + Vec3f at; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6C5C.s") + this->actor.shape.rot.y = this->actor.shape.rot.y - 0x657A; + this->actionTimer = 60; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6CDC.s") + eye.x = (Math_SinS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.x; + eye.z = (Math_CosS(this->actor.home.rot.y + 0x98) * 542.0f) + this->actor.world.pos.z; + eye.y = this->actor.home.pos.y + 3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6D40.s") + at.x = this->actor.world.pos.x; + at.z = this->actor.world.pos.z; + at.y = this->actor.world.pos.y - 116.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C6F6C.s") + player->actor.world.pos.x = Math_SinS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.x; + player->actor.world.pos.z = Math_CosS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.z; + player->actor.shape.rot.y = Actor_WorldYawTowardActor(&player->actor, &this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C70D8.s") + Play_SetCameraAtEye(play, this->camId, &at, &eye); + Play_SetCameraFov(play, this->camId, 77.0f); + func_800B724C(play, &this->actor, 0x15); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C72AC.s") + this->actionFunc = EnDeath_IntroCutscenePart1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C74A4.s") +void EnDeath_IntroCutscenePart1(EnDeath* this, PlayState* play) { + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C74F8.s") + player->actor.world.pos.x = Math_SinS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.x; + player->actor.world.pos.z = Math_CosS(this->actor.home.rot.y - 0x370) * 463.0f + this->actor.world.pos.z; + player->actor.shape.rot.y = Actor_WorldYawTowardActor(&player->actor, &this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7800.s") + if (this->actionTimer == 25) { + func_800B724C(play, &this->actor, 0x51); + } + if (this->actionTimer > 0) { + this->actionTimer--; + } else { + EnDeath_SetupIntroCutscenePart2(this, play); + } + EnDeath_UpdateCoreVelocityAndRotation(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7888.s") +void EnDeath_SetupIntroCutscenePart2(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7A30.s") + EnDeath_DimLights(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7AAC.s") + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_7; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7AEC.s") + this->actionTimer = 50; + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 140.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 20.0f; + this->camAtTarget.x = this->actor.world.pos.x; + this->camAtTarget.z = this->actor.world.pos.z; + this->camAtTarget.y = this->actor.home.pos.y + 50.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * 0.0225f; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * 0.0225f; + this->actionFunc = EnDeath_IntroCutscenePart2; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7B88.s") +void EnDeath_IntroCutscenePart2(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7C04.s") + if (this->actionTimer == 42) { + func_800B724C(play, &this->actor, 4); + } else if (this->actionTimer == 27) { + func_800B724C(play, &this->actor, 0x7B); + } + if (this->actionTimer <= 0) { + if (this->actor.world.pos.y < (this->actor.home.pos.y + 400.0f) - 225.0f) { + play->envCtx.lightSettingOverride = 26; + } + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Play_SetCameraAtEye(play, this->camId, &camera->at, &camera->eye); + if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 9.0f) != 0) { + this->actionTimer--; + if (this->actionTimer == -20) { + EnDeath_SetupIntroCutscenePart3(this); + } + } + } else { + this->actionTimer--; + } + EnDeath_UpdateCoreVelocityAndRotation(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7C88.s") +void EnDeath_SetupIntroCutscenePart3(EnDeath* this) { + gSaveContext.eventInf[6] |= 8; + Animation_Change(&this->skelAnime, &object_death_Anim_00B284, 0.0f, 0.0f, + Animation_GetLastFrame(&object_death_Anim_00B284), ANIMMODE_ONCE, 0.0f); + this->actor.scale.y = 0.01f; + this->actor.shape.rot.y += 0x777F; + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_APPEAR); + this->actionFunc = EnDeath_IntroCutscenePart3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7CFC.s") +void EnDeath_IntroCutscenePart3(EnDeath* this, PlayState* play) { + s32 stepDone = Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f); + f32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7D34.s") + this->actor.scale.z = this->actor.scale.x; + temp = 0.01f - this->actor.scale.x; + if (temp > 0.0025f) { + temp = 0.0025f; + } + this->actor.shape.rot.y += (s16)(temp * 4505600.0f); + if (stepDone) { + this->unk_192 = false; + EnDeath_SetupIntroCutscenePart4(this, play); + } + EnDeath_UpdateCoreVelocityAndRotation(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7DB8.s") +void EnDeath_SetupIntroCutscenePart4(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); + f32 invAnimDuration = 1.0f / Animation_GetLastFrame(&object_death_Anim_00B284); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7DCC.s") + this->actionTimer = 10; + this->skelAnime.playSpeed = 1.0f; + this->actor.shape.rot.y = this->actor.home.rot.y; + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 50.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 95.0f; + this->camAtTarget.x = this->actor.world.pos.x; + this->camAtTarget.z = this->actor.world.pos.z; + this->camAtTarget.y = this->actor.world.pos.y + 100.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * invAnimDuration; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * invAnimDuration; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7E24.s") + this->actionFunc = EnDeath_IntroCutscenePart4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C7EDC.s") +void EnDeath_IntroCutscenePart4(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/EnDeath_Update.s") + if (this->unk_191 < 23) { + this->unk_191++; + } + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Play_SetCameraAtEye(play, this->camId, &camera->at, &camera->eye); + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actionTimer > 0) { + this->actionTimer--; + } else { + EnDeath_SetupIntroCutscenePart5(this, play); + } + } + EnDeath_UpdateCoreVelocityAndRotation(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C84A4.s") +void EnDeath_SetupIntroCutscenePart5(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C8690.s") + Animation_PlayOnce(&this->skelAnime, &object_death_Anim_00CB2C); + this->unk_191 = 0x17; + Audio_PlayBgm_StorePrevBgm(NA_BGM_MINI_BOSS); + this->camEyeTarget.x = Math_SinS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.home.rot.y) * 230.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 40.0f; + this->camAtTarget.y = this->actor.world.pos.y + 85.0f; + this->camEyeSpeed = Math_Vec3f_DistXYZ(&camera->eye, &this->camEyeTarget) * 0.14285715f; + this->camAtSpeed = Math_Vec3f_DistXYZ(&camera->at, &this->camAtTarget) * 0.14285715f; + Audio_PlaySfx_AtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_VOICE); + this->actionFunc = EnDeath_IntroCutscenePart5; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C882C.s") +void EnDeath_IntroCutscenePart5(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); + f32 scale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C8D18.s") + if (Animation_OnFrame(&this->skelAnime, 12.0f)) { + play->envCtx.lightSettingOverride = 27; + } else if (Animation_OnFrame(&this->skelAnime, 25.0f)) { + play->envCtx.lightSettingOverride = 26; + } else if (Animation_OnFrame(&this->skelAnime, 38.0f)) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C9160.s") + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_9; + } + } else if (Animation_OnFrame(&this->skelAnime, 14.0f)) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C9220.s") + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_8; + this->miniDeaths[i]->actor.world.pos.x = + (this->miniDeaths[i]->actor.world.pos.x - this->actor.world.pos.x) * 1.8f + this->actor.world.pos.x; + this->miniDeaths[i]->actor.world.pos.z = + (this->miniDeaths[i]->actor.world.pos.z - this->actor.world.pos.z) * 1.8f + this->actor.world.pos.z; + this->miniDeaths[i]->actor.world.pos.y = + (this->miniDeaths[i]->actor.world.pos.y - this->actor.world.pos.y) * 1.7f + this->actor.world.pos.y; + } + this->unk_18E = true; + this->scytheScale = 1.0f; + } + Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + Math_Vec3f_StepTo(&camera->at, &this->camAtTarget, this->camAtSpeed); + Math_StepToF(&camera->fov, 60.0f, 2.4285715f); + Play_SetCameraFov(play, this->camId, camera->fov); + Play_SetCameraAtEye(play, this->camId, &camera->at, &camera->eye); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/func_808C9340.s") + scale = CLAMP(this->skelAnime.curFrame, 10.0f, 14.0f) - 10.0f; + this->scytheScale = scale * 0.25f; + if (scale < 14.0f) { + EnDeath_UpdateCoreVelocityAndRotation(this); + } + if (SkelAnime_Update(&this->skelAnime)) { + CutsceneManager_Stop(this->actor.csId); + func_800B724C(play, &this->actor, 6); + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + this->coreCollider.base.acFlags |= AC_ON; + EnDeath_SetupApproachPlayer(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Death/EnDeath_Draw.s") +void EnDeath_SetupApproachPlayer(EnDeath* this) { + Animation_MorphToLoop(&this->skelAnime, &gGomessFloatAnim, 10.0f); + + this->actor.speed = 1.5f; + if (this->actionFunc == EnDeath_EndSwingAttack || this->actionFunc == EnDeath_SpinAttack) { + this->actionTimer = 140; + } else { + this->actionTimer = 100; + } + this->actionFunc = EnDeath_ApproachPlayer; +} + +void EnDeath_ApproachPlayer(EnDeath* this, PlayState* play) { + if (play->envCtx.lightSettingOverride == 20) { + play->envCtx.lightSettingOverride = 26; + } + EnDeath_Float(this); + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); + + if (this->actionTimer > 0) { + this->actionTimer--; + } + if (this->actor.params < 5 && Rand_ZeroOne() < 0.4f && EnDeath_ProjectileApproaching(this, play)) { + EnDeath_SetupBlockProjectile(this); + } else if (this->actionTimer < 100 && this->actor.xzDistToPlayer < 200.0f) { + EnDeath_SetupSwingAttack(this); + } else if (this->actionTimer == 0) { + if (this->actor.params >= 5) { + func_808C7AEC(this); + } else { + EnDeath_SetupSpinAttack(this); + } + } +} + +void EnDeath_SetupSwingAttack(EnDeath* this) { + Animation_Change(&this->skelAnime, &gGomessScytheSwingAnim, 1.0f, 0.0f, 10.0f, ANIMMODE_ONCE, -3.0f); + this->actionTimer = 0; + this->floatTimer = 0; + this->actor.speed = 8.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_ATTACK); + this->actionFunc = EnDeath_SwingAttack; +} + +void EnDeath_SwingAttack(EnDeath* this, PlayState* play) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0x1000, 0x200); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 3.0f); + this->actor.shape.rot.x = (s16)((100.0f - this->actor.xzDistToPlayer) * 0.01f * 0x400); + this->actor.shape.rot.x = CLAMP_MIN(this->actor.shape.rot.x, 0); + + if (this->actionTimer > 0) { + this->actionTimer++; + if (this->actionTimer == 3) { + EnDeath_SetupEndSwingAttack(this); + } + } else if (SkelAnime_Update(&this->skelAnime) && this->actor.xzDistToPlayer < 100.0f) { + Audio_PlaySfx_AtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE); + this->actionTimer++; + this->actor.speed = 0.0f; + } +} + +void EnDeath_SetupEndSwingAttack(EnDeath* this) { + this->skelAnime.endFrame = Animation_GetLastFrame(&gGomessScytheSwingAnim); + this->actionTimer = 0; + this->unk_2EC = -1; + this->unk_18C = true; + this->actionFunc = EnDeath_EndSwingAttack; + this->actor.speed = 0.0f; +} + +void EnDeath_EndSwingAttack(EnDeath* this, PlayState* play) { + this->actionTimer++; + if (this->skelAnime.curFrame > 20.0f) { + this->unk_18C = false; + this->unk_788.base.atFlags &= ~AT_ON; + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x200); + } + if (SkelAnime_Update(&this->skelAnime)) { + this->actor.shape.rot.x = 0; + EnDeath_SetupApproachPlayer(this); + } +} + +void EnDeath_SetupBlockProjectile(EnDeath* this) { + Animation_MorphToLoop(&this->skelAnime, &gGomessScytheSpinAnim, -3.0f); + this->unk_2EC = 31; + this->actionTimer = 30; + this->actor.speed = 0.0f; + EnDeath_UpdateSpinAttackTris(this); + this->unk_18C = true; + this->numScytheAfterImages = -3; + this->actionFunc = EnDeath_BlockProjectile; +} + +void EnDeath_BlockProjectile(EnDeath* this, PlayState* play) { + EnDeath_Float(this); + + this->actionTimer--; + if (this->numScytheAfterImages < 7) { + this->numScytheAfterImages++; + } + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Audio_PlaySfx_AtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_ROLL); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); + EnDeath_UpdateSpinAttackTris(this); + if (this->actionTimer == 0) { + if (this->actor.xzDistToPlayer > 200.0f) { + EnDeath_SetupSpinAttack(this); + } else { + EnDeath_SetupApproachPlayer(this); + } + } +} + +void EnDeath_SetupSpinAttack(EnDeath* this) { + if (this->actionFunc != EnDeath_BlockProjectile) { + Animation_MorphToLoop(&this->skelAnime, &gGomessScytheSpinAnim, -3.0f); + this->numScytheAfterImages = -3; + this->actionTimer = 0; + this->unk_2EC = -1; + this->unk_18C = true; + this->actor.speed = 0.0f; + } else { + // Starting straight out of blocking a projectile, already spinning so start moving immediately + this->actionTimer = 10; + this->unk_2EC = 9; + this->actor.speed = 10.0f; + } + EnDeath_UpdateSpinAttackTris(this); + this->actionFunc = EnDeath_SpinAttack; +} + +void EnDeath_SpinAttack(EnDeath* this, PlayState* play) { + EnDeath_Float(this); + + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Audio_PlaySfx_AtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_ROLL); + } + + if (this->numScytheAfterImages < 7) { + this->numScytheAfterImages++; + } + + this->actionTimer++; + if (this->actionTimer < 10) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); + } else if (this->actionTimer == 10) { + this->actor.speed = 10.0f; + } + + EnDeath_UpdateSpinAttackTris(this); + + Math_ScaledStepToS(&this->unk_2F2, (s32)(Math_SinS(this->actionTimer * 0x2000) * 0x800) + 0x3000, 0x1000); + Math_ScaledStepToS(&this->unk_2F4, (s32)(Math_SinS(this->actionTimer * 0x2000 - 0x8000) * 0x800), 0x1000); + + if ((this->actor.bgCheckFlags & 8) || (this->unk_788.base.atFlags & AT_HIT) || + (this->unk_860.base.atFlags & AT_HIT)) { + this->unk_18C = false; + this->unk_788.base.atFlags &= ~(AT_ON | AT_HIT); + this->unk_860.base.atFlags &= ~AT_HIT; + EnDeath_SetupApproachPlayer(this); + } +} + +void EnDeath_SetupDamaged(EnDeath* this) { + Animation_PlayOnce(&this->skelAnime, &gGomessDamagedAnim); + this->actor.speed = 10.0f; + func_800BE568(&this->actor, &this->coreCollider); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 15); + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_DAMAGE); + this->actionFunc = EnDeath_Damaged; +} + +void EnDeath_Damaged(EnDeath* this, PlayState* play) { + EnDeath_Float(this); + Math_StepToF(&this->actor.speed, 0.0f, 0.5f); + if (SkelAnime_Update(&this->skelAnime)) { + this->coreCollider.base.acFlags |= AC_ON; + EnDeath_SetupSpinAttack(this); + } +} + +void EnDeath_SetupDeathCutscenePart1(EnDeath* this, PlayState* play) { + Vec3f eye; + Vec3f at; + s32 i; + + this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_IGNORE_QUAKE); + Animation_PlayOnce(&this->skelAnime, &gGomessBeginDeathAnim); + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_6; + } + + this->unk_18D = false; + this->coreCollider.base.acFlags &= ~AC_ON; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 30); + this->actionTimer = 35; + this->actor.world.pos.y = this->actor.home.pos.y; + this->actor.speed = 0.0f; + this->camEyeTarget.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.x; + this->camEyeTarget.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 79.0f + this->actor.world.pos.z; + this->camEyeTarget.y = this->actor.home.pos.y + 63.0f; + at.x = this->actor.world.pos.x; + at.y = this->actor.world.pos.y + 100.0f; + at.z = this->actor.world.pos.z; + eye.x = Math_SinS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.x; + eye.z = Math_CosS(this->actor.shape.rot.y + 0x900) * 179.0f + this->actor.world.pos.z; + eye.y = this->actor.home.pos.y + 30.0f; + Play_SetCameraAtEye(play, this->camId, &at, &eye); + this->camEyeSpeed = Math_Vec3f_DistXYZ(&eye, &this->camEyeTarget) * 0.05f; + this->actor.shape.rot.y += 0x2000; + func_800B724C(play, &this->actor, 7); + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_DEAD); + this->actionFunc = EnDeath_DeathCutscenePart1; +} + +void EnDeath_DeathCutscenePart1(EnDeath* this, PlayState* play) { + Camera* camera = Play_GetCamera(play, this->camId); + f32 distToTarget = Math_Vec3f_StepTo(&camera->eye, &this->camEyeTarget, this->camEyeSpeed); + + Play_SetCameraAtEye(play, this->camId, &camera->at, &camera->eye); + + if (SkelAnime_Update(&this->skelAnime)) { + this->actor.shape.rot.y += 0x2000; + Animation_PlayLoop(&this->skelAnime, &gGomessDeathAnim); + } else if (this->skelAnime.animation == &gGomessBeginDeathAnim) { + this->actor.shape.rot.y += 0x2000; + if (this->skelAnime.curFrame > 3.0f) { + Matrix_Put(&this->unk_6A4); + Matrix_RotateXS(-0x1000, MTXMODE_APPLY); + Matrix_Get(&this->unk_6A4); + this->unk_18E = false; + this->unk_6A4.yw += 18.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_SCYTHE); + } + } + + if (distToTarget < 0.1f) { + if (this->actionTimer == 35) { + Audio_PlaySfx_AtPosWithVolumeTransition(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_LEV, 0x41); + } + if (this->actionTimer > 0) { + this->actionTimer--; + } + if (this->actionTimer == 0) { + EnDeath_SetupDeathCutscenePart2(this, play); + } + } +} + +void EnDeath_SetupDeathCutscenePart2(EnDeath* this, PlayState* play) { + EnvLightSettings* lightSettings1; + EnvLightSettings* lightSettings2; + Player* player = GET_PLAYER(play); + Vec3f eye; + Vec3f at; + f32 sinRotY; + f32 cosRotY; + s32 i; + + Animation_PlayLoop(&this->skelAnime, &gGomessDeathAnim); + this->actionTimer = 30; + player->actor.shape.rot.y = Actor_WorldYawTowardPoint(&player->actor, &this->actor.home.pos) + 0x1000; + this->actor.shape.rot.y = player->actor.shape.rot.y + 0x6000; + sinRotY = Math_SinS(player->actor.shape.rot.y); + cosRotY = Math_CosS(player->actor.shape.rot.y); + this->actor.world.pos.x = player->actor.world.pos.x + (260.0f * sinRotY); + this->actor.world.pos.z = player->actor.world.pos.z + (260.0f * cosRotY); + this->actor.world.pos.y = this->actor.home.pos.y + 15.0f; + eye.x = (Math_SinS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.x; + eye.z = (Math_CosS((s16)(player->actor.shape.rot.y - 0x2500)) * 182.0f) + this->actor.world.pos.z; + eye.y = this->actor.world.pos.y - 13.0f; + at.x = player->actor.world.pos.x + (120.0f * sinRotY); + at.y = player->actor.world.pos.y + 90.0f; + at.z = player->actor.world.pos.z + (120.0f * cosRotY); + Play_SetCameraAtEye(play, this->camId, &at, &eye); + + lightSettings1 = &play->envCtx.lightSettingsList[20]; + lightSettings2 = &play->envCtx.lightSettingsList[21]; + + for (i = 0; i < 3; i++) { + lightSettings1->light1Dir[i] = lightSettings2->light1Dir[i]; + lightSettings1->light2Dir[i] = lightSettings2->light2Dir[i]; + } + + this->actionFunc = EnDeath_DeathCutscenePart2; +} + +void EnDeath_DeathCutscenePart2(EnDeath* this, PlayState* play) { + f32 sin; + f32 cos; + s16 camYaw; + + SkelAnime_Update(&this->skelAnime); + + this->actionTimer--; + if (this->actionTimer >= 0 && this->actionTimer < 3) { + camYaw = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000; + sin = Math_SinS(camYaw); + cos = Math_CosS(camYaw); + Matrix_Translate(this->actor.world.pos.x + (83.0f * sin) + (-38.0f * cos), + this->actor.world.pos.y + 53.0f + 15.0f * this->actionTimer, + this->actor.world.pos.z + (83.0f * cos) - (-38.0f * sin), MTXMODE_NEW); + Matrix_RotateYS(camYaw - 0x3300, MTXMODE_APPLY); + Matrix_RotateXS(0x1100 - this->actionTimer * 0x1800, MTXMODE_APPLY); + Matrix_RotateZS(-0xA00, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + Matrix_Get(&this->unk_6A4); + if (this->actionTimer == 0) { + Camera_AddQuake(GET_ACTIVE_CAM(play), 2, 4, 6); + Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100); + AudioSfx_StopByPosAndId(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_LEV); + Audio_PlaySfx_AtPos(&this->scytheScreenPos, NA_SE_EN_DEATH_SCYTHE_ONGND); + } + } + if (this->actionTimer < -25) { + play->envCtx.lightSettingOverride = 20; + EnDeath_SetupDeathCutscenePart3(this); + } +} + +void EnDeath_SetupDeathCutscenePart3(EnDeath* this) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_DIE; + } + + this->actionTimer = 0; + this->actionFunc = EnDeath_DeathCutscenePart3; +} + +void EnDeath_DeathCutscenePart3(EnDeath* this, PlayState* play) { + static Vec3f sparkleVel = { 0.0f, -1.5f, 0.0f }; + static Vec3f sparkleAccel = { 0.0f, -0.2f, 0.0f }; + static Color_RGBA8 sparklePrimColor = { 0, 0, 0, 0 }; + static Color_RGBA8 sparkleEnvColor = { 40, 40, 40, 0 }; + static s16 D_808C9A90[GOMESS_LIMB_MAX] = { 30, 30, 10, 2, 12, 17, 17, 17, 17, 17, 17, + 17, 14, 10, 12, 9, 9, 12, 9, 9, 30, 30 }; + s32 phi_v0; + s32 phi_s0; + u8* temp1A9; + Vec3f* sparklePos; + s32 pad; + s32 pad1; + f32 sin; + f32 cos; + f32 temp_fs0; + s32 temp_v1; + + sparklePos = this->unk_404; + temp1A9 = this->unk_1A9; + for (phi_v0 = 0; (phi_v0 ^ 0) < ARRAY_COUNT(this->unk_404); phi_v0++) { + sparklePos->y += 1.7f; + temp_v1 = *temp1A9 - 30; + *temp1A9 = CLAMP_MIN(temp_v1, 0); + sparklePos++; + temp1A9++; + } + + temp_v1 = (-this->actionTimer * 14) + 252; + this->actor.shape.shadowAlpha = CLAMP_MIN(temp_v1, 0); + + if (this->actionTimer < 18) { + sparklePos = &this->unk_404[(this->actionTimer * 7) % ARRAY_COUNT(this->unk_404)]; + temp1A9 = &this->unk_1A9[(this->actionTimer * 7) % ARRAY_COUNT(this->unk_1A9)]; + + sin = Math_SinS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000); + cos = Math_CosS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000); + + for (phi_s0 = 0; phi_s0 < 7; phi_s0++) { + temp_fs0 = Rand_CenteredFloat(100.0f) - 20.0f; + sparklePos->x = this->actor.world.pos.x + (30.0f * sin) + (temp_fs0 * cos); + sparklePos->y = (Rand_ZeroFloat(20.0f) + this->actor.world.pos.y + 4.0f * this->actionTimer) - 30.0f; + sparklePos->z = (this->actor.world.pos.z + 30.0f * cos) - (temp_fs0 * sin); + *temp1A9 = 255 - phi_s0 * 4; + EffectSsKirakira_SpawnSmall(play, sparklePos, &sparkleVel, &sparkleAccel, &sparklePrimColor, + &sparkleEnvColor); + sparklePos++; + temp1A9++; + } + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + + this->actionTimer++; + + for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(this->unk_193); phi_v0++) { + if (this->actionTimer == D_808C9A90[phi_v0]) { + this->unk_193[phi_v0] = 1; + } + } + + if (this->actionTimer == 26) { + EnDeath_SetupDeathCutscenePart4(this); + } +} + +void EnDeath_SetupDeathCutscenePart4(EnDeath* this) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_1A9); i++) { + this->unk_1A9[i] = 0; + } + + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.focus.pos); + this->actor.bgCheckFlags &= ~1; + this->actionTimer = 0; + this->actionFunc = EnDeath_DeathCutscenePart4; + this->actor.gravity = -1.0f; + this->actor.shape.yOffset = 0.0f; +} + +void EnDeath_DeathCutscenePart4(EnDeath* this, PlayState* play) { + static Vec3f sparkleAccel = { 0.0f, -1.0f, 0.0f }; + static Color_RGBA8 sparklePrimColor = { 0, 200, 100, 0 }; + static Color_RGBA8 sparkleEnvColor = { 0, 100, 0, 0 }; + Vec3f sparkleVel; + s32 i; + + if (this->actionTimer == 0) { + if ((this->actor.bgCheckFlags & 1) || this->actor.floorHeight == -32000.0f) { + Actor_SetScale(&this->actor, 0.0f); + this->actionTimer++; + + for (i = 0; i < 40; i++) { + sparkleAccel.y = -0.2f; + sparkleVel.x = Rand_CenteredFloat(4.0f); + sparkleVel.z = Rand_CenteredFloat(4.0f); + sparkleVel.y = Rand_ZeroFloat(2.0f) + 3.0f; + EffectSsKirakira_SpawnSmall(play, &this->actor.world.pos, &sparkleVel, &sparkleAccel, + &sparklePrimColor, &sparkleEnvColor); + } + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_HEARTBREAK); + } + } else { + this->actionTimer++; + if (this->actionTimer == 20) { + EnDeath_SetupDead(this, play); + } + } +} + +void EnDeath_SetupDead(EnDeath* this, PlayState* play) { + CutsceneManager_Stop(this->actor.csId); + func_800B724C(play, &this->actor, 6); + Flags_SetClearTemp(play, play->roomCtx.curRoom.num); + this->actionTimer = 255; + play->envCtx.lightSettingOverride = 255; + this->actionFunc = EnDeath_Dead; +} + +void EnDeath_Dead(EnDeath* this, PlayState* play) { + if (this->actionTimer > 0) { + this->actionTimer -= 5; + if (this->actionTimer <= 0) { + this->actionTimer = 0; + Actor_Kill(&this->actor); + } + } +} + +void func_808C7AEC(EnDeath* this) { + s32 i; + + Actor_PlaySfx(&this->actor, NA_SE_EN_DEATH_VOICE); + Animation_MorphToPlayOnce(&this->skelAnime, &object_death_Anim_0015B4, 5.0f); + this->actor.speed = 0.0f; + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_3; + } + + this->floatTimer = 0; + this->actionFunc = func_808C7B88; +} + +void func_808C7B88(EnDeath* this, PlayState* play) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 5.0f); + + if (SkelAnime_Update(&this->skelAnime)) { + play->envCtx.lightSettingOverride = 27; + func_808C7C04(this); + } +} + +void func_808C7C04(EnDeath* this) { + s32 i; + + Animation_PlayLoop(&this->skelAnime, &object_death_Anim_001834); + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_4; + } + + this->actionFunc = func_808C7C88; + this->actor.speed = 0.0f; +} + +void func_808C7C88(EnDeath* this, PlayState* play) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x1000, 0x100); + SkelAnime_Update(&this->skelAnime); + + if (this->actor.params >= 5) { + play->envCtx.lightSettingOverride = 26; + EnDeath_SetupApproachPlayer(this); + } +} + +void EnDeath_SetupPlayCutscene(EnDeath* this) { + CutsceneManager_Queue(this->actor.csId); + this->actionFunc = EnDeath_PlayCutscene; +} + +void EnDeath_PlayCutscene(EnDeath* this, PlayState* play) { + // Wait for it's turn to play + if (CutsceneManager_IsNext(this->actor.csId)) { + // Start playing + CutsceneManager_Start(this->actor.csId, &this->actor); + this->camId = CutsceneManager_GetCurrentSubCamId(this->actor.csId); + if (this->actor.colChkInfo.health == 0) { + // Death cutscene + EnDeath_SetupDeathCutscenePart1(this, play); + } else { + // Intro cutscene + EnDeath_SetupIntroCutscenePart1(this, play); + } + } else { + CutsceneManager_Queue(this->actor.csId); + } +} + +void EnDeath_SetupBeginWithoutCutscene(EnDeath* this) { + this->actionFunc = EnDeath_BeginWithoutCutscene; +} + +void EnDeath_BeginWithoutCutscene(EnDeath* this, PlayState* play) { + if (!Play_InCsMode(play)) { + EnDeath_DimLights(play); + this->coreCollider.base.acFlags |= AC_ON; + Audio_PlayBgm_StorePrevBgm(NA_BGM_MINI_BOSS); + EnDeath_SetupApproachPlayer(this); + } +} + +void EnDeath_UpdateCore(EnDeath* this, PlayState* play) { + if (this->unk_18D) { + // Core falling to the ground + this->corePos.y += this->coreVelocity; + this->coreVelocity -= 1.0f; + this->coreRotation += 0x1800; + if (this->corePos.y < this->actor.floorHeight) { + // Hit the floor + this->corePos.y = this->actor.floorHeight; + func_800B3030(play, &this->corePos, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(play, &this->corePos, 11, NA_SE_EN_EXTINCT); + this->unk_18D = false; + } + } +} + +void EnDeath_UpdateDamage(EnDeath* this, PlayState* play) { + s32 i; + + if (this->unk_2F8 > 0) { + this->unk_2F8--; + } + if (this->coreCollider.base.acFlags & AC_HIT) { + this->coreCollider.base.acFlags &= ~AC_HIT; + + if (this->actor.params >= 5) { + this->unk_18D = true; + this->coreVelocity = -1.0f; + this->coreRotation = this->actor.shape.rot.y; + Math_Vec3s_ToVec3f(&this->corePos, &this->coreCollider.dim.worldSphere.center); + SoundSource_PlaySfxAtFixedWorldPos(play, &this->corePos, 30, NA_SE_EN_FFLY_DEAD); + + if (this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW && this->actionFunc != func_808C7B88) { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_1; + } + play->envCtx.lightSettingOverride = 28; + + this->unk_2FC = 20; + if (this->actionFunc == EnDeath_ApproachPlayer) { + this->actionTimer = 100; + } + } else if (this->actor.colChkInfo.damageEffect == DMGEFF_EXPLOSIVES) { + this->unk_2F8 = 0xA; + } + } else if (this->actor.colChkInfo.damageEffect != DMGEFF_EXPLOSIVES || this->unk_2F8 == 0) { + this->unk_18C = false; + this->unk_788.base.atFlags &= ~AT_ON; + this->coreCollider.base.acFlags &= ~AC_ON; + + if (this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW) { + this->dmgEffectAlpha = 3.0f; + this->dmgEffectScale = 0.8f; + this->dmgEffect = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, + this->coreCollider.info.bumper.hitPos.x, this->coreCollider.info.bumper.hitPos.y, + this->coreCollider.info.bumper.hitPos.z, 0, 0, 0, 4); + } + if (play->envCtx.lightSettingOverride == 27) { + play->envCtx.lightSettingOverride = 26; + } + this->actor.shape.rot.x = 0; + + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(play, &this->actor); + Audio_RestorePrevBgm(); // Stop miniboss BGM + EnDeath_SetupPlayCutscene(this); + } else { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + this->miniDeaths[i]->actor.params = MINIDEATH_ACTION_2; + } + EnDeath_SetupDamaged(this); + } + } + } +} + +void EnDeath_Update(Actor* thisx, PlayState* play) { + EnDeath* this = THIS; + ArrowLight* lightArrow; + s32 pad; + + if (this->unk_2FC > 0) { + this->unk_2FC--; + + lightArrow = (ArrowLight*)SubS_FindActor(play, NULL, ACTORCAT_ITEMACTION, ACTOR_ARROW_LIGHT); + if (lightArrow != NULL) { + lightArrow->screenFillIntensity = -100.0f; + } + + if (this->unk_2FC == 0) { + play->envCtx.lightSettingOverride = 26; + } + } + + EnDeath_UpdateDamage(this, play); + EnDeath_UpdateCore(this, play); + if (this->actionFunc != EnDeath_SpinAttack) { + Math_ScaledStepToS(&this->unk_2F2, 0, 0x800); + Math_ScaledStepToS(&this->unk_2F4, 0, 0x800); + } + + this->actionFunc(this, play); + + if (this->actionFunc != EnDeath_Damaged) { + this->actor.world.rot.y = this->actor.shape.rot.y; + } + Actor_MoveWithGravity(&this->actor); + + Actor_UpdateBgCheckInfo(play, &this->actor, 40.0f, (this->actionFunc == EnDeath_SpinAttack) ? 50.0f : 100.0f, + 40.0f, 4 | 2 | 1); + + this->bodyCollider.dim.pos.x = this->actor.world.pos.x + Math_SinS(this->actor.shape.rot.y) * 3.0f; + this->bodyCollider.dim.pos.z = this->actor.world.pos.z + Math_CosS(this->actor.shape.rot.y) * 3.0f; + this->bodyCollider.dim.pos.y = this->actor.world.pos.y; + + if (this->actor.params < 5) { + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius + 5; + } else { + this->coreCollider.dim.worldSphere.radius = this->coreCollider.dim.modelSphere.radius; + } + + if (this->actionFunc != EnDeath_Dead) { + CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base); + } + if (this->coreCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->coreCollider.base); + } + if (this->unk_788.base.atFlags & AT_ON) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_788.base); + } + if (this->actionFunc == EnDeath_BlockProjectile || this->actionFunc == EnDeath_SpinAttack) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_860.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_860.base); + } + + if (this->dmgEffectAlpha > 0.0f) { + if (this->dmgEffect != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->dmgEffectAlpha, 0.0f, 0.05f); + this->dmgEffectScale = (this->dmgEffectAlpha + 1.0f) * 0.4f; + + this->dmgEffectScale = CLAMP_MAX(this->dmgEffectScale, 0.8f); + } else if (Math_StepToF(&this->dmgEffectSteamScale, 0.8f, 0.02f) == 0) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +void EnDeath_DrawScytheSpinning(EnDeath* this, PlayState* play) { + s32 i; + Gfx* dl; + s32 pad; + + func_800B8118(&this->actor, play, 0); + Scene_SetRenderModeXlu(play, 1, 2); + + OPEN_DISPS(play->state.gfxCtx); + dl = POLY_XLU_DISP; + + for (i = 1; i < this->numScytheAfterImages; i++) { + gDPPipeSync(dl++); + gDPSetEnvColor(dl++, 30, 30, 0, 255 - i * 35); + + Matrix_Put(&this->unk_6A4); + Matrix_RotateXS(i * 0x2100, MTXMODE_APPLY); + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_death_DL_006F88); // scythe handle + + Matrix_Translate(0.0f, -1084.0f, 7012.0f, MTXMODE_APPLY); + Matrix_RotateZYX(-0x4000, 0, -0x4000, MTXMODE_APPLY); + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_death_DL_0073D0); // scythe blade + } + + POLY_XLU_DISP = dl; + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDeath_DrawScythe(EnDeath* this, PlayState* play) { + Gfx* dl; + s32 pad; + + if (this->actionFunc == EnDeath_Dead) { + func_800B8118(&this->actor, play, 0); + Scene_SetRenderModeXlu(play, 1, 2); + } + + OPEN_DISPS(play->state.gfxCtx); + + if (this->actionFunc == EnDeath_Dead) { + dl = POLY_XLU_DISP; + + gDPPipeSync(dl++); + gDPSetEnvColor(dl++, 30, 30, 0, this->actionTimer); + } else { + dl = POLY_OPA_DISP; + } + + Matrix_Put(&this->unk_6A4); + Matrix_Scale(this->scytheScale, this->scytheScale, this->scytheScale, MTXMODE_APPLY); + + gSPMatrix(&dl[0], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[1], object_death_DL_006F88); // scythe handle + + Matrix_Translate(0.0f, -1084.0f, 7012.0f, MTXMODE_APPLY); + Matrix_RotateZYX(-0x4000, 0, -0x4000, MTXMODE_APPLY); + + gSPMatrix(&dl[2], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[3], object_death_DL_0073D0); // scythe blade + + Matrix_MultZero(&this->scytheWorldPos); + + if (this->actionFunc == EnDeath_Dead) { + POLY_XLU_DISP = &dl[4]; + } else { + POLY_OPA_DISP = &dl[4]; + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDeath_DrawBats(EnDeath* this, PlayState* play) { + // Each bat is animated by cycling through these display lists + static Gfx* sMinideathDLs[MINIDEATH_ANIM_LENGTH] = { + gGomessBatFrame1DL, gGomessBatFrame2DL, gGomessBatFrame3DL, gGomessBatFrame4DL, gGomessBatFrame5DL, + gGomessBatFrame6DL, gGomessBatFrame7DL, gGomessBatFrame8DL, gGomessBatFrame9DL, + }; + EnMinideath* miniDeath; + MtxF* cmf; + f32 phi_fs2; + MiniDeathStruct* phi_s0; + s32 j; + f32 scale; + Gfx* dl; + s32 i; + Vec3f sp9C; + + OPEN_DISPS(play->state.gfxCtx); + dl = POLY_OPA_DISP; + + gSPDisplayList(dl++, &gSetupDLs[0x19]); // incementing by 0x30 it seems. this is odd. The increment size may be wrong? TODO + gSPDisplayList(dl++, gGomessBatMaterialDL); + + cmf = Matrix_GetCurrent(); + + if (this->actionFunc == EnDeath_Dead) { + phi_fs2 = this->actionTimer * 0.000035f; + scale = 0.007f; + if (phi_fs2 > 0.007f) { + phi_fs2 = 0.007f; + scale = 0.007f; + } + } else { + phi_fs2 = 0.007f; + scale = 0.007f; + } + + if (this->actor.flags & ACTOR_FLAG_IGNORE_QUAKE) { + Math_Vec3f_Copy(&sp9C, &play->mainCamera.quakeOffset); + } else { + Math_Vec3f_Copy(&sp9C, &gZeroVec3f); + } + + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + if (this->actionFunc == EnDeath_BeginWithoutCutscene || + (this->miniDeaths[i]->actor.flags & ACTOR_FLAG_40) == ACTOR_FLAG_40) { + miniDeath = this->miniDeaths[i]; + + Matrix_RotateZYX(miniDeath->actor.shape.rot.x, miniDeath->actor.shape.rot.y, 0, MTXMODE_NEW); + Matrix_Scale(phi_fs2, phi_fs2, phi_fs2, MTXMODE_APPLY); + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + if (phi_s0->unk_1 == 0) { + cmf->mf[3][0] = phi_s0->unk_4.x + sp9C.x; + cmf->mf[3][1] = phi_s0->unk_4.y + sp9C.y; + cmf->mf[3][2] = phi_s0->unk_4.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + if (phi_s0->unk_1 == 1) { + Matrix_RotateZYX(0x4000, phi_s0->unk_1E, 0, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + cmf->mf[3][0] = phi_s0->unk_4.x + sp9C.x; + cmf->mf[3][1] = phi_s0->unk_4.y + sp9C.y; + cmf->mf[3][2] = phi_s0->unk_4.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + } + } + + if (this->unk_192) { + for (i = 0; i < ARRAY_COUNT(this->miniDeaths); i++) { + miniDeath = this->miniDeaths[i]; + + Matrix_RotateZYX(miniDeath->actor.shape.rot.x, miniDeath->actor.shape.rot.y, 0, MTXMODE_NEW); + Matrix_Scale(phi_fs2, phi_fs2, phi_fs2, MTXMODE_APPLY); + + for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { + cmf->mf[3][0] = miniDeath->actor.world.pos.x - phi_s0->unk_10.x; + cmf->mf[3][1] = miniDeath->actor.world.pos.y + (20.0f - phi_s0->unk_10.y); + cmf->mf[3][2] = miniDeath->actor.world.pos.z - phi_s0->unk_10.z; + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[phi_s0->animFrame]); + } + } + } + + if (this->unk_18D) { + Matrix_RotateZYX(0x4000, this->coreRotation, 0, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + cmf->mf[3][0] = this->corePos.x + sp9C.x; + cmf->mf[3][1] = this->corePos.y + sp9C.y; + cmf->mf[3][2] = this->corePos.z + sp9C.z; + + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, sMinideathDLs[0]); + } + + POLY_OPA_DISP = dl; + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDeath_DrawFlames(EnDeath* this, PlayState* play2) { + PlayState* play = play2; + s32 phi_t1; + MtxF* cmf; + s32 phi_s7; + u8* phi_s3; + Vec3f* phi_s1; + MiniDeathStruct* phi_s1_2; + u8 alpha; + s32 phi_s3_2; + + phi_s7 = this->actionTimer * 7; + if (phi_s7 > ARRAY_COUNT(this->unk_1A9)) { + phi_s7 = ARRAY_COUNT(this->unk_1A9); + } + + OPEN_DISPS(play->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 230, 135, 25, 0); + + Matrix_Put(&play->billboardMtxF); + Matrix_Scale(0.00405f, 0.003f, 0.00405f, MTXMODE_APPLY); + + cmf = Matrix_GetCurrent(); + + phi_s1 = this->unk_404; + phi_s3 = this->unk_1A9; + for (phi_t1 = 0; phi_t1 < phi_s7; phi_t1++) { + if (*phi_s3 > 0) { + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 165, 255, 215, *phi_s3); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((play->gameplayFrames + (phi_t1 * 10)) * -20) & 0x1FF, 32, 128)); + + cmf->mf[3][0] = phi_s1->x; + cmf->mf[3][1] = phi_s1->y; + cmf->mf[3][2] = phi_s1->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL); + } + phi_s1++; + phi_s3++; + } + + Matrix_Put(&play->billboardMtxF); + Matrix_Scale(0.00405f, 0.003f, 0.00405f, MTXMODE_APPLY); + + if (this->actionFunc == EnDeath_Dead) { + alpha = this->actionTimer; + } else { + alpha = 255; + } + + for (phi_t1 = 0; phi_t1 < ARRAY_COUNT(this->miniDeaths); phi_t1++) { + if ((this->miniDeaths[phi_t1]->actor.flags & ACTOR_FLAG_40) == ACTOR_FLAG_40) { + phi_s1_2 = this->miniDeaths[phi_t1]->unk_160; + + for (phi_s3_2 = 0; phi_s3_2 < ARRAY_COUNT(this->miniDeaths[phi_t1]->unk_160); phi_s3_2++, phi_s1_2++) { + cmf->mf[3][0] = phi_s1_2->unk_4.x; + cmf->mf[3][1] = phi_s1_2->unk_4.y - 12.0f; + cmf->mf[3][2] = phi_s1_2->unk_4.z; + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 165, 255, 215, alpha); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((play->gameplayFrames + ((phi_s3_2 + phi_t1) * 10)) * -20) & 511, 32, + 128)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL); + } + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void EnDeath_DrawCore(EnDeath* this, PlayState* play) { + s32 pad; + Gfx* dl; + + OPEN_DISPS(play->state.gfxCtx); + dl = POLY_OPA_DISP; + + Matrix_ReplaceRotation(&play->billboardMtxF); + + gSPMatrix(&dl[0], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[1], gGomessCoreDL); + + if (this->actor.params >= 5) { + // bats in front of the core + gSPDisplayList(&dl[2], gGomessBatsGuardingCoreDL); + POLY_OPA_DISP = &dl[3]; + } else { + POLY_OPA_DISP = &dl[2]; + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +s32 EnDeath_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnDeath* this = THIS; + f32 temp_f12; + s32 temp_v0; + + if (this->unk_193[limbIndex] == 1) { + *dList = NULL; + } else if (limbIndex == GOMESS_LIMB_CLOAK_LOWER && this->actionFunc == EnDeath_DeathCutscenePart3) { + temp_v0 = this->actionTimer - 5; + if (temp_v0 > 0) { + temp_f12 = 1.0f - (temp_v0 * 0.1f); + Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY); + } + } + if (limbIndex == GOMESS_LIMB_SCYTHE_HANDLE || limbIndex == GOMESS_LIMB_SCYTHE_BLADE) { + if (!this->unk_18E) { + *dList = NULL; + } + } else if (limbIndex == GOMESS_LIMB_CLOAK_UPPER) { + rot->z = rot->z + this->unk_2F2; + } else if (limbIndex == GOMESS_LIMB_CLOAK_LOWER) { + rot->z = rot->z + this->unk_2F4; + } + return 0; +} + +void EnDeath_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_808C9AF4 = { -1000.0f, 12000.0f, 0.0f }; + static Vec3f D_808C9B00 = { -2000.0f, -2500.0f, 0.0f }; + static Vec3f D_808C9B0C[5] = { + { 1000.0f, 2000.0f, 0.0f }, { 1500.0f, 1000.0f, 4000.0f }, { 1500.0f, 1000.0f, -4000.0f }, + { 4000.0f, 4000.0f, 2000.0f }, { 4000.0f, 4000.0f, -2000.0f }, + }; + static s8 D_808C9B48[GOMESS_LIMB_MAX] = { -1, -1, -1, 12, -1, 0, -1, -1, -1, -1, -1, + -1, -1, 7, 1, 2, 3, 4, 5, 6, -1, -1 }; + EnDeath* this = THIS; + s8 index; + + if (limbIndex == GOMESS_LIMB_SCYTHE_BLADE) { + Matrix_MultZero(&this->scytheWorldPos); + + if ((this->unk_788.base.atFlags & AT_ON) && this->unk_2EC != this->actionTimer) { + Vec3f quad0; + Vec3f quad1; + Vec3f pos1; + Vec3f pos2; + + Math_Vec3f_Copy(&quad0, &this->unk_788.dim.quad[0]); + Math_Vec3f_Copy(&quad1, &this->unk_788.dim.quad[1]); + + if (this->actionFunc == EnDeath_EndSwingAttack) { + Matrix_MultVecX(6000.0f, &pos1); + Matrix_MultVec3f(&D_808C9AF4, &pos2); + } else { + Matrix_MultVecY(5000.0f, &pos2); + Matrix_MultVec3f(&D_808C9B00, &pos1); + } + + Collider_SetQuadVertices(&this->unk_788, &pos2, &pos1, &quad0, &quad1); + EffectBlure_AddVertex(Effect_GetByIndex(this->effectIndex), &pos1, &pos2); + + this->unk_2EC = this->actionTimer; + } else if (this->unk_18C) { + if (this->actionFunc == EnDeath_EndSwingAttack) { + Matrix_MultVecX(6000.0f, &this->unk_788.dim.quad[1]); + Matrix_MultVec3f(&D_808C9AF4, &this->unk_788.dim.quad[0]); + } else { + Matrix_MultVecY(5000.0f, &this->unk_788.dim.quad[0]); + Matrix_MultVec3f(&D_808C9B00, &this->unk_788.dim.quad[1]); + } + this->unk_18C = false; + this->unk_788.base.atFlags |= AT_ON; + this->unk_2EC = this->actionTimer; + } + } else if (limbIndex == GOMESS_LIMB_CORE_POS && this->actionFunc != EnDeath_Dead) { + Matrix_Push(); + EnDeath_DrawCore(this, play); + Matrix_Pop(); + Matrix_MultZero(&this->actor.focus.pos); + + this->coreCollider.dim.worldSphere.center.x = this->actor.focus.pos.x; + this->coreCollider.dim.worldSphere.center.y = this->actor.focus.pos.y; + this->coreCollider.dim.worldSphere.center.z = this->actor.focus.pos.z; + + if (this->actor.params < 5) { + this->coreCollider.dim.worldSphere.center.y = this->actor.focus.pos.y + 5.0f; + } + } else if (limbIndex == GOMESS_LIMB_SCYTHE_HANDLE) { + if (!(this->actionFunc != EnDeath_SpinAttack && this->actionFunc != EnDeath_BlockProjectile && + this->actionFunc != EnDeath_IntroCutscenePart5) || + (this->actionFunc == EnDeath_DeathCutscenePart1 && this->unk_18E == true)) { + Matrix_Get(&this->unk_6A4); + } + } + + index = D_808C9B48[limbIndex]; + if (index != -1) { + if (index < 7) { + // get matrix translation as-is, occupies slots 0, 1, 2, 3, 4, 5, 6 + Matrix_MultZero(&this->dmgEffectPositions[index]); + } else if (index == 7) { + // 5 points using 5 offsets, occupies slots 7, 8, 9, 10, 11 + s32 i; + Vec3f* offset; + Vec3f* effPos; + + for (effPos = &this->dmgEffectPositions[index], offset = &D_808C9B0C[0], i = 0; + i != ARRAY_COUNT(D_808C9B0C); i++, offset++, effPos++) { + Matrix_MultVec3f(offset, effPos); + } + } else if (index == 12) { + // get matrix translation as-is and a point offset by -2000 from it, occupies slots 12, 13 + Matrix_MultZero(&this->dmgEffectPositions[index]); + Matrix_MultVecY(-2000.0f, &this->dmgEffectPositions[index + 1]); + } + } +} + +void EnDeath_Draw(Actor* thisx, PlayState* play) { + EnDeath* this = THIS; + s32 pad; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + func_800B8050(&this->actor, play, 0); + AnimatedMat_DrawStepOpa(play, this->bodyMatAnim, this->unk_191); + AnimatedMat_DrawOpa(play, this->coreMatAnim); + Scene_SetRenderModeXlu(play, 0, 1); + + gDPSetEnvColor(POLY_OPA_DISP++, 30, 30, 0, 255); + + if (this->actionFunc != EnDeath_Dead && this->actionFunc != EnDeath_DeathCutscenePart4) { + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDeath_OverrideLimbDraw, EnDeath_PostLimbDraw, &this->actor); + } + if (this->actionFunc == EnDeath_DeathCutscenePart4) { + EnDeath_DrawCore(this, play); + } + if (!this->unk_18E) { + EnDeath_DrawScythe(this, play); + } + if (this->actor.colorFilterTimer != 0) { + func_800AE5A0(play); + } + Actor_DrawDamageEffects(play, &this->actor, this->dmgEffectPositions, ARRAY_COUNT(this->dmgEffectPositions), + this->dmgEffectScale, this->dmgEffectSteamScale, this->dmgEffectAlpha, this->dmgEffect); + if (this->actionFunc == EnDeath_SpinAttack || this->actionFunc == EnDeath_BlockProjectile) { + EnDeath_DrawScytheSpinning(this, play); + } + EnDeath_DrawBats(this, play); + if (this->actionFunc == EnDeath_Dead || this->actionFunc == EnDeath_DeathCutscenePart4 || + (this->actionFunc == EnDeath_DeathCutscenePart3 && this->actionTimer > 0)) { + EnDeath_DrawFlames(this, play); + } + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->scytheWorldPos, &this->scytheScreenPos); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Death/z_en_death.h b/src/overlays/actors/ovl_En_Death/z_en_death.h index 16863cf83..6aa3f696e 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.h +++ b/src/overlays/actors/ovl_En_Death/z_en_death.h @@ -2,6 +2,8 @@ #define Z_EN_DEATH_H #include "global.h" +#include "overlays/actors/ovl_En_Minideath/z_en_minideath.h" +#include "objects/object_death/object_death.h" struct EnDeath; @@ -9,9 +11,53 @@ typedef void (*EnDeathActionFunc)(struct EnDeath*, PlayState*); typedef struct EnDeath { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x44]; + /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnDeathActionFunc actionFunc; - /* 0x18C */ char unk_18C[0x7AC]; + /* 0x18C */ u8 unk_18C; + /* 0x18D */ u8 unk_18D; + /* 0x18E */ u8 unk_18E; + /* 0x18F */ u8 dmgEffect; + /* 0x190 */ s8 numScytheAfterImages; + /* 0x191 */ u8 unk_191; // animated material color step? + /* 0x192 */ u8 unk_192; + /* 0x193 */ u8 unk_193[GOMESS_LIMB_MAX]; + /* 0x1A9 */ u8 unk_1A9[56]; + /* 0x1E2 */ Vec3s jointTable[GOMESS_LIMB_MAX]; + /* 0x266 */ Vec3s morphTable[GOMESS_LIMB_MAX]; + /* 0x2EA */ s16 floatTimer; + /* 0x2EC */ s16 unk_2EC; + /* 0x2EE */ s16 actionTimer; + /* 0x2F0 */ char unk_2F0[0x2]; + /* 0x2F2 */ s16 unk_2F2; + /* 0x2F4 */ s16 unk_2F4; + /* 0x2F6 */ s16 coreRotation; + /* 0x2F8 */ s16 unk_2F8; + /* 0x2FA */ s16 camId; + /* 0x2FC */ s16 unk_2FC; + /* 0x300 */ s32 effectIndex; + /* 0x304 */ f32 scytheScale; + /* 0x308 */ f32 coreVelocity; + /* 0x30C */ f32 camEyeSpeed; + /* 0x310 */ f32 camAtSpeed; + /* 0x314 */ f32 dmgEffectScale; + /* 0x318 */ f32 dmgEffectSteamScale; + /* 0x31C */ f32 dmgEffectAlpha; + /* 0x320 */ Vec3f corePos; + /* 0x32C */ Vec3f scytheWorldPos; + /* 0x338 */ Vec3f scytheScreenPos; + /* 0x344 */ Vec3f camEyeTarget; + /* 0x350 */ Vec3f camAtTarget; + /* 0x35C */ Vec3f dmgEffectPositions[14]; + /* 0x404 */ Vec3f unk_404[56]; + /* 0x6A4 */ MtxF unk_6A4; + /* 0x6E4 */ EnMinideath* miniDeaths[20]; + /* 0x734 */ AnimatedMaterial* bodyMatAnim; + /* 0x738 */ AnimatedMaterial* coreMatAnim; + /* 0x73C */ ColliderCylinder bodyCollider; + /* 0x788 */ ColliderQuad unk_788; // weapon? + /* 0x808 */ ColliderSphere coreCollider; + /* 0x860 */ ColliderTris unk_860; + /* 0x880 */ ColliderTrisElement unk_880[2]; } EnDeath; // size = 0x938 #endif // Z_EN_DEATH_H diff --git a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c index de1d719dd..25c2766f4 100644 --- a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c +++ b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c @@ -93,8 +93,8 @@ void EnHakurock_Destroy(Actor* thisx, PlayState* play) { void func_80B21BE0(BossHakugin* parent, Vec3f* arg1, s32 arg2) { s32 i; - for (i = 0; i < ARRAY_COUNT(parent->unk_9F8); i++) { - BossHakuginEffect* gohtEffect = &parent->unk_9F8[i]; + for (i = 0; i < ARRAY_COUNT(parent->unk_09F8); i++) { + BossHakuginEffect* gohtEffect = &parent->unk_09F8[i]; if (gohtEffect->unk_18 < 0) { s16 sp2E; s16 sp2C; diff --git a/src/overlays/actors/ovl_En_Knight/z_en_knight.c b/src/overlays/actors/ovl_En_Knight/z_en_knight.c index 654a30928..8644729e5 100644 --- a/src/overlays/actors/ovl_En_Knight/z_en_knight.c +++ b/src/overlays/actors/ovl_En_Knight/z_en_knight.c @@ -6,6 +6,8 @@ #include "z_en_knight.h" #include "z64shrink_window.h" +#include "overlays/actors/ovl_Mir_Ray3/z_mir_ray3.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -16,37 +18,84 @@ void EnKnight_Destroy(Actor* thisx, PlayState* play); void EnKnight_Update(Actor* thisx, PlayState* play); void EnKnight_Draw(Actor* thisx, PlayState* play); +void func_809BD1AC(Actor* thisx, PlayState* play); +void func_809BD29C(Actor* thisx, PlayState* play); + void func_809B331C(EnKnight* this, PlayState* play); +void func_809B3394(EnKnight* this, PlayState* play); void func_809B33F0(EnKnight* this, PlayState* play); +void func_809B35BC(EnKnight* this, PlayState* play); void func_809B3618(EnKnight* this, PlayState* play); +void func_809B37C8(EnKnight* this, PlayState* play); void func_809B3834(EnKnight* this, PlayState* play); +void func_809B389C(EnKnight* this, PlayState* play); void func_809B3958(EnKnight* this, PlayState* play); void func_809B3B94(EnKnight* this, PlayState* play); +void func_809B3DAC(EnKnight* this, PlayState* arg1); +void func_809B3E9C(EnKnight* this, PlayState* arg1); +void func_809B3F0C(EnKnight* this, PlayState* arg1); void func_809B40E8(EnKnight* this, PlayState* play); +void func_809B41D8(EnKnight* this, PlayState* arg1); void func_809B41F8(EnKnight* this, PlayState* play); +void func_809B42B8(EnKnight* this, PlayState* play); void func_809B4308(EnKnight* this, PlayState* play); +void func_809B4880(EnKnight* this, PlayState* play); void func_809B4C58(EnKnight* this, PlayState* play); void func_809B4ED8(EnKnight* this, PlayState* play); void func_809B5058(EnKnight* this, PlayState* play); void func_809B52E8(EnKnight* this, PlayState* play); void func_809B5698(EnKnight* this, PlayState* play); void func_809B58D4(EnKnight* this, PlayState* play); +void func_809B59FC(EnKnight* this, PlayState* play); void func_809B5B08(EnKnight* this, PlayState* play); void func_809B5D54(EnKnight* this, PlayState* play); void func_809B5ED0(EnKnight* this, PlayState* play); void func_809B601C(EnKnight* this, PlayState* play); +void func_809B631C(EnKnight* this, PlayState* play); +void func_809B6528(EnKnight* this, PlayState* play); void func_809B6764(EnKnight* this, PlayState* play); +void func_809B6C04(EnKnight* this, PlayState* play); void func_809B6C54(EnKnight* this, PlayState* play); void func_809B6D94(EnKnight* this, PlayState* play); +void func_809B6EC8(EnKnight* this, PlayState* arg1); void func_809B6F40(EnKnight* this, PlayState* play); +void func_809B7190(EnKnight* this, PlayState* play); void func_809B71DC(EnKnight* this, PlayState* play); void func_809B7778(EnKnight* this, PlayState* play); void func_809B7950(EnKnight* this, PlayState* play); +void func_809B842C(EnKnight* this, PlayState* play); void func_809B8458(EnKnight* this, PlayState* play); +void func_809BA058(EnKnight* this, PlayState* play); void func_809BA0CC(EnKnight* this, PlayState* play); +void func_809BA940(EnKnight* this, PlayState* play); void func_809BA978(EnKnight* this, PlayState* play); -#if 0 +void func_809BD490(EnKnight* this, PlayState* play); +void func_809BD858(EnKnight* this, PlayState* play); + +void func_809B329C(EnKnight* this, PlayState* play, s32 arg2); +void func_809B4024(EnKnight* this, PlayState* play, s16 arg2); +void func_809B47EC(EnKnight* this, PlayState* play, u8 arg2); + +typedef struct { + Vec3f unk0; + Vec3f unkC; + Vec3f unk18; + char unk24[0x6]; + u8 unk2A; + s16 unk2C; + s16 unk2E; + s16 unk30; + f32 unk34; + f32 unk38; +} EnKnightEffect; // size = 0x38 + +Vec3f D_809BDAF0 = { 0.0f, 0.0f, 0.0f }; + +u8 D_809BDAFC = 0; + +u8 D_809BDB00 = 0; + // static DamageTable sDamageTable = { static DamageTable D_809BDB04 = { /* Deku Nut */ DMG_ENTRY(0, 0x1), @@ -122,320 +171,3820 @@ static DamageTable D_809BDB24 = { // static ColliderJntSphElementInit sJntSphElementsInit[1] = { static ColliderJntSphElementInit D_809BDB44[1] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 27 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809BDB8C = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809BDB44, // sJntSphElementsInit, -}; - // static ColliderJntSphElementInit sJntSphElementsInit[1] = { static ColliderJntSphElementInit D_809BDB68[1] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 32 }, 100 }, }, }; +// static ColliderJntSphInit sJntSphInit = { +static ColliderJntSphInit D_809BDB8C = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809BDB44), + D_809BDB44, // sJntSphElementsInit, +}; + // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_809BDB9C = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809BDB68, // sJntSphElementsInit, + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809BDB68), + D_809BDB68, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[1] = { static ColliderJntSphElementInit D_809BDBAC[1] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 27 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_809BDBD0 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809BDBAC, // sJntSphElementsInit, + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809BDBAC), + D_809BDBAC, // sJntSphElementsInit, }; // static ColliderJntSphElementInit sJntSphElementsInit[2] = { static ColliderJntSphElementInit D_809BDBE0[2] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7EFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7EFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7EFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7EFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 17 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_809BDC28 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_809BDBE0, // sJntSphElementsInit, + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_809BDBE0), + D_809BDBE0, // sJntSphElementsInit, }; // static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_809BDC38 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 15, 20, -10, { 0, 0, 0 } }, }; // static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_809BDC64 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ALL, AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7FFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ALL, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY | AC_TYPE_OTHER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7FFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 40, 0, { 0, 0, 0 } }, }; -ActorInit En_Knight_InitVars = { - /**/ ACTOR_EN_KNIGHT, - /**/ ACTORCAT_BOSS, - /**/ FLAGS, - /**/ OBJECT_KNIGHT, - /**/ sizeof(EnKnight), - /**/ EnKnight_Init, - /**/ EnKnight_Destroy, - /**/ EnKnight_Update, - /**/ EnKnight_Draw, +Color_RGBA8 D_809BDC90 = { 60, 50, 20, 255 }; + +Color_RGBA8 D_809BDC94 = { 40, 30, 30, 255 }; + +const ActorInit En_Knight_InitVars = { + ACTOR_EN_KNIGHT, + ACTORCAT_BOSS, + FLAGS, + OBJECT_KNIGHT, + sizeof(EnKnight), + (ActorFunc)EnKnight_Init, + (ActorFunc)EnKnight_Destroy, + (ActorFunc)EnKnight_Update, + (ActorFunc)EnKnight_Draw, }; -#endif - -extern DamageTable D_809BDB04; -extern DamageTable D_809BDB24; -extern ColliderJntSphElementInit D_809BDB44[1]; -extern ColliderJntSphInit D_809BDB8C; -extern ColliderJntSphElementInit D_809BDB68[1]; -extern ColliderJntSphInit D_809BDB9C; -extern ColliderJntSphElementInit D_809BDBAC[1]; -extern ColliderJntSphInit D_809BDBD0; -extern ColliderJntSphElementInit D_809BDBE0[2]; -extern ColliderJntSphInit D_809BDC28; -extern ColliderCylinderInit D_809BDC38; -extern ColliderCylinderInit D_809BDC64; - -extern UNK_TYPE D_060005A8; -extern UNK_TYPE D_06001CDC; -extern UNK_TYPE D_06002174; -extern UNK_TYPE D_06003008; -extern UNK_TYPE D_060031F0; -extern UNK_TYPE D_06003650; -extern UNK_TYPE D_060040E0; -extern UNK_TYPE D_06004620; -extern UNK_TYPE D_06004974; -extern UNK_TYPE D_060079D4; -extern UNK_TYPE D_06008524; -extern UNK_TYPE D_06008D80; -extern UNK_TYPE D_06009538; -extern UNK_TYPE D_06009D8C; -extern UNK_TYPE D_0600A530; -extern UNK_TYPE D_0600AFAC; -extern UNK_TYPE D_0600B5D4; -extern UNK_TYPE D_0600BCF4; -extern UNK_TYPE D_0600CDE0; -extern UNK_TYPE D_0600DDCC; -extern UNK_TYPE D_0600EA90; -extern UNK_TYPE D_0600EF44; -extern UNK_TYPE D_06010E98; -extern UNK_TYPE D_06011298; -extern UNK_TYPE D_06013020; -extern UNK_TYPE D_06018BC4; -extern UNK_TYPE D_06020950; -extern UNK_TYPE D_06022728; -extern UNK_TYPE D_06022CAC; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B20F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B21F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B22CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/EnKnight_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/EnKnight_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B2DD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B2F54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B316C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B31E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B329C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B331C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3394.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B33F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B35BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3618.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B37C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3834.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B389C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3958.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3A7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3B94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3CD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3DAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3E9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B3F0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4024.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B40E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B41D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B41F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B42B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4308.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B47EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4880.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4BFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4C58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4E84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4ED8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B4F90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B51DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B52E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5634.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5698.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B58D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B592C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B59FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5D38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5D54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5E90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5ED0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B5FA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B601C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B631C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B638C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6528.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6574.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6764.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6C04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6C54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6D38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6D94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6EC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B6F40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B7190.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B71DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B7708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B7778.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B78A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B7950.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B842C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B8458.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B9A18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B9D24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B9E00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809B9F8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BA058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BA0CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BA940.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BA978.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/EnKnight_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BC2C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BC67C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BC720.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BC8B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BCA80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BCAD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BCB54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BCB78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/EnKnight_Draw.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BD1AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BD260.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BD29C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BD490.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Knight/func_809BD858.s") +u16 D_809BDCB8[4] = { NA_SE_EN_BOSU_WALK, NA_SE_EN_YASE_WALK, NA_SE_EN_DEBU_WALK, 0 }; +u16 D_809BDCC0[4] = { NA_SE_EN_BOSU_LAUGH_K, NA_SE_EN_YASE_PAUSE_K, NA_SE_EN_DEBU_PAUSE_K, 0 }; +u16 D_809BDCC8[4] = { NA_SE_EN_BOSU_LAUGH_K, NA_SE_EN_YASE_LAUGH_K, NA_SE_EN_DEBU_LAUGH_K, 0 }; +u16 D_809BDCD0[4] = { NA_SE_EN_BOSU_ATTACK_W, NA_SE_EN_YASE_ATTACK_W, NA_SE_EN_DEBU_ATTACK_W, 0 }; +u16 D_809BDCD8[4] = { NA_SE_EN_BOSU_DAMAGE, NA_SE_EN_YASE_DAMAGE, NA_SE_EN_DEBU_DAMAGE, 0 }; +u16 D_809BDCE0[4] = { NA_SE_EN_BOSU_DEAD, NA_SE_EN_YASE_DEAD, NA_SE_EN_DEBU_DEAD, 0 }; +u16 D_809BDCE8[4] = { NA_SE_EN_BOSU_DEAD_VOICE, NA_SE_EN_YASE_DEAD_VOICE, NA_SE_EN_DEBU_DEAD_VOICE, 0 }; + +Color_RGBA8 D_809BDCF0 = { 60, 50, 20, 255 }; + +Color_RGBA8 D_809BDCF4 = { 40, 30, 30, 255 }; + +Color_RGBA8 D_809BDCF8 = { 170, 255, 255, 255 }; + +Color_RGBA8 D_809BDCFC = { 200, 200, 255, 255 }; + +Vec3f D_809BDD00 = { 0.0f, -1.0f, 0.0f }; + +Vec3f D_809BDD0C = { 100.0f, 0.0f, 0.0f }; + +Vec3f D_809BDD18 = { 0.0f, 600.0f, 0.0f }; + +Vec3f D_809BDD24 = { 0.0f, 600.0f, 1000.0f }; + +Vec3f D_809BDD30 = { 1000.0f, 0.0f, 0.0f }; + +s8 D_809BDD3C[0x20] = { + -1, -1, -1, -1, 3, 4, 5, -1, -1, 6, 7, 8, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, -1, 9, 10, 11, 12, 13, 14, -1, 0, 0, +}; + +Vec3f D_809BDD5C = { 300.0f, 500.0f, 0.0f }; + +Vec3f D_809BDD68 = { 1000.0f, 0.0f, 0.0f }; + +Vec3f D_809BDD74 = { 700.0f, -500.0f, 0.0f }; + +Vec3f D_809BDD80 = { 300.0f, 500.0f, 0.0f }; + +EnKnight* D_809BEFD0; +EnKnight* D_809BEFD4; +EnKnight* D_809BEFD8; +EnKnight* D_809BEFDC; +EnKnight* D_809BEFE0; +MirRay3* D_809BEFE4; +EnKnightEffect D_809BEFE8[100]; + +// object + +extern AnimationHeader D_060005A8; +extern AnimationHeader D_060009E0; +extern AnimationHeader D_06000D9C; +extern AnimationHeader D_06001CDC; +extern AnimationHeader D_06002174; +extern AnimationHeader D_06003008; +extern AnimationHeader D_060031F0; +extern AnimationHeader D_06003650; +extern AnimationHeader D_060040E0; +extern AnimationHeader D_06004620; +extern AnimationHeader D_06004974; +extern AnimationHeader D_06005D30; +extern AnimationHeader D_060079D4; +extern AnimationHeader D_06008390; +extern AnimationHeader D_06008524; +extern AnimationHeader D_060089E4; +extern AnimationHeader D_06008D80; +extern AnimationHeader D_06009538; +extern AnimationHeader D_06009D8C; +extern AnimationHeader D_0600A530; +extern AnimationHeader D_0600AFAC; +extern AnimationHeader D_0600B5D4; +extern AnimationHeader D_0600BCF4; +extern AnimationHeader D_0600C384; +extern AnimationHeader D_0600CDE0; +extern AnimationHeader D_0600DDCC; +extern AnimationHeader D_0600E15C; +extern AnimationHeader D_0600E45C; +extern AnimationHeader D_0600EA90; +extern AnimationHeader D_0600EF44; +extern AnimationHeader D_06010E98; +extern AnimationHeader D_06011298; +extern AnimationHeader D_06005E78; +extern AnimationHeader D_06006754; +extern AnimationHeader D_06006EF8; +extern AnimationHeader D_0600A88C; +extern AnimationHeader D_0600C7F0; +extern AnimationHeader D_0600D870; +extern AnimationHeader D_0600E7F4; +extern AnimationHeader D_0600FC78; +extern AnimationHeader D_0601024C; +extern AnimationHeader D_0602105C; +extern AnimationHeader D_06021B10; +extern AnimationHeader D_06021E34; +extern Gfx D_06013020[]; +extern Gfx D_06012DB0[]; +extern Gfx D_06012400[]; +extern AnimatedMaterial D_06018BC4; +extern AnimationHeader D_06020950; +extern AnimationHeader D_06022728; +extern AnimationHeader D_06022CAC; +extern FlexSkeletonHeader D_06020374; +extern FlexSkeletonHeader D_060201A8; +extern Gfx D_060188F8[]; +extern Gfx D_060189F0[]; +extern Gfx D_06018AF0[]; + +extern Gfx D_08000000[]; + +void func_809B20F0(PlayState* play, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, f32 arg5, s16 arg6) { + s16 i; + EnKnightEffect* eff; + + for (eff = play->specialEffects, i = 0; i < ARRAY_COUNT(D_809BEFE8); i++, eff++) { + if (eff->unk2A == 0) { + eff->unk2A = 1; + eff->unk0 = *arg1; + eff->unkC = *arg2; + eff->unk18 = *arg3; + eff->unk30 = 0; + eff->unk34 = (BREG(50) * 0.0001f + 0.001f) * arg4; + eff->unk38 = (BREG(51) * 0.0001f + 0.001f) * arg5; + eff->unk2E = arg6; + eff->unk2C = 0; + return; + } + } +} + +void func_809B21F4(EnKnight* this, s32 arg1, ColliderJntSph* jntSph, Vec3f* pos) { + f32 var_fv0 = (this == D_809BEFD0) ? 1.3076924f : 1.0f; + + if (this->actionFunc == func_809B52E8) { + var_fv0 *= 2.0f; + } + + jntSph->elements[arg1].dim.worldSphere.center.x = pos->x; + jntSph->elements[arg1].dim.worldSphere.center.y = pos->y; + jntSph->elements[arg1].dim.worldSphere.center.z = pos->z; + jntSph->elements[arg1].dim.worldSphere.radius = + jntSph->elements[arg1].dim.modelSphere.radius * var_fv0 * jntSph->elements[arg1].dim.scale; +} + +void func_809B22CC(EnKnight* this, PlayState* play, u8 arg2) { + u8 i; + Vec3f pos; + Vec3f vel; + Vec3f acc; + + if (!(this->unk146 & arg2) && this->unk162 == 0 && + (this->unk2A4 > 1.0f || this->unk2A8 > 1.0f || arg2 == 0 || this->actor.speed > 1.0f)) { + for (i = 0; i < 2; i++) { + vel.x = Rand_CenteredFloat(3.0f); + vel.y = Rand_ZeroFloat(1.0f); + vel.z = Rand_CenteredFloat(3.0f); + acc.y = -0.1f; + acc.x = acc.z = 0.0f; + pos.x = this->unk2AC[i].x + Rand_CenteredFloat(10.0f); + pos.y = (Rand_ZeroFloat(5.0f) + this->actor.floorHeight) - 5.0f; + pos.z = this->unk2AC[i].z + Rand_CenteredFloat(10.0f); + func_800B0EB0(play, &pos, &vel, &acc, &D_809BDC90, &D_809BDC94, Rand_ZeroFloat(80.0f) + 150.0f, 10, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } +} + +void EnKnight_Init(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; + s32 pad; + s32 temp_v0_2; + + this->actor.targetMode = 5; + this->actor.colChkInfo.mass = MASS_HEAVY; + this->actor.colChkInfo.damageTable = &D_809BDB04; + this->unk17C = 255.0f; + this->unk146 = Rand_ZeroFloat(1000.0f); + this->actor.flags |= 0x400; + + if (this->actor.params == 0x64) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 12.0f); + SkelAnime_InitFlex(play, &this->unk194, &D_060201A8, &D_06003008, this->unk2C4, this->unk372, 29); + Actor_SetScale(&this->actor, KREG(12) * 0.001f + 0.017f); + func_809BA058(this, play); + Collider_InitAndSetCylinder(play, &this->unk488, &this->actor, &D_809BDC38); + Collider_InitAndSetCylinder(play, &this->unk634, &this->actor, &D_809BDC64); + this->actor.colChkInfo.health = 0xA - BREG(40); + } else if (this->actor.params >= 0xC8) { + this->actor.update = func_809BD1AC; + this->actor.draw = func_809BD29C; + this->actor.flags &= ~1; + if (1) {} + if (this->actor.params == 0xC8) { + SkelAnime_InitFlex(play, &this->unk194, &D_06020374, &D_060040E0, this->unk2C4, this->unk372, 0x1D); + Actor_SetScale(&this->actor, KREG(13) * 0.001f + 0.013f); + } else { + SkelAnime_InitFlex(play, &this->unk194, &D_060201A8, &D_060040E0, this->unk2C4, this->unk372, 0x1D); + Actor_SetScale(&this->actor, KREG(13) * 0.001f + 0.017f); + } + if (this->actor.params == 0xCA) { + this->unk17C = BREG(79) + 100.0f; + } else { + this->unk17C = BREG(77) + 120.0f; + } + } else { + this->actor.hintId = 0x16; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 40.0f); + Collider_InitAndSetJntSph(play, &this->unk534, &this->actor, &D_809BDBD0, this->unk554); + Collider_InitAndSetJntSph(play, &this->unk594, &this->actor, &D_809BDC28, this->unk5B4); + if (this->actor.params == 0x23) { + Collider_InitAndSetJntSph(play, &this->unk4D4, &this->actor, &D_809BDB8C, this->unk4F4); + SkelAnime_InitFlex(play, &this->unk194, &D_06020374, &D_060040E0, this->unk2C4, this->unk372, 0x1D); + this->actor.colChkInfo.health = 6 - BREG(40); + Actor_SetScale(&this->actor, KREG(13) * 0.001f + 0.013f); + } else { + Collider_InitAndSetJntSph(play, &this->unk4D4, &this->actor, &D_809BDB9C, this->unk4F4); + SkelAnime_InitFlex(play, &this->unk194, &D_060201A8, &D_060040E0, this->unk2C4, this->unk372, 0x1D); + this->actor.colChkInfo.health = 14 - BREG(41); + Actor_SetScale(&this->actor, KREG(12) * 0.001f + 0.017f); + this->unk290 = Rand_ZeroFloat(1.9999f); + } + this->unk18E = 3; + this->unk180 = 180.0f; + temp_v0_2 = D_809BDAFC & 3; + D_809BDAFC++; + this->unk6B4 = D_809BDCB8[temp_v0_2]; + this->unk6B6 = D_809BDCC0[temp_v0_2]; + this->unk6B8 = D_809BDCC8[temp_v0_2]; + this->unk6BC = D_809BDCD0[temp_v0_2]; + this->unk6BE = D_809BDCD8[temp_v0_2]; + this->unk6C0 = D_809BDCE0[temp_v0_2]; + this->unk6C2 = D_809BDCE8[temp_v0_2]; + if (this->actor.params != 0x23) { + s32 i; + play->specialEffects = D_809BEFE8; + + for (i = 0; i < ARRAY_COUNT(D_809BEFE8); i++) { + D_809BEFE8[i].unk2A = 0; + } + + D_809BEFD0 = this; + D_809BEFE0 = NULL; + D_809BEFDC = NULL; + this->actor.shape.rot.y = -0x4000; + D_809BEFD4 = + (EnKnight*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KNIGHT, 1398.0f, 66.0f, 2730.0f, + this->actor.shape.rot.x, this->actor.shape.rot.y, this->actor.shape.rot.z, 0x23); + D_809BEFD8 = + (EnKnight*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KNIGHT, 1398.0f, 66.0f, 2969.0f, + this->actor.shape.rot.x, this->actor.shape.rot.y, this->actor.shape.rot.z, 0x23); + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, 0x12E, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0); + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, 0x12E, 0.0f, 0.0f, 0.0f, 0, 0, 0, 1); + } + if ((gSaveContext.eventInf[5] & 0x80) && !Flags_GetClear(play, play->roomCtx.curRoom.num)) { + if (this == D_809BEFD0) { + this->actor.world.pos.x = BREG(27) + 1376.0f; + this->actor.world.pos.y = 45.0f; + this->actor.world.pos.z = BREG(28) + 2864.0f; + func_809B6528(this, play); + this->unk194.curFrame = 25.0f; + this->actor.flags &= ~1; + D_809BDB00 = KREG(83) + 0x28; + } else { + func_809B3E9C(this, play); + this->unk152 = 1; + this->unk46C = this->unk470 = 1.0f; + this->actor.gravity = -1.5f; + this->unk6B0 = 60.0f; + } + play->envCtx.lightSettingOverride = 7; + return; + } + func_809B631C(this, play); + play->envCtx.lightSettingOverride = 0; + } +} + +void EnKnight_Destroy(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; +} + +void func_809B2DD0(EnKnight* this, PlayState* play) { + Player* player; + Actor* explosive; + f32 px; + f32 pz; + f32 dx; + f32 dz; + + if (this->unk162 == 0) { + player = GET_PLAYER(play); + + explosive = play->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + while (explosive != NULL) { + px = this->actor.world.pos.x; + pz = this->actor.world.pos.z; + dx = explosive->world.pos.x - px; + dz = explosive->world.pos.z - pz; + if (sqrtf(SQ(dx) + SQ(dz)) < 100.0f) { + this->unk440.x = px - dx * 100.0f; + this->unk440.z = pz - dz * 100.0f; + func_809B47EC(this, play, 0); + } + explosive = explosive->next; + } + + if (D_809BEFE4 != NULL && D_809BEFE4->unk_214 > 0.1f && this->actor.xzDistToPlayer <= (BREG(70) + 300.0f)) { + px = this->actor.world.pos.x; + pz = this->actor.world.pos.z; + dx = player->actor.world.pos.x - px; + dz = player->actor.world.pos.z - pz; + this->unk440.x = px - dx * 100.0f; + this->unk440.z = pz - dz * 100.0f; + func_809B47EC(this, play, 1); + } + } +} + +s32 func_809B2F54(EnKnight* this, PlayState* play) { + f32 var_fv0; + s32 sp20 = false; + Player* player = GET_PLAYER(play); + + var_fv0 = (this == D_809BEFD0) ? 1.3076924f : 1.0f; + + if (this->actor.xzDistToPlayer <= 90.0f * var_fv0 && !(this->unk146 & 7)) { + if (Rand_ZeroOne() < 0.5f && D_809BEFDC != (EnKnight*)player->actor.parent) { + func_809B389C(this, play); + } else if (Rand_ZeroOne() < 0.5f) { + func_809B329C(this, play, false); + } else { + func_809B35BC(this, play); + } + sp20 = true; + } + + if (this == D_809BEFD0 && this->unk162 == 0 && (this->unk14A[2] == 0 || BREG(15) == 1)) { + if (KREG(71) + 100.0f < this->actor.xzDistToPlayer) { + sp20 = true; + if (this->actor.xzDistToPlayer < KREG(72) + 300.0f) { + if (Rand_ZeroOne() > 0.5f) { + func_809B6EC8(this, play); + } else { + func_809B6C04(this, play); + } + } else { + func_809B6C04(this, play); + } + } + } + return sp20; +} + +s32 func_809B316C(EnKnight* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s16 temp_v1 = this->unk172; + s16 var_a0 = temp_v1 - this->actor.shape.rot.y; + + if (ABS_ALT(var_a0) < 0x3000) { + s16 var_a0 = temp_v1 - (s16)(player->actor.shape.rot.y + 0x8000); + s32 var_v0 = ABS_ALT(var_a0); + + if (var_v0 < 0x3000) { + return 1; + } + } + return 0; +} + +s32 func_809B31E8(EnKnight* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s16 var_v1 = this->unk172 - (s16)(player->actor.focus.rot.y + 0x8000); + + if (ABS_ALT(var_v1) < (s16)(KREG(91) * 0x100 + 0x400)) { + s16 var_a1 = (s16) - this->unk170 - player->actor.focus.rot.x; + s32 var_v0 = ABS_ALT(var_a1); + + if (var_v0 < (s16)(KREG(92) * 0x100 + 0x300)) { + return 1; + } + } + return 0; +} + +void func_809B329C(EnKnight* this, PlayState* play, s32 arg2) { + Animation_MorphToLoop(&this->unk194, &D_06020950, -5.0f); + this->actionFunc = func_809B331C; + if (this == D_809BEFD0) { + if (arg2) { + this->unk14A[0] = 0; + } else { + this->unk14A[0] = 6; + } + } else { + this->unk14A[0] = 15; + } +} + +void func_809B331C(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0x500); + if (this->unk14A[0] == 0) { + func_809B3394(this, play); + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); +} + +void func_809B3394(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_06011298, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06011298); + this->actionFunc = func_809B33F0; +} + +void func_809B33F0(EnKnight* this, PlayState* play) { + Vec3f sp2C; + + this->unk186 = 0; + if (this->unk194.curFrame >= 3.0f && this->unk194.curFrame <= 6.0f) { + this->unk450 = 255.0f; + this->unk454 = -19.0f; + this->unk458 = 46.0f; + this->unk45C = 17.0f; + this->unk460 = -0.5497787f; + this->unk464 = 2.9059734f; + this->unk468 = -1.1780972f; + } + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk194.curFrame >= 2.0f && this->unk194.curFrame <= 5.0f) { + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(5.0f, &sp2C); + this->unk2A4 = sp2C.x; + this->unk2A8 = sp2C.z; + } + if (Animation_OnFrame(&this->unk194, 1.0f)) { + Actor_PlaySfx(&this->actor, this->unk6BC); + } + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + if (Rand_ZeroOne() < 0.5f && this->actor.xzDistToPlayer <= 100.0f) { + func_809B35BC(this, play); + } else { + func_809B3E9C(this, play); + } + } + this->unk190 = 1; +} + +void func_809B35BC(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_06022728, -5.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06022728); + this->actionFunc = func_809B3618; +} + +void func_809B3618(EnKnight* this, PlayState* play) { + Vec3f sp2C; + + this->unk186 = 0; + if (this == D_809BEFD0) { + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0x800); + } + if (this->unk194.curFrame >= 12.0f && this->unk194.curFrame <= 15.0f) { + this->unk450 = 255.0f; + this->unk454 = -20.0f; + this->unk458 = 47.0f; + this->unk45C = 0.0f; + this->unk460 = 3.1415927f; + this->unk464 = 0.f; + this->unk468 = 0.47123894f; + } + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk194.curFrame >= 12.0f && this->unk194.curFrame <= 15.0f) { + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(5.0f, &sp2C); + this->unk2A4 = sp2C.x; + this->unk2A8 = sp2C.z; + } + if (Animation_OnFrame(&this->unk194, 12.0f)) { + Actor_PlaySfx(&this->actor, this->unk6BC); + } + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + func_809B37C8(this, play); + } + if (this->unk194.curFrame >= 12.0f) { + this->unk190 = 1; + } +} + +void func_809B37C8(EnKnight* this, PlayState* play) { + Animation_MorphToLoop(&this->unk194, &D_06022CAC, 0.0f); + this->actionFunc = func_809B3834; + if (this == D_809BEFD0) { + this->unk14A[0] = 6; + } else { + this->unk14A[0] = 15; + } +} + +void func_809B3834(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); +} + +void func_809B389C(EnKnight* this, PlayState* play) { + if (Rand_ZeroOne() < 0.5f) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600C384, -2.0f); + this->unk1D8 = Animation_GetLastFrame(&D_0600C384); + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_0600BCF4, -2.0f); + this->unk1D8 = Animation_GetLastFrame(&D_0600BCF4); + } + this->actionFunc = func_809B3958; + this->unk14A[0] = 20; +} + +void func_809B3958(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + if (Rand_ZeroOne() < 0.6f && this->actor.xzDistToPlayer <= 100.0f) { + if (Rand_ZeroOne() < 0.5f) { + func_809B389C(this, play); + } else { + func_809B329C(this, play, 0); + } + } else { + func_809B3E9C(this, play); + } + } + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 5, 0x500); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] == 16) { + this->unk190 = 1; + } +} + +void func_809B3A7C(EnKnight* this, PlayState* play) { + s32 i; + Vec3f sp28; + + if (this->actor.xzDistToPlayer <= 200.0f) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600AFAC, -3.0f); + this->unk1D8 = Animation_GetLastFrame(&D_0600AFAC); + this->actionFunc = func_809B3B94; + Matrix_RotateYS(this->unk172, MTXMODE_NEW); + Matrix_MultVecZ(KREG(49) + 7.0f, &sp28); + this->unk2A4 = sp28.x; + this->unk2A8 = sp28.z; + this->actor.velocity.y = 10.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_TEKU_JUMP); + this->unk14A[0] = 15; + + for (i = 0; i < 5; i++) { + func_809B22CC(this, play, 0); + } + } +} + +void func_809B3B94(EnKnight* this, PlayState* play) { + if (this->unk14A[0] >= 2 && this->unk14A[0] < 6) { + this->unk450 = 255.0f; + this->unk454 = -19.0f; + this->unk458 = 46.0f; + this->unk45C = 17.0f; + this->unk460 = -0.5497787f; + this->unk464 = 2.9059734f; + this->unk468 = -1.1780972f; + } + SkelAnime_Update(&this->unk194); + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600B5D4, 0.0f); + Actor_PlaySfx(&this->actor, this->unk6BC); + this->unk1D8 = 1000.0f; + } + this->actor.speed = 0.0f; + if (this->actor.velocity.y <= 0.0f && this->actor.bgCheckFlags & 1) { + this->unk2A8 = 0.0f; + this->unk2A4 = 0.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } + this->unk190 = 1; +} + +void func_809B3CD0(EnKnight* this, PlayState* play) { + if (this == D_809BEFD0 && this->actor.xzDistToPlayer <= 120.0f && Rand_ZeroOne() < 0.1f) { + func_809B59FC(this, play); + return; + } + if (this->actionFunc != func_809B3DAC) { + this->unk424 = this->actionFunc; + Animation_MorphToPlayOnce(&this->unk194, &D_060031F0, -2.0f); + this->unk1D8 = Animation_GetLastFrame(&D_060031F0); + this->actionFunc = func_809B3DAC; + } + this->unk14A[0] = 5; +} + +void func_809B3DAC(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0x800); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] != 0) { + this->unk191 = 1; + } else if (this->unk424 == func_809B4880) { + func_809B47EC(this, play, 1); + } else { + func_809B3E9C(this, play); + if (this == D_809BEFD0 && Rand_ZeroOne() < 0.4f) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_CYNICAL); + } + } + this->unk192 = 1; +} + +void func_809B3E9C(EnKnight* this, PlayState* play) { + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + this->actionFunc = func_809B3F0C; + this->unk14A[0] = Rand_ZeroFloat(50.0f) + 20.0f; +} + +void func_809B3F0C(EnKnight* this, PlayState* play) { + s16 temp_v1; + s32 var_a0; + + SkelAnime_Update(&this->unk194); + temp_v1 = this->unk172 - this->actor.shape.rot.y; + var_a0 = (this == D_809BEFD0) ? 0x7FFF : 0x6000; + if (ABS_ALT(temp_v1) < var_a0) { + func_809B41D8(this, play); + } else { + if (!(this->unk146 & 7) && Rand_ZeroOne() < 0.75f) { + this->unk186 = Rand_CenteredFloat(28672.0f); + } + if (this->unk14A[0] == 0) { + func_809B4024(this, play, 0x4000); + } + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + this->unk192 = 1; +} + +void func_809B4024(EnKnight* this, PlayState* play, s16 arg2) { + this->actionFunc = func_809B40E8; + Animation_MorphToPlayOnce(&this->unk194, &D_0600EF44, -2.0f); + if (Rand_ZeroOne() < 0.5f) { + this->unk15A = this->actor.shape.rot.y + arg2; + this->unk186 = 0x3800; + } else { + this->unk15A = this->actor.shape.rot.y - arg2; + this->unk186 = -0x3800; + } + this->unk15C = (arg2 == 0x4000) ? 0 : 0x800; + this->unk14A[0] = 0x14; +} + +void func_809B40E8(EnKnight* this, PlayState* play) { + s16 temp_v0; + + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] < 0xF) { + Math_ApproachS(&this->actor.world.rot.y, this->unk15A, 2, this->unk15C); + Math_ApproachS(&this->unk15C, 0x800, 1, 0x200); + } + temp_v0 = this->unk172 - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x6000) { + func_809B41D8(this, play); + } else if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } + this->unk18C = 0x3000; + this->unk18E = 2; +} + +void func_809B41D8(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B41F8; + this->unk14A[0] = 0xA; +} + +void func_809B41F8(EnKnight* this, PlayState* play) { + s16 temp_v0; + + SkelAnime_Update(&this->unk194); + temp_v0 = this->unk172 - this->actor.shape.rot.y; + if (temp_v0 > 0x3800) { + this->unk186 = 0x3800; + } else if (temp_v0 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v0; + } + if (this->unk14A[0] == 0) { + func_809B42B8(this, play); + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + this->unk18C = 0x3000; + this->unk18E = 2; + this->unk192 = 1; +} + +void func_809B42B8(EnKnight* this, PlayState* play) { + Animation_MorphToLoop(&this->unk194, &D_06004620, -5.0f); + this->actionFunc = func_809B4308; + this->actor.speed = 0.0f; +} + +void func_809B4308(EnKnight* this, PlayState* play) { + f32 sp5C; + f32 dx; + f32 dz; + f32 var_fv0; + Vec3f sp44; + Vec3f sp38; + s16 temp_v0; + s16 sp34; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->unk194); + if (!(this->unk146 & 0x3F) && Rand_ZeroOne() < 0.5f) { + if (Rand_ZeroOne() < 0.6666f) { + Actor_PlaySfx(&this->actor, this->unk6B6); + } else { + Actor_PlaySfx(&this->actor, this->unk6B8); + } + } + if (this != D_809BEFD0 && this->actor.xzDistToPlayer > 150.0f) { + Matrix_RotateYS(player->actor.world.rot.y, MTXMODE_NEW); + if (this == D_809BEFD4) { + sp44.x = 100.0f; + } else { + sp44.x = -100.0f; + } + sp44.y = 0.0f; + sp44.z = 100.0f; + Matrix_MultVec3f(&sp44, &sp38); + this->unk440.x = player->actor.world.pos.x + sp38.x; + this->unk440.z = player->actor.world.pos.z + sp38.z; + dx = this->unk440.x - this->actor.world.pos.x; + dz = this->unk440.z - this->actor.world.pos.z; + sp34 = Math_Atan2S_XY(dz, dx); + } else { + sp34 = this->unk172; + } + Math_ApproachS(&this->actor.world.rot.y, sp34, 5, 0xA00); + Math_ApproachS(&this->actor.shape.rot.y, this->unk172, 5, 0x500); + sp5C = this->actor.speed; + var_fv0 = (this == D_809BEFD0) ? 1.3076924f : 1.0f; + if (this->actor.xzDistToPlayer <= (150.0f * var_fv0)) { + if (this->actor.xzDistToPlayer <= (80.0f * var_fv0)) { + if (this->actor.xzDistToPlayer <= (40.0f * var_fv0)) { + Math_ApproachF(&this->actor.speed, -2.5f, 1.0f, 1.0f); + } else { + Math_ApproachF(&this->actor.speed, 0.0f, 1.0f, 1.0f); + } + } else { + Math_ApproachF(&this->actor.speed, 2.5f, 1.0f, 1.0f); + } + } else { + Math_ApproachF(&this->actor.speed, 5.0f, 1.0f, 1.0f); + if ((Animation_OnFrame(&this->unk194, 0.0f) != 0) || (Animation_OnFrame(&this->unk194, 5.0f) != 0)) { + Actor_PlaySfx(&this->actor, this->unk6B4); + } + func_809B22CC(this, play, 3); + } + if ((this->actor.speed > 3.0f) && (sp5C <= 3.0f)) { + Animation_MorphToLoop(&this->unk194, &D_06003650, -3.0f); + if (Rand_ZeroOne() < 0.25f) { + func_809B3A7C(this, play); + } + } + if (this->actionFunc == func_809B4308) { + if ((this->actor.speed < 4.0f) && (sp5C >= 4.0f)) { + Animation_MorphToLoop(&this->unk194, &D_06004620, -5.0f); + if (Rand_ZeroOne() < 0.25f) { + func_809B3A7C(this, play); + } + } + if ((this->actor.speed < 1.0f) && (sp5C >= 1.0f)) { + Animation_MorphToLoop(&this->unk194, &D_060040E0, -10.0f); + } + if ((this->actor.speed >= 1.0f) && (sp5C < 1.0f)) { + Animation_MorphToLoop(&this->unk194, &D_06004620, -5.0f); + } + } + temp_v0 = sp34 - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x6000) { + if (temp_v0 >= 0x3801) { + this->unk186 = 0x3800; + } else if (temp_v0 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v0; + } + if (func_809B2F54(this, play) != 0) { + return; + } + } else { + func_809B3E9C(this, play); + } + this->unk192 = 1; +} + +void func_809B47EC(EnKnight* this, PlayState* play, u8 arg2) { + if (this->actionFunc != func_809B4880) { + Animation_MorphToLoop(&this->unk194, &D_06003650, -5.0f); + this->unk148 = 0; + this->actionFunc = func_809B4880; + } + this->unk14A[0] = Rand_ZeroFloat(15.0f) + 10.0f; + this->unk292 = arg2; +} + +void func_809B4880(EnKnight* this, PlayState* play) { + f32 dx; + f32 dz; + + SkelAnime_Update(&this->unk194); + this->unk186 = 0; + switch (this->unk148) { + case 0: + Math_ApproachF(&this->actor.speed, 5.0f, 1.0f, 1.0f); + dx = this->unk440.x - this->actor.world.pos.x; + dz = this->unk440.z - this->actor.world.pos.z; + Math_ApproachS(&this->actor.world.rot.y, Math_Atan2S_XY(dz, dx), 5, 0xA00); + if (Animation_OnFrame(&this->unk194, 0.0f) || Animation_OnFrame(&this->unk194, 5.0f)) { + Actor_PlaySfx(&this->actor, this->unk6B4); + } + func_809B22CC(this, play, 3); + if (this->unk292 != 0 && ((D_809BEFE4 != NULL && D_809BEFE4->unk_214 < 0.1f) || + BREG(70) + 300.0f < this->actor.xzDistToPlayer || this->unk291 != 0)) { + if (this->unk291 != 0) { + this->unk148 = 3; + this->unk2A1 = 30; + Animation_MorphToLoop(&this->unk194, &D_0600E45C, -2.0f); + this->unk1D8 = Animation_GetLastFrame(&D_0600E45C); + Actor_PlaySfx(&this->actor, NA_SE_EN_STAL_FREEZE_LIGHTS); + } else { + this->unk148 = 1; + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + this->unk1D8 = 1000.0f; + } + } + break; + case 1: + if (this->unk291 != 0) { + this->unk148 = 2; + Animation_MorphToPlayOnce(&this->unk194, &D_060031F0, -2.0f); + Actor_PlaySfx(&this->actor, this->unk6B6); + } + goto block_24; + case 2: + if (this->unk291 == 0) { + this->unk148 = 1; + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + } + if (this->unk291 >= 8) { + Math_ApproachF(&this->unk474, 1.0f, 1.0f, 0.5f); + } + goto block_24; + case 3: + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + this->unk148 = 2; + Animation_MorphToPlayOnce(&this->unk194, &D_060031F0, -2.0f); + this->unk1D8 = 1000.0f; + } + goto block_24; + + block_24: + this->unk594.base.colType = 0xA; + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk1D8 > 10.0f) { + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0xE00); + } + if (D_809BEFE4 != NULL && D_809BEFE4->unk_214 > 0.1f) { + this->unk14A[0] = Rand_ZeroFloat(15.0f) + 10.0f; + } + this->unk192 = 1; + break; + } + if (this->unk14A[0] == 0) { + func_809B4024(this, play, 0x7000); + } +} + +void func_809B4BFC(EnKnight* this, PlayState* play) { + Animation_MorphToLoop(&this->unk194, &D_0600CDE0, -25.0f); + Actor_PlaySfx(&this->actor, this->unk6B6); + this->actionFunc = func_809B4C58; + this->unk14A[0] = 35; +} + +void func_809B4C58(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + this->unk186 = 0; + Math_ApproachF(&this->unk180, 180.0f, 1.0f, 10.0f); + + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } + + if (((s16)(BREG(74) + 10) < this->unk14A[0]) && !((BREG(76) + 3) & this->unk146)) { + EnKnight* temp_v0 = (EnKnight*)Actor_SpawnAsChild( + &play->actorCtx, &this->actor, play, ACTOR_EN_KNIGHT, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, + (this == D_809BEFD0) ? 0x00C9 : 0x00C8); + + if (temp_v0 != NULL) { + s32 i; + + for (i = 0; i < 29; i++) { + temp_v0->unk194.jointTable[i] = this->unk194.jointTable[i]; + temp_v0->unk194.skeleton = this->unk194.skeleton; + temp_v0->unk194.dListCount = this->unk194.dListCount; + } + } + } +} + +void func_809B4E84(EnKnight* this, PlayState* play, u16 arg2) { + this->actionFunc = func_809B4ED8; + this->unk14A[0] = arg2; + this->unk14A[1] = 0x1E; + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, arg2); +} + +void func_809B4ED8(EnKnight* this, PlayState* play) { + if (this->unk14A[1] > 0 && this->unk14A[1] < 23) { + if (this->unk14A[1] == 1) { + D_809BEFE0 = NULL; + } else { + D_809BEFE0 = this; + } + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] < 20) { + if (this->unk14A[0] % 2 != 0) { + this->unk184 = 0x708; + } else { + this->unk184 = -0x708; + } + } else { + this->unk186 = 0; + } + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } +} + +void func_809B4F90(EnKnight* this, PlayState* arg1) { + Vec3f sp2C; + s16 temp_v0; + + this->actionFunc = func_809B5058; + temp_v0 = this->unk172 - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x4000) { + Animation_MorphToPlayOnce(&this->unk194, &D_06004974, 0.0f); + this->unk148 = 0; + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_06000D9C, 0.0f); + this->unk148 = 1; + } + Matrix_RotateYS(this->unk172, MTXMODE_NEW); + Matrix_MultVecZ(-15.0f, &sp2C); + this->unk2A4 = sp2C.x; + this->unk2A8 = sp2C.z; + this->unk14A[0] = 10; +} + +void func_809B5058(EnKnight* this, PlayState* play) { + f32 rand = Rand_ZeroOne(); + + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] == 0) { + if (this == D_809BEFD0 && this->actor.xzDistToPlayer < 150.0f) { + if (rand < 0.25f) { + func_809B35BC(this, play); + } else if (rand < 0.5f) { + func_809B329C(this, play, 0); + } else if (rand < 0.75f) { + func_809B59FC(this, play); + } else { + func_809B3CD0(this, play); + } + } else if (this->unk148 == 0) { + func_809B3E9C(this, play); + } else { + func_809B4024(this, play, 0x6000); + } + } + if (this == D_809BEFD0 && this->unk14A[0] < 4) { + this->unk192 = 1; + } +} + +void func_809B51DC(EnKnight* this, PlayState* play) { + Vec3f sp2C; + s16 temp_v0; + + this->actionFunc = func_809B52E8; + temp_v0 = this->unk172 - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x4000) { + Animation_MorphToPlayOnce(&this->unk194, &D_06001CDC, 0.0f); + this->unk1D8 = 1.0f; + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_06005D30, 0.0f); + this->unk1D8 = -1.0f; + } + Matrix_RotateYS(this->unk172, MTXMODE_NEW); + Matrix_MultVecZ(KREG(29) + -15.0f, &sp2C); + this->unk2A4 = sp2C.x; + this->unk2A8 = sp2C.z; + this->unk14A[0] = 35; + this->unk14A[1] = 150; + this->actor.colChkInfo.damageTable = &D_809BDB24; +} + +void func_809B52E8(EnKnight* this, PlayState* play) { + s32 pad; + f32 temp_fv0; + f32 var_fv0; + Vec3f sp40; + CollisionPoly* sp3C; + f32 temp_fv1; + f32 temp; + f32 temp_ft4; + s16 var_v0; + + if (this->unk14A[0] < (s16)(KREG(6) + 25)) { + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + if (this == D_809BEFD0) { + var_fv0 = -75.0f; + } else { + var_fv0 = -65.0f; + } + Matrix_MultVecZ((KREG(9) + 1.0f) * (var_fv0 * this->unk1D8), &sp40); + sp40.x += this->actor.world.pos.x; + sp40.y += this->actor.world.pos.y + 300.0f; + sp40.z += this->actor.world.pos.z; + temp_fv0 = BgCheck_EntityRaycastFloor1(&play->colCtx, &sp3C, &sp40); + if (temp_fv0 > -10.0f && temp_fv0 != this->actor.floorHeight) { + temp_fv1 = sp40.x - this->actor.world.pos.x; + temp = temp_fv0 - this->actor.world.pos.y; + temp_ft4 = sp40.z - this->actor.world.pos.z; + Math_ApproachS(&this->actor.shape.rot.x, + Math_Atan2S(temp, sqrtf(SQ(temp_fv1) + SQ(temp_ft4))) * (s32)this->unk1D8, 1, 0x800); + } else { + Math_ApproachS(&this->actor.shape.rot.x, 0, 1, 0x800); + } + } + if (this->unk14A[1] >= 0x78 && this->unk14A[1] < 0x8C) { + if (this->unk14A[1] == 0x78) { + D_809BEFE0 = NULL; + } else { + D_809BEFE0 = this; + } + } + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + Math_ApproachZeroF(&this->unk180, 1.0f, 10.0f); + if (this->unk1D8 > 0.0f) { + var_v0 = 0x14; + } else { + var_v0 = KREG(8) + 8; + } + if (var_v0 == this->unk14A[0]) { + Actor_PlaySfx(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + this->actor.flags &= ~1; + if (this->unk2A0 == 0xA) { + this->unk2A2 = 0; + } + } + if (this->unk14A[1] == 0 && D_809BEFD0->actionFunc != func_809B7950) { + this->actor.flags |= 1; + func_809B4BFC(this, play); + if (this == D_809BEFD0) { + this->actor.colChkInfo.health = 0xE - BREG(41); + } else { + this->actor.colChkInfo.health = 6 - BREG(40); + } + this->unk594.elements[0].info.bumperFlags &= ~2; + this->unk594.elements[1].info.bumperFlags &= ~2; + this->actor.colChkInfo.damageTable = &D_809BDB04; + this->unk156 = 0x19; + } +} + +void func_809B5634(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B5698; + this->unk14A[2] = 0x32; + this->unk2A1 = 0x14; + if (this == D_809BEFD0) { + Audio_RestorePrevBgm(); + } + Audio_PlaySfx_AtPos(&this->unk6C8, this->unk6C2); +} + +void func_809B5698(EnKnight* this, PlayState* play) { + Vec3f sp44; + Vec3f sp38; + s16 sp36; + + if (this->unk14A[2] >= 0xA && this->unk14A[2] < 0x28) { + if (this->unk14A[2] == 0xA) { + D_809BEFE0 = NULL; + } else { + D_809BEFE0 = this; + } + } + if (this->unk14A[2] == 0) { + this->unk152 = 0; + this->actor.draw = NULL; + this->actor.world.pos.y = 1000.0f; + this->actor.world.pos.x = 1300.0f; + this->actor.world.pos.z = 2864.0f; + this->actor.gravity = 0.0f; + } + Math_ApproachZeroF(&this->actor.scale.y, 0.1f, 0.0015f); + if (this->unk14A[2] != 0) { + sp36 = (s32)Rand_ZeroFloat(14.9f); + sp44 = D_809BDAF0; + sp44.y = 0.03f; + sp38.x = this->unk1DC[sp36].x + Rand_CenteredFloat(20.0f); + sp38.y = this->unk1DC[sp36].y - 5.0f; + sp38.z = this->unk1DC[sp36].z + Rand_CenteredFloat(20.0f); + EffectSsKFire_Spawn(play, &sp38, &D_809BDAF0, &sp44, Rand_ZeroFloat(20.0f) + 20.0f, 0); + Actor_PlaySfx(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + if (this->unk14A[2] == 0) { + this->actor.flags &= ~1; + if (this == D_809BEFD0) { + if (CutsceneManager_IsNext(this->actor.csId)) { + CutsceneManager_StartWithPlayerCs(this->actor.csId, &this->actor); + this->actionFunc = func_809B58D4; + } else { + CutsceneManager_Queue(this->actor.csId); + } + } else { + this->actionFunc = func_809B58D4; + } + func_800BC154(play, &play->actorCtx, &this->actor, 5); + this->unk14A[0] = 30; + } +} + +void func_809B58D4(EnKnight* this, PlayState* play) { + if (this == D_809BEFD0 && this->unk14A[0] == 0) { + Actor_Kill(&this->actor); + Actor_Kill(&D_809BEFD4->actor); + Actor_Kill(&D_809BEFD8->actor); + } +} + +void func_809B592C(EnKnight* this, PlayState* play) { + s32 var_s0; + Vec3f sp28; + + this->actionFunc = func_809B5B08; + Animation_MorphToPlayOnce(&this->unk194, &D_06002174, 0.0f); + Matrix_RotateYS(this->unk172, MTXMODE_NEW); + Matrix_MultVecZ(-15.0f, &sp28); + this->unk2A4 = sp28.x; + this->unk2A8 = sp28.z; + this->actor.velocity.y = 7.5f; + for (var_s0 = 0; var_s0 < 5; var_s0++) { + func_809B22CC(this, play, 0); + } + Actor_PlaySfx(&this->actor, NA_SE_EN_TEKU_JUMP); + this->unk148 = 0; + this->unk156 = 0xA; +} + +void func_809B59FC(EnKnight* this, PlayState* play) { + s32 var_s0; + Vec3f sp28; + + this->actionFunc = func_809B5B08; + Animation_MorphToPlayOnce(&this->unk194, &D_06002174, 0.0f); + Matrix_RotateYS(this->unk172, MTXMODE_NEW); + Matrix_MultVecZ(KREG(90) + 14.0f, &sp28); + this->unk2A4 = sp28.x; + this->unk2A8 = sp28.z; + this->actor.velocity.y = KREG(91) + 13.0f; + for (var_s0 = 0; var_s0 < 5; var_s0++) { + func_809B22CC(this, play, 0); + } + Actor_PlaySfx(&this->actor, NA_SE_EN_MIBOSS_JUMP1); + this->unk148 = 1; + this->unk156 = 0x14; +} + +void func_809B5B08(EnKnight* this, PlayState* play) { + if (this->unk148 == 1) { + Actor_PlaySfx(&this->actor, NA_SE_EN_MIBOSS_JUMP2 - SFX_FLAG); + } + + SkelAnime_Update(&this->unk194); + this->actor.speed = 0.0f; + + if (this == D_809BEFD0) { + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0x1000); + if (this->unk156 == 0xD) { + if (this->unk148 == 1) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_LAUGH_DEMO); + } else { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_CYNICAL); + } + } + } + + if (this->actor.velocity.y <= 0.0f && (this->actor.bgCheckFlags & 1)) { + this->unk2A4 = this->unk2A8 = 0.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + if (this->unk148 == 1) { + if (this->unk162 != 0) { + if (Rand_ZeroOne() < 0.5f) { + func_809B3A7C(this, play); + } else { + func_809B329C(this, play, 0); + } + } else if (Rand_ZeroOne() < 0.5f) { + func_809B3A7C(this, play); + } else { + func_809B6EC8(this, play); + } + } else if (this == D_809BEFD0 && Rand_ZeroOne() < 0.3f) { + if (Rand_ZeroOne() < 0.5f || this->unk162 != 0) { + func_809B3A7C(this, play); + } else { + func_809B6EC8(this, play); + } + } else { + func_809B3E9C(this, play); + } + } +} + +void func_809B5D38(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B5D54; + this->unk148 = 0; +} + +void func_809B5D54(EnKnight* this, PlayState* play) { + this->unk_680 = 1; + if (this->unk148 != 0) { + SkelAnime_Update(&this->unk194); + } + switch (this->unk148) { + case 0: + break; + case 1: + if (this->unk290 == 0) { + Animation_MorphToPlayOnce(&this->unk194, &D_060009E0, 0.0f); + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_060005A8, 0.0f); + } + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_STAND); + this->unk290 = 1 - this->unk290; + this->unk148 = 2; + this->unk14A[0] = 2; + /* fallthrough */ + case 2: + if (this->unk14A[0] == 1) { + if (this->unk290 == 0) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SHOCK); + } else { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SHIT); + } + } + if (this->unk_151 == 0) { + func_809B6528(this, play); + this->unk194.curFrame = 25.0f; + } + break; + } + this->unk18A = 0; + this->unk184 = this->unk186 = this->unk188 = this->unk18A; +} + +void func_809B5E90(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B5ED0; + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); +} + +void func_809B5ED0(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + + if (D_809BEFE0 == NULL) { + func_809B3E9C(this, play); + } else { + f32 dx = D_809BEFE0->actor.focus.pos.x - this->actor.world.pos.x; + f32 dz = D_809BEFE0->actor.focus.pos.z - this->actor.world.pos.z; + s16 temp_v1 = Math_Atan2S_XY(dz, dx) - this->actor.shape.rot.y; + + if (temp_v1 > 0x3800) { + this->unk186 = 0x3800; + } else if (temp_v1 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v1; + } + this->unk18C = 0x3000; + this->unk18E = 2; + } +} + +void func_809B5FA8(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B601C; + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + this->unk148 = 0; + this->unk14A[0] = Rand_ZeroFloat(10.0f) + 65.0f; +} + +void func_809B601C(EnKnight* this, PlayState* play) { + f32 dx; + f32 dz; + s16 temp_v1_2; + EnKnight* var_t0; + Player* sp2C = GET_PLAYER(play); + + SkelAnime_Update(&this->unk194); + + var_t0 = (this == D_809BEFD4) ? D_809BEFD8 : D_809BEFD4; + + switch (this->unk148) { + case 0: + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 2, 0x500); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] < 0x28 && this->unk14A[0] >= 0x10) { + dx = var_t0->actor.focus.pos.x - this->actor.world.pos.x; + dz = var_t0->actor.focus.pos.z - this->actor.world.pos.z; + temp_v1_2 = Math_Atan2S_XY(dz, dx) - this->actor.shape.rot.y; + + if (temp_v1_2 > 0x3800) { + this->unk186 = 0x3800; + } else if (temp_v1_2 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v1_2; + } + + this->unk18C = 0x3000; + this->unk18E = 2; + } else { + this->unk186 = 0; + } + + if (this->unk14A[0] == 0 && func_801A46F8() == 1) { + Animation_MorphToLoop(&this->unk194, &D_0600DDCC, -3.0f); + this->unk148 = 1; + this->unk14A[0] = 0xC8; + } + + if (!(sp2C->stateFlags3 & PLAYER_STATE3_20000000)) { + this->unk148 = 2; + this->unk14A[0] = 0xA; + } + break; + case 1: + this->actor.speed = KREG(38) + 1.0f; + + if (this == D_809BEFD4) { + this->actor.world.rot.y = (this->actor.world.rot.y + KREG(39) * 0x100) + 0x100; + } else { + this->actor.world.rot.y = (this->actor.world.rot.y - KREG(39) * 0x100) - 0x100; + } + + if (this->unk14A[0] == 0 || !(sp2C->stateFlags3 & PLAYER_STATE3_20000000)) { + this->unk148 = 2; + this->unk14A[0] = 0xA; + } + goto block_29; + case 2: + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + } + goto block_29; + + block_29: + if (Animation_OnFrame(&this->unk194, KREG(53) + 1.0f) || + Animation_OnFrame(&this->unk194, KREG(54) + 11.0f)) { + Actor_PlaySfx(&this->actor, this->unk6B4); + } + break; + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 5, 0x500); +} + +void func_809B631C(EnKnight* this, PlayState* play) { + if (this == D_809BEFD0) { + this->actionFunc = func_809B8458; + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + } else { + this->actionFunc = func_809B842C; + } + this->actor.world.pos.y = 1000.0f; +} + +void func_809B638C(EnKnight* this, PlayState* play, s16 arg2) { + Vec3f sp4C; + Vec3f sp40; + Vec3f sp34; + s16 var_a1; + + Math_Vec3f_Copy(&sp4C, &this->unk434); + Matrix_RotateYS(this->unk184 + this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x + arg2, MTXMODE_APPLY); + Matrix_MultVecZ(BREG(48) + 20.0f, &sp40); + var_a1 = (this->unk14A[0] < 0x28) ? 0 : 0xC8; + Math_ApproachS(&this->unk160, var_a1, 1, 5); + if (this->unk160 >= 0x3D) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_FREEZAD_BREATH - SFX_FLAG); + } + sp34.x = sp34.y = sp34.z = 0.0f; + func_809B20F0(play, &sp4C, &sp40, &sp34, 2.0f, 25.0f, this->unk160); + sp4C.x -= sp40.x * 0.5f; + sp4C.y -= sp40.y * 0.5f; + sp4C.z -= sp40.z * 0.5f; + func_809B20F0(play, &sp4C, &sp40, &sp34, 2.0f, 25.0f, this->unk160); +} + +void func_809B6528(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600A530, -5.0f); + this->actionFunc = func_809B6764; + this->unk148 = 0; +} + +void func_809B6574(PlayState* play, u8 arg1) { + Player* player = GET_PLAYER(play); + Vec3f spB0; + Vec3f spA4; + Vec3f sp98; + u8 var_s1; + + for (var_s1 = 0; var_s1 < arg1; var_s1++) { + spA4.x = Rand_CenteredFloat(3.0f); + spA4.y = Rand_ZeroFloat(2.0f) + 1.0f; + spA4.z = Rand_CenteredFloat(3.0f); + sp98.x = sp98.z = 0.0f; + sp98.y = -0.1f; + spB0.x = player->actor.world.pos.x + Rand_CenteredFloat(30.0f); + spB0.y = player->actor.world.pos.y + 20.0f + Rand_CenteredFloat(30.0f); + spB0.z = player->actor.world.pos.z + Rand_CenteredFloat(30.0f); + func_800B0EB0(play, &spB0, &spA4, &sp98, &D_809BDCF0, &D_809BDCF4, Rand_ZeroFloat(50.0f) + 100.0f, 0xA, + Rand_ZeroFloat(5.0f) + 14.0f); + } +} + +void func_809B6764(EnKnight* this, PlayState* play) { + s16 temp_v1; + s16 sp54 = 0; + Player* player = GET_PLAYER(play); + Vec3f sp44; + Vec3f sp38; + + SkelAnime_Update(&this->unk194); + + temp_v1 = this->unk172 - this->actor.shape.rot.y; + if (temp_v1 > 0x3800) { + this->unk186 = 0x3800; + } else if (temp_v1 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v1; + } + + switch (this->unk148) { + case 0: + if (this->actor.xzDistToPlayer < 35.0f) { + if (player->actor.world.pos.z < this->actor.world.pos.z) { + this->unk148 = 1; + } else { + this->unk148 = 5; + } + this->unk14A[0] = 8; + Actor_PlaySfx(&this->actor, this->unk6BC); + } + if (player->unk_D57 == 4 && func_809B31E8(this, play) != 0) { + this->unk148 = 0xA; + Animation_MorphToPlayOnce(&this->unk194, &D_06008524, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06008524); + } + break; + case 1: + if (this->unk14A[0] == 0) { + this->unk148++; + this->unk14A[0] = 0x14; + } else { + Math_ApproachS(&this->unk17A, 0x3C00, 1, 0x1770); + Math_ApproachS(&this->unk176, 0x1400, 1, 0x1770); + if (this->unk14A[0] == 7) { + sp54 = -0x2000; + } + break; + } + case 2: + Math_ApproachS(&this->unk17A, 0, 1, 0xBB8); + Math_ApproachS(&this->unk176, 0, 1, 0xBB8); + if (this->unk14A[0] == 0) { + this->unk148 = 0; + } + break; + case 5: + if (this->unk14A[0] == 0) { + this->unk148++; + this->unk14A[0] = 0x14; + } else { + Math_ApproachS(&this->unk178, 0x3C00, 1, 0x1770); + Math_ApproachS(&this->unk174, 0x1400, 1, 0x1770); + if (this->unk14A[0] == 7) { + sp54 = 0x2000; + } + break; + } + case 6: + Math_ApproachS(&this->unk178, 0, 1, 0xBB8); + Math_ApproachS(&this->unk174, 0, 1, 0xBB8); + if (this->unk14A[0] == 0) { + this->unk148 = 0; + } + break; + case 10: + if (Animation_OnFrame(&this->unk194, this->unk1D8) != 0) { + this->unk148 = 0xB; + Animation_MorphToPlayOnce(&this->unk194, &D_060089E4, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_060089E4); + } + break; + case 11: + if (Animation_OnFrame(&this->unk194, this->unk1D8) != 0) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600A530, -15.0f); + this->unk148 = 0; + } + break; + } + + if (this->unk148 >= 0xA) { + sp44.x = this->actor.world.pos.x + 40.0f; + sp44.y = this->actor.world.pos.y + 70.0f; + sp44.z = this->actor.world.pos.z; + func_809B21F4(this, 0, &this->unk534, &sp44); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk534.base); + } + + if (D_809BEFD4->actor.draw == NULL && D_809BEFD8->actor.draw == NULL) { + func_809B7190(this, play); + this->unk17A = this->unk178 = this->unk176 = this->unk174 = 0; + } + + if (sp54 != 0) { + Math_Vec3f_Copy(&sp38, &player->actor.world.pos); + sp38.y += 25.0f; + EffectSsHitmark_SpawnFixedScale(play, 0, &sp38); + func_800B8D50(play, NULL, KREG(53) + 12.0f, this->actor.shape.rot.y + sp54, KREG(54) + 7.0f, 0x10); + func_809B6574(play, 0xC); + Actor_PlaySfx(&this->actor, NA_SE_EV_BLOCK_SHAKE); + } +} + +void func_809B6C04(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_06003008, -5.0f); + this->actionFunc = func_809B6C54; + this->unk14A[0] = 0x32; +} + +void func_809B6C54(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); + if (Animation_OnFrame(&this->unk194, 19.0f)) { + this->unk162 = 1; + D_809BEFDC = (EnKnight*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KNIGHT, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, 0x64); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HEAD_SHORT); + } + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + if (this->unk14A[0] == 0) { + func_809B3E9C(this, play); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_LAUGH_DEMO); + } +} + +void func_809B6D38(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_060079D4, -10.0f); + this->actionFunc = func_809B6D94; + this->unk148 = 0; + this->unk14A[0] = 0x3C; + this->unk194.playSpeed = 0.0f; +} + +void func_809B6D94(EnKnight* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + this->unk156 = 5; + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + + switch (this->unk148) { + case 1: + this->unk148 = 2; + this->unk14A[0] = 0x28; + this->unk194.playSpeed = 1.0f; + /* fallthrough */ + case 2: + if (this->unk14A[0] == 0x22) { + this->unk162 = 0; + Actor_Kill(&D_809BEFDC->actor); + D_809BEFDC = NULL; + this->actor.flags |= 1; + player->lockOnActor = &this->actor; + play->actorCtx.targetCtx.fairyActor = &this->actor; + play->actorCtx.targetCtx.lockOnActor = &this->actor; + } + if (this->unk14A[0] == 0xF) { + func_809B3E9C(this, play); + this->unk14A[2] = Rand_ZeroFloat(100.0f) + 150.0f; + } + /* fallthrough */ + case 0: + return; + } +} + +void func_809B6EC8(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_06009538, -5.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06009538); + this->actionFunc = func_809B6F40; + this->unk148 = 0; + this->unk14A[0] = KREG(57) + 0x96; + this->unk160 = 0; +} + +void func_809B6F40(EnKnight* this, PlayState* play) { + s16 temp_v0; + + SkelAnime_Update(&this->unk194); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + Math_ApproachS(&this->actor.world.rot.y, this->unk172, 5, 0x500); + + temp_v0 = this->unk172 - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x6000) { + if (temp_v0 > 0x3800) { + this->unk186 = 0x3800; + } else if (temp_v0 < -0x3800) { + this->unk186 = -0x3800; + } else { + this->unk186 = temp_v0; + } + } + + switch (this->unk148) { + case 0: + if (Animation_OnFrame(&this->unk194, this->unk1D8) != 0) { + this->unk148 = 1; + Animation_MorphToLoop(&this->unk194, &D_06008D80, 0.0f); + } + func_809B638C(this, play, 0x1600); + break; + case 1: + func_809B638C(this, play, 0x1600); + if (KREG(21) == 0) { + this->unk186 = + Math_SinS((KREG(84) + 0x11DC) * this->unk146) * (KREG(85) * 0x800 + 0x1800) + this->unk186; + } + if (this->unk14A[0] == 0) { + this->unk148 = 2; + Animation_MorphToPlayOnce(&this->unk194, &D_0600E15C, -5.0f); + this->unk1D8 = Animation_GetLastFrame(&D_0600E15C); + } + break; + case 2: + func_809B638C(this, play, 0x1600); + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + func_809B3E9C(this, play); + this->unk14A[2] = Rand_ZeroFloat(150.0f) + 150.0f; + } + break; + } + + this->unk192 = 1; +} + +void func_809B7190(EnKnight* this, PlayState* play) { + this->actionFunc = func_809B71DC; + this->unk684 = 0; + this->unk688 = 0; + this->unk6A4 = 0.0f; + AudioSeq_QueueSeqCmd(0x101400FF); +} + +void func_809B71DC(EnKnight* this, PlayState* play) { + f32 temp_fa0; + Camera* sp30; + f32 temp_fv0; + + this->unk684++; + SkelAnime_Update(&this->unk194); + + switch (this->unk688) { + case 0: + if (CutsceneManager_GetCurrentCsId() != -1) { + break; + } + Cutscene_StartManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 7); + this->unk_68A = Play_CreateSubCamera(play); + Play_ChangeCameraStatus(play, 0, 1); + Play_ChangeCameraStatus(play, this->unk_68A, 7); + this->actor.flags &= ~1; + this->unk684 = 0; + this->unk688 = 1; + this->unk68C.x = 1342.0f; + this->unk68C.y = 56.0f; + this->unk68C.z = 2810.0f; + this->unk698.x = 1400.0f; + this->unk698.y = 57.0f; + this->unk698.z = 2870.0f; + this->unk6B0 = 60.0f; + /* Fallthrough */ + case 1: + if (this->unk684 == (u32)(sREG(64) + 0xD)) { + Animation_MorphToPlayOnce(&this->unk194, &D_06009D8C, sREG(65)); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_STAND); + } + if (this->unk684 != (u32)(sREG(66) + 0x17)) { + break; + } + this->unk68C.x = 1253.0f; + this->unk68C.y = 79.0f; + this->unk68C.z = 2903.0f; + this->unk698.x = 1354.0f; + this->unk698.y = 83.0f; + this->unk698.z = 2865.0f; + Animation_MorphToPlayOnce(&this->unk194, &D_06009D8C, 0.0f); + this->unk684 = 0; + this->unk688 = 2; + /* Fallthrough */ + case 2: + this->unk6A4 = sREG(67) * 0.001f + 0.05f; + Math_ApproachF(&this->unk698.y, 119.0f, 0.2f, this->unk6A4 * 36.0f); + if (this->unk684 >= (u32)(sREG(68) + 0xA)) { + if (this->unk684 == (u32)(sREG(68) + 0xA)) { + this->unk14A[1] = 0x11; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SWORD); + } + + temp_fv0 = Math_SinS(this->unk14A[1] * 0x6000); + temp_fa0 = (temp_fv0 * this->unk14A[1] * 0.0175f) + (this->unk14A[1] * 0.0175f) + 1.0f; + + Math_ApproachF(&this->unk46C, temp_fa0, 1.0f, 0.5f); + Math_ApproachF(&this->unk470, temp_fa0, 1.0f, 0.5f); + } + if (this->unk684 == (u32)(sREG(69) + 0x32)) { + Animation_MorphToPlayOnce(&this->unk194, &D_06008390, sREG(65) + -10.0f); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_ATTACK_K); + } + if (this->unk684 >= (u32)(sREG(69) + 0x32)) { + Math_ApproachF(&this->unk6B0, sREG(70) + 40.0f, 0.2f, sREG(71) * 0.1f + 3.0f); + } + if (this->unk684 >= (u32)(sREG(72) + 0x5A)) { + sp30 = Play_GetCamera(play, 0); + this->unk688 = 0; + func_809B3E9C(this, play); + this->unk14A[2] = 0x12C; + this->unk152 = 1; + this->actor.flags |= 1; + this->actor.gravity = -1.5f; + sp30->eye = this->unk68C; + sp30->eyeNext = this->unk68C; + sp30->at = this->unk698; + func_80169AFC(play, this->unk_68A, 0); + this->unk_68A = 0; + Cutscene_StopManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 6); + D_809BDB00 = 1; + } + break; + } + + if (this->unk_68A != 0) { + ShrinkWindow_Letterbox_SetSizeTarget(27); + Play_SetCameraAtEye(play, this->unk_68A, &this->unk698, &this->unk68C); + Play_SetCameraFov(play, this->unk_68A, this->unk6B0); + } +} + +void func_809B7708(EnKnight* this, PlayState* play) { + if (this->actionFunc != func_809B52E8 && this->actionFunc != func_809B5698 && this->actionFunc != func_809B58D4) { + Animation_MorphToLoop(&this->unk194, &D_060040E0, -5.0f); + this->actionFunc = func_809B7778; + } +} + +void func_809B7778(EnKnight* this, PlayState* play) { + Vec3f sp2C; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->unk194); + this->unk186 = 0; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.speed = 0.0f; + if (D_809BEFD0->unk148 == 0) { + if (this == D_809BEFD4) { + Matrix_RotateYS(D_809BEFD0->actor.shape.rot.y + 0x1400, MTXMODE_NEW); + } else { + Matrix_RotateYS(D_809BEFD0->actor.shape.rot.y - 0x1400, MTXMODE_NEW); + } + Matrix_MultVecZ((KREG(19) + 350.0f) - 220.0f, &sp2C); + this->actor.world.pos.x = player->actor.world.pos.x + sp2C.x; + this->actor.world.pos.z = player->actor.world.pos.z + sp2C.z; + } + if (D_809BEFD0->actionFunc != func_809B7950) { + func_809B3E9C(this, play); + } +} + +void func_809B78A4(EnKnight* this, PlayState* play) { + this->unk684 = 0; + this->unk688 = 0; + this->unk6A4 = 0.0f; + AudioSeq_QueueSeqCmd(0x100A00FF); + if (this->actionFunc != func_809B6764) { + this->unk148 = 1; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + } else { + this->unk148 = 0; + } + func_809B7708(D_809BEFD4, play); + func_809B7708(D_809BEFD8, play); + this->unk424 = this->actionFunc; + this->actionFunc = func_809B7950; +} + +void func_809B7950(EnKnight* this, PlayState* play) { + Vec3f sp44; + Player* sp40 = GET_PLAYER(play); + Camera* var_v1; + s32 pad; + + this->unk186 = 0; + this->actor.speed = 0.0f; + this->unk684 += 1; + this->unk2A4 = 0.0f; + this->unk2A8 = 0.0f; + + SkelAnime_Update(&this->unk194); + + switch (this->unk688) { + case 0: + if (CutsceneManager_GetCurrentCsId() == -1) { + Cutscene_StartManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 7); + this->unk_68A = Play_CreateSubCamera(play); + Play_ChangeCameraStatus(play, 0, 1); + Play_ChangeCameraStatus(play, this->unk_68A, 7); + this->actor.flags &= ~1; + this->unk684 = 0; + this->unk688 = 1; + this->unk6B0 = 60.0f; + if (this->unk424 == func_809B6764) { + Animation_MorphToPlayOnce(&this->unk194, &D_0600EA90, 0.0f); + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_0600E7F4, 0.0f); + } + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_STAND); + case 1: + Matrix_RotateYS(KREG(29) + this->actor.shape.rot.y + 0x1B58, MTXMODE_NEW); + Matrix_MultVecZ(KREG(16) + 90.0f, &sp44); + + this->unk68C.x = this->actor.world.pos.x + sp44.x; + this->unk68C.y = this->actor.world.pos.y + KREG(17) + 40.0f; + this->unk68C.z = this->actor.world.pos.z + sp44.z; + + this->unk698.x = this->actor.focus.pos.x; + this->unk698.y = this->actor.focus.pos.y + KREG(18) - 10.0f; + this->unk698.z = this->actor.focus.pos.z; + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + + sp40->actor.world.rot.y = sp40->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000; + + Matrix_MultVecZ((KREG(19) + 350.0f) - 220.0f, &sp44); + + sp40->actor.world.pos.x = this->actor.world.pos.x + sp44.x; + sp40->actor.world.pos.z = this->actor.world.pos.z + sp44.z; + + if (this->unk684 == (u32)(KREG(31) + 0x19)) { + this->unk688 = 2; + this->unk684 = 0; + this->unk6A4 = KREG(20) + 80.0f; + } + } + break; + case 2: + Matrix_RotateYS(sp40->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(KREG(26) - 0x7D0, MTXMODE_APPLY); + Matrix_MultVecZ(this->unk6A4, &sp44); + if (this->unk684 >= 0x1A) { + Math_ApproachF(&this->unk6A4, 40.0f, 0.2f, 2.0f); + } + + this->unk68C.x = sp40->actor.world.pos.x + sp44.x; + this->unk68C.y = KREG(21) + (sp40->actor.world.pos.y + sp44.y) + 44.0f; + this->unk68C.z = sp40->actor.world.pos.z + sp44.z; + + this->unk698.x = sp40->actor.world.pos.x; + this->unk698.y = (sp40->actor.world.pos.y + KREG(22) + 44.0f) - 5.0f; + this->unk698.z = sp40->actor.world.pos.z; + + if (this->unk684 == (u32)(KREG(48) + 0x55)) { + this->unk688 = 3; + this->unk684 = 0; + this->unk1D8 = 1000.0f; + } + break; + case 3: + if (this->unk684 == 7) { + if (this->unk424 == func_809B6764) { + Animation_MorphToPlayOnce(&this->unk194, &D_06006EF8, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06006EF8); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_STAND_RAPID); + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_06006754, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06006754); + } + Message_StartTextbox(play, 0x153E, NULL); + } + + Matrix_RotateYS(KREG(29) + this->actor.shape.rot.y + 0x1B58, MTXMODE_NEW); + Matrix_MultVecZ(KREG(16) + 90.0f, &sp44); + + this->unk68C.x = this->actor.world.pos.x + sp44.x; + this->unk68C.y = this->actor.world.pos.y + KREG(17) + 40.0f; + this->unk68C.z = this->actor.world.pos.z + sp44.z; + + if (this->unk684 < (u32)(KREG(24) + 0x23)) { + this->unk698.x = this->actor.focus.pos.x; + this->unk698.y = this->actor.focus.pos.y + KREG(18) - 10.0f; + this->unk698.z = this->actor.focus.pos.z; + } + + if (Animation_OnFrame(&this->unk194, this->unk1D8) != 0) { + Animation_MorphToLoop(&this->unk194, &D_0600C7F0, 0.0f); + this->unk1D8 = 1000.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HAND); + } + + if (this->unk684 == (u32)(KREG(25) + 0x78)) { + this->unk688 = 4; + this->unk684 = 0; + Animation_MorphToPlayOnce(&this->unk194, &D_0600C7F0, 0.0f); + } + break; + case 4: + Matrix_RotateYS(KREG(29) * 0x100 + this->actor.shape.rot.y + 0x2400, MTXMODE_NEW); + Matrix_MultVecZ(KREG(16) + 230.0f, &sp44); + + this->unk68C.x = this->actor.world.pos.x + sp44.x; + this->unk68C.y = this->actor.world.pos.y + KREG(17) + 40.0f; + this->unk68C.z = this->actor.world.pos.z + sp44.z; + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(KREG(49) + 65.0f, &sp44); + + this->unk698.x = this->actor.world.pos.x + sp44.x; + this->unk698.y = (this->actor.world.pos.y + KREG(50) + 50.0f) - 20.0f; + this->unk698.z = this->actor.world.pos.z + sp44.z; + + if (this->unk684 == 0x3C) { + Message_StartTextbox(play, 0x153FU, NULL); + } + if (this->unk684 == (u32)(BREG(16) + 0x78)) { + Message_CloseTextbox(play); + } + if (this->unk684 == (u32)(BREG(17) + 0xA0)) { + Message_StartTextbox(play, 0x1542, NULL); + Animation_MorphToLoop(&this->unk194, &D_0600A88C, 0.0f); + } + if (this->unk684 == (u32)(BREG(18) + 0xAA)) { + func_800B7298(play, &this->actor, 4); + } + if ((this->unk684 >= 0x9D) && (this->unk684 < 0xDD)) { + if (!(this->unk684 & 1)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_WALK); + } + if (!(this->unk684 & 3)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SIT); + } + } + if (this->unk684 == (u32)(BREG(19) + 0xDC)) { + Animation_MorphToPlayOnce(&this->unk194, &D_06021E34, -3.0f); + } + if (this->unk684 == (u32)(BREG(20) + 0xE6)) { + Message_StartTextbox(play, 0x1540, NULL); + } + if (this->unk684 == (u32)(BREG(20) + 0xF0)) { + Animation_MorphToLoop(&this->unk194, &D_06005E78, 0.0f); + } + + if (this->unk684 == (u32)(BREG(21) + 0x140)) { + if (this->unk424 == func_809B6764) { + Animation_MorphToPlayOnce(&this->unk194, &D_0601024C, 0.0f); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SIT); + } else { + Animation_MorphToPlayOnce(&this->unk194, &D_0602105C, 0.0f); + } + Message_CloseTextbox(play); + } + + if (this->unk684 >= (u32)(BREG(22) + 0x154)) { + var_v1 = Play_GetCamera(play, 0); + + this->unk688 = 0; + if (this->unk424 == func_809B6764) { + func_809B6528(this, play); + this->unk194.curFrame = 25.0f; + } else { + func_809B3E9C(this, play); + this->actor.flags |= 1; + } + + var_v1->eye = this->unk68C; + var_v1->eyeNext = this->unk68C; + var_v1->at = this->unk698; + + func_80169AFC(play, this->unk_68A, 0); + this->unk_68A = 0; + Cutscene_StopManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 6); + D_809BDB00 = 5; + } + break; + } + + if (this->unk_68A != 0) { + ShrinkWindow_Letterbox_SetSizeTarget(27); + Play_SetCameraAtEye(play, this->unk_68A, &this->unk698, &this->unk68C); + Play_SetCameraFov(play, this->unk_68A, this->unk6B0); + } +} + +void func_809B842C(EnKnight* this, PlayState* play) { + SkelAnime_Update(&this->unk194); +} + +void func_809B8458(EnKnight* this, PlayState* play) { + f32 sp64 = 0.0f; + Player* sp60 = GET_PLAYER(play); + Camera* temp_v0_2; + Vec3f sp50; + Vec3f sp44; + f32 temp_fv1; + + this->unk684++; + SkelAnime_Update(&this->unk194); + + switch (this->unk688) { + case 0: + if (Flags_GetClear(play, play->roomCtx.curRoom.num) || (CutsceneManager_GetCurrentCsId() != -1) || + !(sp60->actor.world.pos.x >= 870.0f)) { + break; + } + + Cutscene_StartManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 7); + this->unk_68A = Play_CreateSubCamera(play); + Play_ChangeCameraStatus(play, 0, 1); + Play_ChangeCameraStatus(play, this->unk_68A, 7); + this->actor.flags &= ~1; + this->unk684 = 0; + this->unk688 = 1; + this->unk6B0 = 60.0f; + this->unk68C.x = 621.0f; + this->unk68C.y = 54.0f; + this->unk68C.z = 2865.0f; + this->unk698.x = 661.0f; + this->unk698.y = 110.0f; + this->unk698.z = 2939.0f; + AudioSeq_QueueSeqCmd(0x105000FF); + /* Fallthrough */ + case 1: + sp60->actor.world.pos.x = 870.0f; + sp60->actor.world.pos.z = 2865.0f; + this->unk6AC = 0x4000; + this->unk68C.x = sp60->actor.world.pos.x + BREG(16) + 100.0f; + this->unk68C.y = sp60->actor.world.pos.y + BREG(17) + 20.0f; + this->unk68C.z = sp60->actor.world.pos.z + BREG(18); + this->unk698.x = sp60->actor.world.pos.x + BREG(19); + this->unk698.y = sp60->actor.world.pos.y + BREG(20) + 40.0f; + this->unk698.z = sp60->actor.world.pos.z + BREG(21); + + if (this->unk684 >= (u32)(BREG(22) + 0x14)) { + sp64 = 0.5f; + Audio_PlaySfx(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + } + + if (this->unk684 == (u32)(BREG(22) + 0x1E)) { + func_800B7298(play, &this->actor, 0x15); + } + + if (this->unk684 == (u32)(BREG(22) + 0x32)) { + Message_StartTextbox(play, 0x1518, NULL); + } + + if (this->unk684 != (u32)(BREG(23) + 0x96)) { + break; + } + + Message_CloseTextbox(play); + + this->unk688 = 2; + this->unk684 = 0; + this->unk_153 = 1; + play->envCtx.lightSettingOverride = 1; + play->envCtx.lightBlendOverride = 0; + D_809BEFD0->unk_154 = 0; + /* Fallthrough */ + case 2: + this->unk_144 = 0x8000; + + if (this->unk684 == 10) { + func_800B7298(play, &this->actor, 4); + } + + if (this->unk684 >= 10) { + Math_ApproachS(&this->unk6AC, 0, 2, 0x1000); + } + + this->unk68C.x = 896.0f; + this->unk68C.y = 4.0f; + this->unk68C.z = 2752.0f; + this->unk698.x = 894.0f; + this->unk698.y = 46.0f; + this->unk698.z = 2860.0f; + + if (this->unk684 == (u32)(BREG(65) + 0x28)) { + Message_StartTextbox(play, 0x1519, NULL); + } + if ((u32)(BREG(94) + 0x82) >= this->unk684) { + sp64 = 0.5f; + Audio_PlaySfx(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + } + if (this->unk684 == (u32)(BREG(65) + 0x8C)) { + Message_CloseTextbox(play); + } + if (this->unk684 == (u32)(BREG(65) + 0xAA)) { + Message_StartTextbox(play, 0x151AU, NULL); + } + if ((this->unk684 >= 0xAA) && (this->unk684 < 0xBF)) { + this->unk430 = KREG(42) + 200.0f; + } + if ((this->unk684 == 150) || (this->unk684 == 180)) { + Actor_PlaySfx(&this->actor, this->unk6B4); + } + + if (this->unk684 != (u32)(BREG(24) + 0xBE)) { + break; + } + + this->unk688 = 3; + this->unk684 = 0; + func_800B7298(play, &this->actor, 0x85); + /* Fallthrough */ + case 3: + Math_ApproachS(&this->unk6AC, 0x4000, 2, 0x1000); + if (this->unk684 != (u32)(BREG(26) + 0xF)) { + break; + } + this->unk688 = 4; + this->unk684 = 0; + Animation_MorphToPlayOnce(&this->unk194, &D_06010E98, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06010E98); + /* Fallthrough */ + case 4: + this->unk6A4 = BREG(29) * 0.01f + 0.1f; + Math_ApproachF(&this->unk68C.x, 1076.0f, 0.5f, this->unk6A4 * 180.0f); + Math_ApproachF(&this->unk68C.y, 20.0f, 0.5f, this->unk6A4 * 16.0f); + Math_ApproachF(&this->unk68C.z, 2741.0f, 0.5f, this->unk6A4 * 11.0f); + Math_ApproachF(&this->unk698.x, 1155.0f, 0.5f, this->unk6A4 * 261.0f); + Math_ApproachF(&this->unk698.y, 50.0f, 0.5f, this->unk6A4 * 4.0f); + Math_ApproachF(&this->unk698.z, 2822.0f, 0.5f, this->unk6A4 * 38.0f); + + this->actor.world.pos.x = BREG(27) + 1376.0f; + this->actor.world.pos.y = 45.0f; + this->actor.world.pos.z = BREG(28) + 2864.0f; + + if (this->unk684 != (u32)(BREG(29) + 0x14)) { + break; + } + + this->unk688 = 5; + this->unk684 = 0; + Animation_MorphToLoop(&D_809BEFD8->unk194, &D_06021B10, 0.0f); + D_809BEFD8->actor.world.pos.x = BREG(30) + 1363.0f + 120.0f; + Message_StartTextbox(play, 0x1533, NULL); + this->unk6B0 = 30.0f; + play->envCtx.lightSettingOverride = 2; + /* Fallthrough */ + case 5: + if (this->unk684 == (u32)(BREG(71) + 2)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_SIT); + } + if ((this->unk684 == (u32)(BREG(72) + 0xA)) || (this->unk684 == (u32)(BREG(73) + 0x19)) || + (this->unk684 == (u32)(BREG(74) + 0x28))) { + Actor_PlaySfx(&D_809BEFD8->actor, D_809BEFD8->unk6B4); + } + if ((this->unk684 >= 9) && (this->unk684 < 0x2C)) { + this->unk430 = KREG(42) + 200.0f; + } + if (Animation_OnFrame(&this->unk194, this->unk1D8)) { + Animation_MorphToLoop(&this->unk194, &D_0600FC78, 0.0f); + this->unk1D8 = 1000.0f; + } + this->unk68C.x = 1349.0f; + this->unk68C.y = 126.0f; + this->unk68C.z = 2740.0f; + this->unk698.x = 1377.0f; + this->unk698.y = 121.0f; + this->unk698.z = 2851.0f; + Math_ApproachF(&D_809BEFD8->actor.world.pos.x, BREG(30) + 1363.0f + 30.0f, 1.0f, BREG(32) + 2.0f); + D_809BEFD8->actor.world.pos.y = 45.0f; + D_809BEFD8->actor.world.pos.z = BREG(31) + 2864.0f + 60.0f; + if (this->unk684 == (u32)(BREG(35) + 0x2D)) { + Animation_MorphToPlayOnce(&D_809BEFD8->unk194, &D_0600D870, -10.0f); + Actor_PlaySfx(&D_809BEFD8->actor, NA_SE_EN_DEBU_PAUSE_K); + } + if (this->unk684 != (u32)(BREG(33) + 0x50)) { + break; + } + this->unk688 = 6; + this->unk684 = 0; + Animation_MorphToLoop(&D_809BEFD4->unk194, &D_06021B10, 0.0f); + D_809BEFD4->actor.world.pos.x = BREG(30) + 1363.0f + 120.0f; + D_809BEFD8->actor.world.pos.z = 3164.0f; + Message_StartTextbox(play, 0x151B, NULL); + play->envCtx.lightSettingOverride = 3; + /* Fallthrough */ + case 6: + if ((this->unk684 == (u32)(BREG(72) + 0xA)) || (this->unk684 == (u32)(BREG(73) + 0x19)) || + (this->unk684 == (u32)(BREG(74) + 0x28))) { + Actor_PlaySfx(&D_809BEFD4->actor, D_809BEFD4->unk6B4); + } + if ((this->unk684 >= 0xA) && (this->unk684 < 0x22)) { + this->unk430 = KREG(42) + 200.0f; + } + this->unk68C.x = 1343.0f; + this->unk68C.y = 146.0f; + this->unk68C.z = 2975.0f; + this->unk698.x = 1372.0f; + this->unk698.y = 122.0f; + this->unk698.z = 2867.0f; + Math_ApproachF(&D_809BEFD4->actor.world.pos.x, BREG(30) + 1363.0f + 30.0f, 1.0f, BREG(32) + 2.0f); + D_809BEFD4->actor.world.pos.y = 45.0f; + D_809BEFD4->actor.world.pos.z = (BREG(31) + 2864.0f) - 60.0f; + if (this->unk684 == (u32)(BREG(35) + 0x2D)) { + Animation_MorphToPlayOnce(&D_809BEFD4->unk194, &D_0600D870, -10.0f); + Actor_PlaySfx(&D_809BEFD4->actor, NA_SE_EN_YASE_PAUSE_K); + } + if (this->unk684 != (u32)(BREG(33) + 0x50)) { + break; + } + this->unk688 = 7; + this->unk684 = 0; + D_809BEFD4->actor.world.pos.z = ((BREG(31) + 2864.0f) - 60.0f) - 10.0f; + D_809BEFD8->actor.world.pos.z = BREG(31) + 2864.0f + 60.0f + 10.0f; + D_809BEFD4->actor.world.pos.x = (BREG(30) + 1363.0f + 30.0f) - 40.0f; + D_809BEFD8->actor.world.pos.x = (BREG(30) + 1363.0f + 30.0f) - 40.0f; + this->unk68C.x = 1339.0f; + this->unk68C.y = 117.0f; + this->unk68C.z = 2864.0f; + this->unk698.x = 1452.0f; + this->unk698.y = 120.0f; + this->unk698.z = 2864.0f; + this->unk6A4 = 0.0f; + Message_StartTextbox(play, 0x1534, NULL); + this->unk6B0 = 60.0f; + play->envCtx.lightSettingOverride = 4; + /* Fallthrough */ + case 7: + if (this->unk684 >= (u32)(BREG(37) + 0x14)) { + if (this->unk684 == (u32)(BREG(37) + 0x14)) { + Animation_MorphToPlayOnce(&this->unk194, &D_06009D8C, 0.0f); + this->unk1D8 = Animation_GetLastFrame(&D_06009D8C); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_STAND); + } + if (Animation_OnFrame(&this->unk194, this->unk1D8) != 0) { + Animation_MorphToLoop(&this->unk194, &D_06008390, 0.0f); + this->unk1D8 = 1000.0f; + } + } + if (this->unk684 < (u32)(BREG(87) + 0x14)) { + this->unk430 = 200.0f; + } + if (this->unk684 == (u32)(BREG(37) + 0x19)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HAND); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_ATTACK); + } + if (this->unk684 == (u32)(BREG(44) + 0x28)) { + Animation_MorphToLoop(&D_809BEFD4->unk194, &D_0600CDE0, -5.0f); + Animation_MorphToLoop(&D_809BEFD8->unk194, &D_0600CDE0, -5.0f); + } + if (this->unk684 == 40) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HEAD_MID); + } + if (this->unk684 == 45) { + Actor_PlaySfx(&D_809BEFD8->actor, NA_SE_EN_DEBU_LAUGH_K); + } + if (this->unk684 == 50) { + Actor_PlaySfx(&D_809BEFD4->actor, NA_SE_EN_YASE_LAUGH_K); + } + Math_ApproachF(&this->unk68C.x, 1196.0f, 0.1f, this->unk6A4 * 143.0f); + Math_ApproachF(&this->unk68C.y, 52.0f, 0.1f, this->unk6A4 * 65.0f); + Math_ApproachF(&this->unk698.x, 1302.0f, 0.1f, this->unk6A4 * 150.0f); + Math_ApproachF(&this->unk698.y, 90.0f, 0.1f, this->unk6A4 * 30.0f); + Math_ApproachF(&this->unk6A4, BREG(45) * 0.01f + 0.1f, 1.0f, BREG(45) * 0.0001f + 0.01f); + + if (this->unk684 != (u32)(BREG(18) + 0x3C)) { + break; + } + + this->unk688 = 8; + this->unk684 = 0; + + this->unk68C.x = 1309.0f; + this->unk68C.y = 103.0f; + this->unk68C.z = 2790.0f; + + this->unk698.x = 1421.0f; + this->unk698.y = 103.0f; + this->unk698.z = 2790.0f; + + play->envCtx.lightSettingOverride = 5; + Actor_PlaySfx(&D_809BEFD4->actor, NA_SE_EN_YASE_LAUGH_K); + /* Fallthrough */ + case 8: + if (this->unk684 == 15) { + this->unk68C.x = 1309.0f; + this->unk68C.y = 103.0f; + this->unk68C.z = 2930.0f; + this->unk698.x = 1421.0f; + this->unk698.y = 103.0f; + this->unk698.z = 2930.0f; + Actor_PlaySfx(&D_809BEFD8->actor, NA_SE_EN_DEBU_LAUGH_K); + Actor_PlaySfx(&D_809BEFD4->actor, NA_SE_EN_YASE_LAUGH_K); + } + if (this->unk684 == 30) { + this->unk68C.x = 1324.0f; + this->unk68C.y = 144.0f; + this->unk68C.z = 2864.0f; + this->unk698.x = 1436.0f; + this->unk698.y = 144.0f; + this->unk698.z = 2864.0f; + play->envCtx.lightSettingOverride = 6; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_LAUGH_DEMO_K); + Actor_PlaySfx(&D_809BEFD8->actor, NA_SE_EN_DEBU_LAUGH_K); + Actor_PlaySfx(&D_809BEFD4->actor, NA_SE_EN_YASE_LAUGH_K); + } + if (this->unk684 == (u32)(BREG(19) + 0x37)) { + temp_v0_2 = Play_GetCamera(play, 0); + this->unk688 = 0; + + func_809B6528(this, play); + func_809B41D8(D_809BEFD4, play); + func_809B41D8(D_809BEFD8, play); + + D_809BEFD8->actor.gravity = -1.5f; + D_809BEFD4->actor.gravity = D_809BEFD8->actor.gravity; + D_809BEFD8->unk152 = 1; + D_809BEFD4->unk152 = D_809BEFD8->unk152; + + temp_v0_2->eye = this->unk68C; + temp_v0_2->eyeNext = this->unk68C; + temp_v0_2->at = this->unk698; + + func_80169AFC(play, this->unk_68A, 0); + this->unk_68A = 0; + Cutscene_StopManual(play, &play->csCtx); + func_800B7298(play, &this->actor, 6); + D_809BDB00 = 1; + this->unk_153 = 2; + Message_CloseTextbox(play); + play->envCtx.lightSettingOverride = 7; + gSaveContext.eventInf[5] |= 0x80; + } + break; + } + + if (this->unk_68A != 0) { + ShrinkWindow_Letterbox_SetSizeTarget(27); + temp_fv1 = Math_SinS(this->unk146 * 0x6000) * 0.5f * sp64; + + sp50.x = this->unk68C.x; + sp50.y = this->unk68C.y + temp_fv1; + sp50.z = this->unk68C.z; + sp44.x = this->unk698.x; + sp44.y = this->unk698.y + 2.0f * temp_fv1; + sp44.z = this->unk698.z; + Play_SetCameraAtEye(play, this->unk_68A, &sp44, &sp50); + Play_SetCameraFov(play, this->unk_68A, this->unk6B0); + sp60->actor.world.rot.y = sp60->actor.shape.rot.y = this->unk6AC; + } + + Math_ApproachF(&this->unk42C, this->unk430, 1.0f, 2.0f * KREG(41) + 200.0f); + this->unk428 = Math_SinS((KREG(40) * 0x100 + 0x3F00) * this->unk146) * this->unk42C + this->unk42C; + Math_ApproachZeroF(&this->unk42C, 1.0f, KREG(41) + 100.0f); + + if ((this->unk430 >= 50.0f) && !(this->unk146 & 1) && (Rand_ZeroOne() < 0.5f)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_TALK); + } +} + +void func_809B9A18(EnKnight* arg0, PlayState* arg1) { + s32 var_s0; + s32 var_s4; + Vec3f sp4C; + Player* temp_v0 = GET_PLAYER(arg1); + + if (arg0->unk534.elements[0].info.bumperFlags & 2) { + arg0->unk534.elements[0].info.bumperFlags &= 0xFFFD; + arg0->unk193 = 5; + if ((temp_v0->meleeWeaponState != 0) && (temp_v0->meleeWeaponAnimation >= 0x1E) && (arg0->unk478 == 0)) { + Audio_PlaySfx(NA_SE_IT_SHIELD_REFLECT_SW); + CollisionCheck_SpawnShieldParticlesMetal(arg1, &arg0->unk47C); + arg0->unk478 = 5; + } + Matrix_RotateYS(arg0->unk172, MTXMODE_NEW); + Matrix_MultVecZ((arg0 == D_809BEFD0) ? -6.0f : -4.0f, &sp4C); + arg0->unk2A4 = sp4C.x; + arg0->unk2A8 = sp4C.z; + return; + } + + for (var_s4 = 0; var_s4 < 2; var_s4++) { + if (arg0->unk156 != 0) { + continue; + } + + if (arg0->unk594.elements[var_s4].info.bumperFlags & 2) { + arg0->unk594.elements[var_s4].info.bumperFlags &= ~2; + + switch (arg0->actor.colChkInfo.damageEffect) { + case 3: + arg0->unk2A1 = 10; + func_809B4E84(arg0, arg1, 0x50); + Actor_PlaySfx(&arg0->actor, NA_SE_EN_COMMON_FREEZE); + arg0->unk156 = 15; + break; + case 1: + func_809B4E84(arg0, arg1, 0x28); + Actor_PlaySfx(&arg0->actor, NA_SE_EN_COMMON_FREEZE); + arg0->unk156 = 15; + break; + case 2: + arg0->unk2A1 = 1; + break; + case 4: + arg0->unk2A1 = 0x14; + break; + case 14: + arg0->unk291 = 10; + break; + case 10: + arg0->unk2A1 = 0x28; + func_809B4E84(arg0, arg1, 0x28); + Actor_PlaySfx(&arg0->actor, NA_SE_EN_COMMON_FREEZE); + arg0->unk156 = 15; + break; + case 13: + if (arg0->actor.bgCheckFlags & 1) { + Matrix_RotateYS(arg0->unk172, MTXMODE_NEW); + Matrix_MultVecZ(-4.0f, &sp4C); + arg0->unk2A4 = sp4C.x; + arg0->unk2A8 = sp4C.z; + arg0->actor.velocity.y = 5.0f; + + for (var_s0 = 0; var_s0 < 5; var_s0++) { + func_809B22CC(arg0, arg1, 0); + } + } + break; + } + if (arg0->actor.colChkInfo.damage != 0) { + arg0->actor.colChkInfo.health -= arg0->actor.colChkInfo.damage; + if ((s8)arg0->actor.colChkInfo.health <= 0) { + func_809B51DC(arg0, arg1); + Enemy_StartFinishingBlow(arg1, &arg0->actor); + Actor_PlaySfx(&arg0->actor, arg0->unk6C0); + } else if (arg0->actor.colChkInfo.damageEffect != 3) { + func_809B4F90(arg0, arg1); + Actor_PlaySfx(&arg0->actor, arg0->unk6BE); + } + arg0->unk156 = 10; + arg0->unk158 = 15; + } + arg0->unk192 = 0; + } + } +} + +void func_809B9D24(EnKnight* this, PlayState* play) { + if (this->unk156 == 0) { + s32 i; + + for (i = 0; i < 2; i++) { + ColliderJntSphElement* temp_v0 = &this->unk594.elements[i]; + ColliderInfo* acHitInfo; + + if (temp_v0->info.bumperFlags & 2) { + temp_v0->info.bumperFlags &= ~2; + + acHitInfo = temp_v0->info.acHitInfo; + + this->unk156 = 10; + if (acHitInfo->toucher.dmgFlags & 0x200000) { + this->unk158 = 15; + this->unk156 = 1000; + func_809B5634(this, play); + } + } + } + } +} + +void func_809B9E00(EnKnight* this, PlayState* play) { + Vec3f sp94; + Vec3f sp88; + s32 i; + + SoundSource_PlaySfxAtFixedWorldPos(play, &this->unk1DC[0], 30, NA_SE_EV_ICE_BROKEN); + + for (i = 0; i < 15; i++) { + sp88.x = Rand_CenteredFloat(7.0f); + sp88.z = Rand_CenteredFloat(7.0f); + sp88.y = Rand_ZeroFloat(6.0f) + 4.0f; + sp94.x = sp88.x + this->unk1DC[i].x; + sp94.y = sp88.y + this->unk1DC[i].y; + sp94.z = sp88.z + this->unk1DC[i].z; + EffectSsEnIce_Spawn(play, &sp94, Rand_ZeroFloat(0.5f) + 0.7f, &sp88, &D_809BDD00, &D_809BDCF8, &D_809BDCFC, + 0x1E); + } +} + +void func_809B9F8C(EnKnight* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (this->unk156 == 0) { + if (this->unk634.base.acFlags & AC_HIT) { + this->unk634.base.acFlags &= ~AC_HIT; + this->unk156 = 0xF; + if (&this->actor == player->actor.parent) { + player->av2.actionVar2 = 0x65; + player->actor.parent = NULL; + player->csAction = 0; + Play_DisableMotionBlur(); + func_800B8D50(play, &this->actor, 10.0f, D_809BEFD0->unk172, 5.0f, 16); + func_809BA058(this, play); + this->unk148 = 1; + this->unk14A[1] = 0x1E; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_LAUGH_DEMO_K); + } + } + } +} + +void func_809BA058(EnKnight* this, PlayState* play) { + Animation_MorphToPlayOnce(&this->unk194, &D_06003008, 0.0f); + this->unk194.curFrame = 19.0f; + this->actionFunc = func_809BA0CC; + this->unk148 = 0; + this->unk14A[1] = KREG(77) + 0xC8; + this->actor.flags |= ACTOR_FLAG_TARGETABLE; +} + +void func_809BA0CC(EnKnight* this, PlayState* play) { + f32 sp4C; + f32 sp48; + f32 sp44; + s32 pad; + f32 sp3C; + s16 sp3A; + s16 sp38; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->unk194); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HEAD_FLOAT - SFX_FLAG); + + switch (this->unk148) { + case 0: + this->unk148 = 1; + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(500.0f, &this->unk440); + this->unk440.x += this->actor.world.pos.x; + this->unk440.y = this->actor.world.pos.y + 500.0f; + this->unk440.z += this->actor.world.pos.z; + this->actor.world.rot.x = KREG(39) * 0x1000 + 0x2000; + this->unk14A[0] = 0x14; + D_809BEFD0->actor.flags &= ~1; + player->lockOnActor = &this->actor; + play->actorCtx.targetCtx.fairyActor = &this->actor; + play->actorCtx.targetCtx.lockOnActor = &this->actor; + Math_Vec3f_Copy(&this->actor.world.pos, &D_809BEFD0->actor.world.pos); + Math_Vec3s_Copy(&this->actor.world.rot, &D_809BEFD0->actor.world.rot); + Math_Vec3s_Copy(&this->actor.shape.rot, &D_809BEFD0->actor.world.rot); + this->unk156 = 0xA; + this->unk152 = 1; + return; + case 1: + this->unk428 = (Math_SinS((KREG(40) * 0x100 + 0x1200) * this->unk146) * 1000.0f) + 1000.0f; + sp4C = this->unk440.x - this->actor.world.pos.x; + sp48 = this->unk440.y - this->actor.world.pos.y; + sp44 = this->unk440.z - this->actor.world.pos.z; + sp3C = sqrtf(SQ(sp4C) + SQ(sp48) + SQ(sp44)); + + if ((this->unk14A[1] == 1) || (KREG(5) != 0)) { + KREG(5) = 0; + if (D_809BEFD0->actionFunc != func_809B52E8 && D_809BEFD0->actionFunc != func_809B5698) { + this->unk14A[1] = 0; + func_809B6D38(D_809BEFD0, play); + Animation_MorphToPlayOnce(&this->unk194, &D_060079D4, -10.0f); + this->unk152 = 0; + this->unk194.playSpeed = 0.0f; + } else { + this->unk14A[1] = 0x32; + } + } + if (this->unk14A[1] == 0) { + Math_Vec3f_Copy(&this->unk440, &D_809BEFD0->actor.world.pos); + this->unk440.y += 100.0f; + if (sp3C < 100.0f) { + Math_ApproachF(&this->actor.speed, (f32)sREG(48) + 1.5f, 1.0f, 0.3f); + } + if (sp3C < 30.0f) { + this->unk148 = 2; + this->unk14A[0] = 0x32; + this->unk156 = 0x3E8; + break; + } + } else { + Math_ApproachF(&this->actor.speed, sREG(48) + 5.0f, 1.0f, 5.0f); + if (this->unk14A[0] == 0 || sp3C < 50.0f) { + this->unk14A[0] = Rand_ZeroFloat(50.0f) + 50.0f; + if (Rand_ZeroOne() < 0.2f) { + Math_Vec3f_Copy(&this->unk440, &player->actor.world.pos); + this->unk440.y += 25.0f; + } else { + this->unk440.x = Rand_CenteredFloat(500.0f) + player->actor.world.pos.x; + this->unk440.y = Rand_ZeroFloat(100.0f) + player->actor.world.pos.y + 50.0f; + this->unk440.z = Rand_CenteredFloat(500.0f) + player->actor.world.pos.z; + } + } + } + sp38 = Math_Atan2S(sp4C, sp44); + sp3A = Math_Atan2S(sp48, sqrtf(SQ(sp4C) + SQ(sp44))); + Math_ApproachS(&this->actor.world.rot.y, sp38, 0xA, 0x800); + Math_ApproachS(&this->actor.world.rot.x, sp3A, 0xA, 0x800); + Math_ApproachF(&this->unk164.x, 300.0f, 0.1f, 3.0f); + Math_ApproachF(&this->unk164.y, -3800.0f, 0.1f, 38.0f); + Math_ApproachF(&this->unk164.z, -900.0f, 0.1f, 9.0f); + Math_ApproachS(&this->actor.shape.rot.y, this->unk172, 0xA, 0x200); + Math_ApproachS(&this->actor.shape.rot.x, this->unk170, 0xA, 0x200); + if (this->unk14A[1] == 0x28) { + func_809BA940(this, play); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_CYNICAL); + } + break; + case 2: + case 3: + this->unk156 = 10; + Math_ApproachZeroF(&this->actor.speed, 1.0f, 0.1f); + Math_ApproachS(&this->actor.shape.rot.y, D_809BEFD0->actor.world.rot.y, 5, 0x800); + Math_ApproachS(&this->actor.shape.rot.x, 0, 5, 0x800); + Math_ApproachZeroF(&this->unk164.x, 0.5f, (sREG(73) * 0.01f + 0.05f) * 300.0f); + Math_ApproachZeroF(&this->unk164.y, 0.5f, (sREG(73) * 0.01f + 0.05f) * 3800.0f); + Math_ApproachZeroF(&this->unk164.z, 0.5f, (sREG(73) * 0.01f + 0.05f) * 900.0f); + Math_ApproachF(&this->actor.world.pos.x, D_809BEFD0->actor.world.pos.x, 0.5f, sREG(74) * 0.1f + 4.0f); + Math_ApproachF(&this->actor.world.pos.y, D_809BEFD0->actor.world.pos.y, 0.5f, sREG(74) * 0.1f + 4.0f); + Math_ApproachF(&this->actor.world.pos.z, D_809BEFD0->actor.world.pos.z, 0.5f, sREG(74) * 0.1f + 4.0f); + if (this->unk148 == 2) { + if ((fabsf(this->actor.world.pos.x - D_809BEFD0->actor.world.pos.x) < 30.0f) && + (fabsf(this->actor.world.pos.z - D_809BEFD0->actor.world.pos.z) < 30.0f) && + (fabsf(this->actor.world.pos.y - D_809BEFD0->actor.world.pos.y) < sREG(75) * 0.1f + 30.0f)) { + this->unk148 = 3; + D_809BEFD0->unk148 = 1; + this->unk194.playSpeed = 1.0f; + } + } + break; + } +} + +void func_809BA940(EnKnight* this, PlayState* play) { + this->actionFunc = func_809BA978; + this->unk148 = 0; + this->unk14A[0] = BREG(16) + 0x3C; + this->unk14A[2] = 0xFA; +} + +void func_809BA978(EnKnight* this, PlayState* play) { + Vec3f sp54; + f32 sp50; + f32 sp4C; + f32 sp48; + f32 sp44; + s16 sp42; + s16 sp40; + Player* player = GET_PLAYER(play); + s32 pad; + + Matrix_RotateYS(player->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(7.0f, &sp54); + + if (player->transformation == 1) { + sp54.y = 67.0f; + } else if (player->transformation == 0) { + sp54.y = 85.0f; + } else if (player->transformation == 2) { + sp54.y = 60.0f; + } else if (player->transformation == 3) { + sp54.y = 34.0f; + } else { + sp54.y = 40.0f; + } + + sp50 = player->actor.world.pos.x - this->actor.world.pos.x; + sp4C = BREG(17) + (player->actor.world.pos.y + 100.0f) - this->actor.world.pos.y; + sp48 = player->actor.world.pos.z - this->actor.world.pos.z; + + if (this->unk148 != 1) { + f32 var_fv1 = (this->unk148 == 2) ? 3000.0f : 1000.0f; + + this->unk428 = Math_SinS((KREG(40) * 0x100 + 0x1200) * this->unk146) * 1000.0f + var_fv1; + } + + sp44 = sqrtf(SQ(sp50) + SQ(sp48)); + + switch (this->unk148) { + case 0: + Math_ApproachF(&this->actor.speed, BREG(18) + 10.0f, 1.0f, 1.0f); + sp40 = Math_Atan2S(sp50, sp48); + sp42 = Math_Atan2S(sp4C, sp44); + Math_ApproachS(&this->actor.world.rot.y, sp40, 0xA, 0x800); + Math_ApproachS(&this->actor.world.rot.x, sp42, 0xA, 0x800); + + if (this->unk14A[2] == 0) { + func_809BA058(this, play); + this->unk148 = 1; + this->unk14A[1] = 0x1E; + break; + } + + if (this->unk14A[0] == 0 && sp44 < BREG(19) + 100.0f) { + this->unk148 = 1; + this->unk14A[2] = 0x3C; + this->unk6A4 = 0.0f; + } + break; + case 1: + this->unk152 = 0; + Math_ApproachS(&this->unk428, 0xFA0, 5, 0x1000); + Math_ApproachZeroF(&this->actor.speed, 1.0f, 1.0f); + Math_ApproachF(&this->actor.world.pos.x, player->actor.world.pos.x + sp54.x, 1.0f, this->unk6A4); + Math_ApproachF(&this->actor.world.pos.y, player->actor.world.pos.y + sp54.y, 1.0f, this->unk6A4); + Math_ApproachF(&this->actor.world.pos.z, player->actor.world.pos.z + sp54.z, 1.0f, this->unk6A4); + Math_ApproachF(&this->unk6A4, BREG(20) + 20.0f, 1.0f, BREG(21) + 0.5f); + + if (this->unk14A[2] == 0 || (player->stateFlags3 & 0x1000)) { + func_809BA058(this, play); + this->unk148 = 1; + this->unk14A[1] = 0x1E; + break; + } + + if (sp44 < BREG(22) + 20.0f) { + if (play->grabPlayer(play, player) != 0) { + Play_EnableMotionBlur(0x96); + player->actor.parent = &this->actor; + AudioSfx_PlaySfx(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); + this->actor.flags &= ~1; + this->unk148 = 2; + this->unk14A[0] = 0x50; + } else { + this->unk14A[2] = 0; + } + } + break; + case 2: + if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B)) { + + if (1) {} + if (this->unk14A[0] != 0) { + this->unk14A[0]--; + if (1) {} + } + if (this->unk14A[0] != 0) { + this->unk14A[0]--; + } + if (this->unk14A[0] != 0) { + this->unk14A[0]--; + } + if (this->unk14A[0] != 0) { + this->unk14A[0]--; + } + if (this->unk14A[0] != 0) { + this->unk14A[0]--; + } + } + Math_ApproachF(&this->actor.world.pos.x, player->actor.world.pos.x + sp54.x, 1.0f, this->unk6A4); + Math_ApproachF(&this->actor.world.pos.y, player->actor.world.pos.y + sp54.y, 1.0f, this->unk6A4); + Math_ApproachF(&this->actor.world.pos.z, player->actor.world.pos.z + sp54.z, 1.0f, this->unk6A4); + Math_ApproachF(&this->unk6A4, BREG(20) + 20.0f, 1.0f, BREG(21) + 0.5f); + Math_ApproachS(&this->actor.shape.rot.y, player->actor.shape.rot.y + 0x8000, 2, 0x1000); + Math_ApproachS(&this->actor.shape.rot.x, BREG(83) * 0x800 + 0x4000, 2, 0x1000); + player->av2.actionVar2 = 0x5A; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HEAD_BITE - SFX_FLAG); + if (this->unk14A[0] == 0 && &this->actor == player->actor.parent) { + player->av2.actionVar2 = 0x65; + player->actor.parent = NULL; + player->csAction = 0; + Play_DisableMotionBlur(); + func_809BA058(this, play); + this->unk148 = 1; + this->unk14A[1] = 0x1E; + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_LAUGH_DEMO_K); + } + break; + } + + if (this->unk148 != 2) { + Math_ApproachS(&this->actor.shape.rot.y, this->unk172, 0xA, 0x200); + Math_ApproachS(&this->actor.shape.rot.x, this->unk170, 0xA, 0x200); + Actor_PlaySfx(&this->actor, NA_SE_EN_BOSU_HEAD_FLOAT - SFX_FLAG); + } +} + +void EnKnight_Update(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; + Input* input; + PlayState* play2 = play; + Player* sp78; + f32 sp74; + f32 sp70; + f32 sp6C; + u8 var_a0; + s32 var_v1; + + sp78 = GET_PLAYER(play); + Math_Vec3f_Copy(&this->unk6C8, &this->actor.projectedPos); + sp74 = sp78->actor.world.pos.x - this->actor.focus.pos.x; + sp70 = KREG(93) + ((sp78->actor.world.pos.y + 34.0f) - this->actor.focus.pos.y); + sp6C = sp78->actor.world.pos.z - this->actor.focus.pos.z; + + this->unk172 = Math_Atan2S_XY(sp6C, sp74); + this->unk170 = Math_Atan2S(-sp70, sqrtf(SQ(sp74) + SQ(sp6C))); + + this->unk146++; + + if (this == D_809BEFDC) { + for (var_a0 = 0; var_a0 < 3; var_a0++) { + if (this->unk14A[var_a0] != 0) { + this->unk14A[var_a0]--; + } + } + + if (this->unk156 != 0) { + this->unk156--; + } + if (this->unk158 != 0) { + this->unk158--; + } + this->actionFunc(this, play); + Math_ApproachS(&this->unk184, this->unk186, 5, 0x2000); + this->unk186 = 0; + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); + this->actor.world.pos.x += this->unk2A4; + this->actor.world.pos.z += this->unk2A8; + Math_ApproachZeroF(&this->unk2A4, 1.0f, KREG(86) + 2.0f); + Math_ApproachZeroF(&this->unk2A8, 1.0f, KREG(86) + 2.0f); + if (this->unk152 != 0) { + Actor_UpdateBgCheckInfo(play, &this->actor, 50.0f, 20.0f, 100.0f, 5); + } + func_809B9F8C(this, play); + + this->unk488.dim.pos.x = (s32)this->actor.focus.pos.x; + this->unk488.dim.pos.y = (s32)this->actor.focus.pos.y; + this->unk488.dim.pos.z = (s32)this->actor.focus.pos.z; + + if (this->actionFunc == func_809BA978) { + if (this->unk148 < 2) { + if (this->unk148 == 0) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk488.base); + } + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk488.base); + } else { + this->unk634.dim.radius = KREG(34) + 0x14; + this->unk634.dim.height = KREG(35) + 0x28; + this->unk634.dim.yShift = 0; + this->unk634.dim.pos.x = (s32)sp78->actor.world.pos.x; + this->unk634.dim.pos.y = (s32)sp78->actor.world.pos.y; + this->unk634.dim.pos.z = (s32)sp78->actor.world.pos.z; + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk634.base); + } + } else { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk488.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk488.base); + } + + if ((this->actionFunc != func_809BA978 || this->unk148 != 2) && !(BREG(76) & this->unk146)) { + EnKnight* temp_v0_5 = (EnKnight*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_KNIGHT, + this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, 0xCA); + if (temp_v0_5 != NULL) { + for (var_v1 = 0; var_v1 < 29; var_v1++) { + temp_v0_5->unk194.jointTable[var_v1] = this->unk194.jointTable[var_v1]; + temp_v0_5->unk194.skeleton = this->unk194.skeleton; + temp_v0_5->unk194.dListCount = this->unk194.dListCount; + } + Math_Vec3f_Copy(&temp_v0_5->unk164, &this->unk164); + } + } + } else { + this->unk_680 = 0; + + if (this == D_809BEFD0) { + Actor* var_v0; + + D_809BEFE4 = NULL; + for (var_v0 = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; var_v0 != NULL; var_v0 = var_v0->next) { + if (var_v0->id == ACTOR_MIR_RAY3) { + D_809BEFE4 = (MirRay3*)var_v0; + break; + } + } + + this->unk_144 = gSaveContext.save.time; + Math_ApproachS(&this->unk428, 0, 2, 0x200); + } else if (D_809BEFD0->unk_154 == 0) { + this->actor.hintId = 0x1D; + } else { + this->actor.hintId = 0x1E; + } + + if (D_809BEFD0->unk_151 != 0) { + if ((this == D_809BEFD0) && (this->actionFunc == func_809B6764)) { + func_809B5D38(this, play); + } + if (!((this == D_809BEFD0) && (this->actionFunc == func_809B5D54))) { + return; + } + } + + this->unk190 = 0; + this->unk191 = 0; + this->unk192 = 0; + this->unk594.base.colType = 3; + if (((KREG(63) == 0) && (this != D_809BEFD0)) || ((KREG(63) != 2) && (this == D_809BEFD0))) { + for (var_a0 = 0; var_a0 < 3; var_a0++) { + if (this->unk14A[var_a0] != 0) { + this->unk14A[var_a0]--; + } + } + + if (this->unk156 != 0) { + this->unk156--; + } + if (this->unk158 != 0) { + this->unk158--; + } + if (this->unk478 != 0) { + this->unk478--; + } + if (this->unk2A2 != 0) { + this->unk2A2--; + } + if (this->unk15E != 0) { + this->unk15E--; + } + if (this->unk291 != 0) { + this->unk291--; + } + + Math_ApproachZeroF(&this->unk474, 1.0f, 0.2f); + + if ((this->actionFunc != func_809B52E8) && (this->actionFunc != func_809B5698)) { + Math_ApproachS(&this->actor.shape.rot.x, 0, 10, 0x200); + } + + this->actionFunc(this, play); + + Actor_MoveWithGravity(&this->actor); + + this->actor.world.pos.x += this->unk2A4; + this->actor.world.pos.z += this->unk2A8; + + if ((this->unk192 != 0) || (this->actionFunc == func_809B4880)) { + func_809B2DD0(this, play); + + if ((this->unk192 != 0) && (D_809BEFE0 != NULL) && (this != D_809BEFE0)) { + func_809B5E90(this, play); + } else if ((this != D_809BEFD0) && (sp78->stateFlags3 & 0x20000000)) { + func_809B5FA8(this, play); + } + } + } + + if (this->unk152 != 0) { + Actor_UpdateBgCheckInfo(play, &this->actor, 100.0f, 50.0f, 150.0f, 5); + } + + if (this->actor.bgCheckFlags & 1) { + if (this->actor.velocity.y <= 0.0f) { + this->actor.velocity.y = -2.0f; + } + Math_ApproachZeroF(&this->unk2A4, 1.0f, 1.0f); + Math_ApproachZeroF(&this->unk2A8, 1.0f, 1.0f); + } + + Math_ApproachS(&this->unk184, this->unk186, this->unk18E, this->unk18C); + this->unk18C = 0x1000; + this->unk18E = 3; + Math_ApproachS(&this->unk188, this->unk18A, this->unk18E, this->unk18C); + this->unk18A = 0; + + if (this->actionFunc != func_809B4308) { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0xA00); + } + + if (this->actionFunc != func_809B842C && this->actionFunc != func_809B5698 && + this->actionFunc != func_809B58D4 && this->actionFunc != func_809B6764 && + this->actionFunc != func_809B6C54 && this->actionFunc != func_809B6D94 && !Play_InCsMode(play)) { + + if (this->actionFunc != func_809B52E8) { + func_809B9A18(this, play); + + if (this->unk190 != 0) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk4D4.base); + CollisionCheck_SetAT(play, &play2->colChkCtx, &this->unk4D4.base); + } + + if (this->unk191 != 0) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk534.base); + } + + if (this->unk162 == 0) { + if (this->unk193 == 0) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk594.base); + } else { + this->unk193--; + } + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk594.base); + + if (this->unk192 != 0 && + (sp78->unk_D57 != 0 || (sp78->unk_ADC != 0 && this->actor.xzDistToPlayer <= 120.0f)) && + func_809B316C(this, play)) { + f32 var_fv1 = (this == D_809BEFD0) ? 0.65f : 0.25f; + + if ((Rand_ZeroOne() < var_fv1) && (sp78->unk_ADC != 0) && (this->actionFunc != func_809B3DAC) && + !(this->actor.bgCheckFlags & 8)) { + func_809B592C(this, play); + } else { + func_809B3CD0(this, play); + } + } + } + } else { + func_809B9D24(this, play); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk594.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk594.base); + } + } + + input = &play->state.input[3]; + if (CHECK_BTN_ALL(input->press.button, BTN_L) && this == D_809BEFD0) { + func_809B5634(D_809BEFD4, play); + func_809B5634(D_809BEFD8, play); + } + if (CHECK_BTN_ALL(input->press.button, BTN_R) && this == D_809BEFD0) { + this->unk2A1 = KREG(17); + } + + switch (this->unk2A1) { + case 0: + this->unk2A0 = 0; + this->unk2A2 = 0; + this->unk29C = 0.0f; + break; + case 1: + this->unk2A0 = 0; + this->unk2A2 = 0x50; + this->unk2A1++; + this->unk29C = 1.0f; + this->unk294 = 0.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 0x78, 0, 0x3C); + /* fallthrough */ + case 2: + if (this->unk2A2 == 0) { + Math_ApproachZeroF(&this->unk29C, 1.0f, 0.02f); + if (this->unk29C == 0.0f) { + this->unk2A1 = 0; + } + } else { + Math_ApproachF(&this->unk294, 0.5f, 0.1f, 0.5f); + } + break; + case 10: + this->unk2A0 = 11; + this->unk2A2 = 0x50; + this->unk2A1++; + this->unk29C = 1.0f; + this->unk294 = 0.0f; + this->unk298 = 1.0f; + /* fallthrough */ + case 11: + if (this->unk2A2 == 0) { + func_809B9E00(this, play); + this->unk2A1 = 0; + } else { + if (this->unk2A2 == 50) { + this->unk2A0 = 10; + } + Math_ApproachF(&this->unk294, 0.5f, 1.0f, 0.08f); + Math_ApproachF(&this->unk298, 0.5f, 0.05f, 0.05f); + } + break; + case 20: + this->unk2A0 = 0x14; + this->unk2A2 = 0x28; + this->unk2A1++; + this->unk29C = 1.0f; + this->unk294 = 0.0f; + /* fallthrough */ + case 21: + if (this->unk2A2 == 0) { + Math_ApproachZeroF(&this->unk294, 1.0f, 0.03f); + if (this->unk294 == 0.0f) { + this->unk2A1 = 0; + this->unk29C = 0.0f; + } + } else { + Math_ApproachF(&this->unk294, 0.75f, 0.5f, 0.5f); + } + break; + case 30: + this->unk2A0 = 20; + this->unk2A2 = 10; + this->unk2A1++; + this->unk29C = 0.5f; + /* fallthrough */ + case 31: + if (this->unk2A2 == 0) { + Math_ApproachZeroF(&this->unk294, 1.0f, 0.03f); + if (this->unk294 == 0.0f) { + this->unk2A1 = 0; + this->unk29C = 0.0f; + } + } else { + Math_ApproachF(&this->unk294, 0.5f, 0.5f, 0.3f); + } + break; + case 40: + this->unk2A0 = 30; + this->unk2A2 = 50; + this->unk29C = 1.0f; + this->unk294 = (KREG(18) * 0.1f) + 0.5f; + this->unk2A1++; + /* fallthrough */ + case 41: + if (this->unk2A2 == 0) { + Math_ApproachZeroF(&this->unk294, 1.0f, 0.05f); + if (this->unk294 == 0.0f) { + this->unk2A1 = 0; + this->unk29C = 0.0f; + } + } + break; + } + + this->unk430 = 0.0f; + + if (this == D_809BEFD0) { + if (D_809BDB00 != 0) { + D_809BDB00--; + if (D_809BDB00 == 0) { + Audio_PlayBgm_StorePrevBgm(NA_BGM_MINI_BOSS); + } + } + if (this->unk162 != 0) { + Math_ApproachF(&this->unk17C, 60.0f, 1.0f, 8.0f); + } else { + Math_ApproachF(&this->unk17C, 255.0f, 1.0f, 8.0f); + } + func_809BD490(this, play); + if (this->unk_154 != 0) { + u16 var_v0_2; + + play->envCtx.lightSettingOverride = 0; + play->envCtx.lightBlendOverride = 2; + if (this->unk_154 == 1) { + play->envCtx.lightSetting = 8; + play->envCtx.prevLightSetting = 12; + } else { + play->envCtx.lightSetting = 0; + play->envCtx.prevLightSetting = 10; + } + var_v0_2 = gSaveContext.save.time; + if ((s32)var_v0_2 > 0x8000) { + var_v0_2 = (0xFFFF - var_v0_2) & 0xFFFF; + } + play->envCtx.lightBlend = var_v0_2 * 0.000030517578f; + } + if ((this->unk6C4 == 0) && (this->unk162 == 0) && (Player_GetMask(play) == 15) && + ((this->actionFunc == func_809B6764) || (this->unk192 != 0)) && + (this->actor.xzDistToPlayer < (KREG(82) + 130.0f)) && (func_809B316C(this, play) != 0)) { + this->unk6C4 = 1; + func_809B78A4(this, play); + } + } + this->actor.shape.shadowAlpha = (this->unk180 * this->unk17C) / 255.0f; + } +} + +void func_809BC2C4(EnKnight* this, PlayState* play) { + f32 var_fv0; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(&D_06018BC4)); + + gSPDisplayList(POLY_XLU_DISP++, D_08000000); + + if (this == D_809BEFD0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)(sREG(11) + 0xB4), 255, 255, + (u8)((sREG(14) * 0.1f + 1.0f) * this->unk450)); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)((sREG(14) * 0.1f + 1.0f) * this->unk450)); + } + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(this->unk454, this->unk458, this->unk45C, MTXMODE_APPLY); + Matrix_RotateXFApply(this->unk460); + Matrix_RotateZF(this->unk468, MTXMODE_APPLY); + Matrix_RotateYF(this->unk464, MTXMODE_APPLY); + + var_fv0 = (this == D_809BEFD0) ? (17.0f / 13) : 1.0f; + Matrix_Scale(0.021f * var_fv0, 0.021f * var_fv0, 0.021f * var_fv0, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + switch (this->unk44C) { + case 0: + gSPDisplayList(POLY_XLU_DISP++, D_06018AF0); + break; + case 1: + gSPDisplayList(POLY_XLU_DISP++, D_060189F0); + break; + default: + case 2: + gSPDisplayList(POLY_XLU_DISP++, D_060188F8); + break; + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +s32 func_809BC67C(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnKnight* this = THIS; + + if (limbIndex == 15) { + rot->x += (f32)this->unk184; + } + if (limbIndex == 18) { + rot->z += this->unk428; + } else if (limbIndex == 19) { + rot->z -= this->unk428; + } + + if (limbIndex != 18 && limbIndex != 19) { + *dList = NULL; + } + return 0; +} + +s32 func_809BC720(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnKnight* this = THIS; + + if (limbIndex == 0xF) { + rot->x += (f32)this->unk184; + rot->z += this->unk188; + } + if (this == D_809BEFD0) { + if (limbIndex == 0x12) { + rot->z += this->unk428; + } else if (limbIndex == 0x13) { + rot->z -= this->unk428; + } + if (limbIndex == 0x17) { + rot->z -= this->unk174; + } + if (limbIndex == 0x18) { + rot->z -= this->unk178; + } + if (limbIndex == 0x1A) { + rot->z -= this->unk176; + } + if (limbIndex == 0x1B) { + rot->z -= this->unk17A; + } + if ((limbIndex == 0x12 || limbIndex == 0x13) && this->unk162 != 0) { + *dList = NULL; + } + } else if (this == D_809BEFD8) { + if (limbIndex == 0xF) { + *dList = D_06013020; + } else if (limbIndex == 0x12) { + *dList = D_06012DB0; + } else if (limbIndex == 0x13) { + *dList = D_06012400; + } + } + return 0; +} + +void func_809BC8B4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnKnight* this = THIS; + Vec3f sp28; + + if (this->actionFunc == func_809B5698 || this->unk29C > 0.0f) { + s8 temp_v0 = D_809BDD3C[limbIndex]; + if (temp_v0 >= 0) { + Matrix_MultZero(&this->unk1DC[temp_v0]); + } + } + if (limbIndex == 15) { + Matrix_MultVec3f(&D_809BDD0C, &this->actor.focus.pos); + Matrix_MultVec3f(&D_809BDD5C, &this->unk434); + } + if (limbIndex == 20) { + Matrix_MultVec3f(&D_809BDD68, &sp28); + func_809B21F4(this, 0, &this->unk594, &sp28); + } + if (limbIndex == 21) { + Matrix_MultVec3f(&D_809BDD74, &sp28); + func_809B21F4(this, 1, &this->unk594, &sp28); + } + if (limbIndex == 6 && this->actionFunc != func_809B6764) { + Matrix_MultVec3f(&D_809BDD18, &sp28); + func_809B21F4(this, 0, &this->unk534, &sp28); + Matrix_MultVec3f(&D_809BDD24, &this->unk47C); + } + if (limbIndex == 11) { + Matrix_MultVec3f(&D_809BDD30, &sp28); + func_809B21F4(this, 0, &this->unk4D4, &sp28); + } + if (limbIndex == 28) { + Matrix_MultZero(this->unk2AC); + } + if (limbIndex == 25) { + Matrix_MultZero(&this->unk2AC[1]); + } +} + +void func_809BCA80(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnKnight* this = THIS; + + if (limbIndex == 15) { + Matrix_MultVec3f(&D_809BDD80, &this->actor.focus.pos); + Math_Vec3f_Copy(&this->unk434, &this->actor.focus.pos); + } +} + +void func_809BCAD8(PlayState* play, s32 limbIndex, Actor* thisx, Gfx** gfx) { + EnKnight* this = THIS; + + if (this == D_809BEFD0) { + if (limbIndex == 6) { + Matrix_Scale(this->unk470, this->unk470, this->unk470, MTXMODE_APPLY); + } else if (limbIndex == 11) { + Matrix_Scale(this->unk46C, this->unk46C, this->unk46C, MTXMODE_APPLY); + } + } +} + +Gfx* func_809BCB54(GraphicsContext* gfxCtx) { + Gfx* gfx = GRAPH_ALLOC(gfxCtx, 2 * sizeof(Gfx)); + gSPEndDisplayList(gfx); + return gfx; +} + +Gfx* func_809BCB78(GraphicsContext* gfxCtx, u8 alpha) { + Gfx* dList = GRAPH_ALLOC(gfxCtx, 6 * sizeof(Gfx)); + Gfx* gfx = dList; + + gDPPipeSync(gfx++); + gDPSetCombineLERP(gfx++, TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0, PRIMITIVE, 0, COMBINED, 0, COMBINED, 0, ENVIRONMENT, + 0); + gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + gDPSetRenderMode(gfx++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gSPClearGeometryMode(gfx++, G_CULL_BACK); + gSPEndDisplayList(gfx++); + return dList; +} + +void EnKnight_Draw(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; + f32 temp_fa0; + s32 sp6C = false; + + OPEN_DISPS(play->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0A, func_809BCB54(play->state.gfxCtx)); + gSPSegment(POLY_XLU_DISP++, 0x0A, func_809BCB54(play->state.gfxCtx)); + + if (this->unk17C >= 254.0f) { + Gfx_SetupDL25_Opa(play->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x09, func_809BCB54(play->state.gfxCtx)); + } else { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x09, func_809BCB78(play->state.gfxCtx, (u32)this->unk17C)); + sp6C = true; + } + + if (this->unk158 & 1) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + if (this->actionFunc == func_809B5698) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 0, 0, 0, 255, 900, 1099); + } + + if (this == D_809BEFDC) { + Matrix_Translate(this->unk164.x, this->unk164.y, this->unk164.z, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(play, this->unk194.skeleton, this->unk194.jointTable, this->unk194.dListCount, + func_809BC67C, func_809BCA80, &this->actor); + } else { + if (this == D_809BEFD0 && sp6C) { + POLY_XLU_DISP = + SubS_DrawTransformFlex(play, this->unk194.skeleton, this->unk194.jointTable, this->unk194.dListCount, + func_809BC720, func_809BC8B4, func_809BCAD8, &this->actor, POLY_XLU_DISP); + } else { + POLY_OPA_DISP = + SubS_DrawTransformFlex(play, this->unk194.skeleton, this->unk194.jointTable, this->unk194.dListCount, + func_809BC720, func_809BC8B4, func_809BCAD8, &this->actor, POLY_OPA_DISP); + } + + if (this->unk450 > 0.0f) { + func_809BC2C4(this, play); + Math_ApproachZeroF(&this->unk450, 1.0f, 40.0f); + this->unk44C++; + if (this->unk44C >= 3) { + this->unk44C = 2; + } + } else { + this->unk44C = 0; + } + + Actor_DrawDamageEffects(play, &this->actor, this->unk1DC, 15, this->unk294, this->unk298, this->unk29C, + this->unk2A0); + + if (this->unk474 > 0.01f) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gSPDisplayList(POLY_XLU_DISP++, gLightOrbMaterial1DL); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, (u8)(sREG(18) + 0xDC), (u8)(sREG(16) + 0xAA)); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, (u8)(sREG(22) + 0x64), 128); + + Matrix_Translate(this->unk47C.x, this->unk47C.y, this->unk47C.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_RotateZS(play->gameplayFrames * 0x80, MTXMODE_APPLY); + + temp_fa0 = (sREG(17) + 600) * 0.01f * this->unk474; + Matrix_Scale(temp_fa0, temp_fa0, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbModelDL); + } + } + + POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP); + + if (this == D_809BEFD0) { + func_809BD858(this, play); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_809BD1AC(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; + f32 var_fv0; + + if (this->actor.params == 0xCA) { + var_fv0 = BREG(75) + 15.0f; + } else { + var_fv0 = BREG(78) + 8.0f; + } + Math_ApproachZeroF(&this->unk17C, 1.0f, var_fv0); + if (this->unk17C < 0.1f) { + Actor_Kill(&this->actor); + } +} + +s32 func_809BD260(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnKnight* this = THIS; + + if (this->actor.params == 0xCA && limbIndex != 18 && limbIndex != 19) { + *dList = NULL; + } + return 0; +} + +void func_809BD29C(Actor* thisx, PlayState* play) { + EnKnight* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x09, func_809BCB78(play->state.gfxCtx, this->unk17C)); + gSPSegment(POLY_XLU_DISP++, 0x0A, func_809BCB78(play->state.gfxCtx, this->unk17C)); + Matrix_Translate(this->unk164.x, this->unk164.y, this->unk164.z, MTXMODE_APPLY); + POLY_XLU_DISP = SkelAnime_DrawFlex(play, this->unk194.skeleton, this->unk194.jointTable, this->unk194.dListCount, + func_809BD260, NULL, &this->actor, POLY_XLU_DISP); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_809BD490(EnKnight* this, PlayState* play) { + EnKnightEffect* var_s0 = play->specialEffects; + Player* player = GET_PLAYER(play); + s32 var_s4; + + for (var_s4 = 0; var_s4 < ARRAY_COUNT(D_809BEFE8); var_s4++, var_s0++) { + if (var_s0->unk2A != 0) { + var_s0->unk0.x += var_s0->unkC.x; + var_s0->unk0.y += var_s0->unkC.y; + var_s0->unk0.z += var_s0->unkC.z; + + var_s0->unk2C++; + + var_s0->unkC.x += var_s0->unk18.x; + var_s0->unkC.y += var_s0->unk18.y; + var_s0->unkC.z += var_s0->unk18.z; + + var_s0->unk18.y = BREG(56) * 0.01f + 1.0f; + + if (var_s0->unk2A == (u32)1) { // fake + Math_ApproachF(&var_s0->unk34, (KREG(59) * 0.01f + 1.0f) * var_s0->unk38, 0.1f, var_s0->unk38 * 0.1f); + + if (((s16)(BREG(60) + 0x6E) >= var_s0->unk2E) || + (var_s0->unk0.y < (BREG(62) + (this->actor.floorHeight + 30.0f)))) { + if ((s16)(BREG(60) + 0x6E) < var_s0->unk2E) { + var_s0->unk2E = BREG(60) + 0x6E; + } + var_s0->unk18.y = BREG(61) * 0.01f + 0.3f; + + var_s0->unkC.x *= 0.85f + BREG(59) * 0.01f; + var_s0->unkC.z *= 0.85f + BREG(59) * 0.01f; + + var_s0->unk38 = (BREG(58) * 0.1f + 2.0f) * 0.025f; + + if (var_s0->unkC.y < 0.0f) { + var_s0->unkC.y = 0.0f; + } + } + var_s0->unk2E -= (s16)(BREG(49) + 0xA); + if (var_s0->unk2E <= 0) { + var_s0->unk2E = 0; + var_s0->unk2A = 0; + } + if (this->unk15E == 0) { + f32 temp_fv0_3 = player->actor.world.pos.x - var_s0->unk0.x; + f32 temp_fv1_2 = (player->actor.world.pos.y + 25.0f) - var_s0->unk0.y; + f32 temp_fa0_2 = player->actor.world.pos.z - var_s0->unk0.z; + if ((SQ(temp_fv0_3) + SQ(temp_fv1_2) + SQ(temp_fa0_2)) < + ((BREG(57) * 0.1f + 1.0f) * ((2500.0f * var_s0->unk34) / 0.025f))) { + this->unk15E = 10; + func_800B8D10(play, &this->actor, 0.0f, 0, 0.0f, 1, 4); + } + } + } + } + } +} + +void func_809BD858(EnKnight* this, PlayState* play) { + GraphicsContext* gfxCtx = play->state.gfxCtx; + s16 i; + u8 materialFlag = 0; + EnKnightEffect* eff = play->specialEffects; + + OPEN_DISPS(gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPSetColorDither(POLY_XLU_DISP++, G_CD_BAYER); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_PATTERN); + + for (i = 0; i < ARRAY_COUNT(D_809BEFE8); i++, eff++) { + if (eff->unk2A != 1) { + continue; + } + + gDPPipeSync(POLY_XLU_DISP++); + + if (materialFlag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamMaterialDL); + gDPSetEnvColor(POLY_XLU_DISP++, 155, 145, 155, 128); + materialFlag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 155, 155, 255, eff->unk2E); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, (eff->unk2C + (i * 3)) * 3, (eff->unk2C + (i * 3)) * 15, 32, + 64, 1, 0, 0, 32, 32)); + + Matrix_Translate(eff->unk0.x, eff->unk0.y, eff->unk0.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_Scale(eff->unk34, eff->unk34, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamModelDL); + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Knight/z_en_knight.h b/src/overlays/actors/ovl_En_Knight/z_en_knight.h index 2d413fea3..c4a6a0f96 100644 --- a/src/overlays/actors/ovl_En_Knight/z_en_knight.h +++ b/src/overlays/actors/ovl_En_Knight/z_en_knight.h @@ -9,21 +9,106 @@ typedef void (*EnKnightActionFunc)(struct EnKnight*, PlayState*); typedef struct EnKnight { /* 0x000 */ Actor actor; - /* 0x144 */ s16 unk_144; - /* 0x146 */ char unk_146[0x2]; - /* 0x148 */ s8 unk_148; - /* 0x149 */ char unk_149[0x8]; - /* 0x151 */ s8 unk_151; - /* 0x152 */ char unk_152[0x1]; + /* 0x144 */ u16 unk_144; + /* 0x146 */ s16 unk146; + /* 0x148 */ u8 unk148; + /* 0x14A */ s16 unk14A[3]; + /* 0x150 */ char pad150[1]; + /* 0x151 */ u8 unk_151; + /* 0x152 */ u8 unk152; /* 0x153 */ u8 unk_153; /* 0x154 */ u8 unk_154; - /* 0x155 */ char unk_155[0x2CB]; + /* 0x156 */ s16 unk156; + /* 0x158 */ s16 unk158; + /* 0x15A */ s16 unk15A; + /* 0x15C */ s16 unk15C; + /* 0x15E */ s16 unk15E; + /* 0x160 */ s16 unk160; + /* 0x162 */ u8 unk162; + /* 0x164 */ Vec3f unk164; + /* 0x170 */ s16 unk170; + /* 0x172 */ s16 unk172; + /* 0x174 */ s16 unk174; + /* 0x176 */ s16 unk176; + /* 0x178 */ s16 unk178; + /* 0x17A */ s16 unk17A; + /* 0x17C */ f32 unk17C; + /* 0x180 */ f32 unk180; + /* 0x184 */ s16 unk184; + /* 0x186 */ s16 unk186; + /* 0x188 */ s16 unk188; + /* 0x18A */ s16 unk18A; + /* 0x18C */ s16 unk18C; + /* 0x18E */ s16 unk18E; + /* 0x190 */ u8 unk190; + /* 0x191 */ u8 unk191; + /* 0x192 */ u8 unk192; + /* 0x193 */ u8 unk193; + /* 0x194 */ SkelAnime unk194; + /* 0x1D8 */ f32 unk1D8; + /* 0x1DC */ Vec3f unk1DC[15]; + /* 0x290 */ u8 unk290; + /* 0x291 */ u8 unk291; + /* 0x292 */ u8 unk292; + /* 0x294 */ f32 unk294; + /* 0x298 */ f32 unk298; + /* 0x29C */ f32 unk29C; + /* 0x2A0 */ u8 unk2A0; + /* 0x2A1 */ u8 unk2A1; + /* 0x2A2 */ s16 unk2A2; + /* 0x2A4 */ f32 unk2A4; + /* 0x2A8 */ f32 unk2A8; + /* 0x2AC */ Vec3f unk2AC[2]; + /* 0x2C4 */ Vec3s unk2C4[29]; + /* 0x372 */ Vec3s unk372[29]; /* 0x420 */ EnKnightActionFunc actionFunc; - /* 0x424 */ char unk_424[0x25C]; + /* 0x424 */ EnKnightActionFunc unk424; + /* 0x428 */ s16 unk428; + /* 0x42C */ f32 unk42C; + /* 0x430 */ f32 unk430; + /* 0x434 */ Vec3f unk434; + /* 0x440 */ Vec3f unk440; + /* 0x44C */ u8 unk44C; + /* 0x450 */ f32 unk450; + /* 0x454 */ f32 unk454; + /* 0x458 */ f32 unk458; + /* 0x45C */ f32 unk45C; + /* 0x460 */ f32 unk460; + /* 0x464 */ f32 unk464; + /* 0x468 */ f32 unk468; + /* 0x46C */ f32 unk46C; + /* 0x470 */ f32 unk470; + /* 0x474 */ f32 unk474; + /* 0x478 */ s16 unk478; + /* 0x47C */ Vec3f unk47C; + /* 0x488 */ ColliderCylinder unk488; + /* 0x4D4 */ ColliderJntSph unk4D4; + /* 0x4F4 */ ColliderJntSphElement unk4F4[1]; + /* 0x534 */ ColliderJntSph unk534; + /* 0x554 */ ColliderJntSphElement unk554[1]; + /* 0x594 */ ColliderJntSph unk594; + /* 0x5B4 */ ColliderJntSphElement unk5B4[2]; + /* 0x634 */ ColliderCylinder unk634; /* 0x680 */ u8 unk_680; - /* 0x681 */ char unk_681[0x9]; + /* 0x684 */ u32 unk684; + /* 0x688 */ s16 unk688; /* 0x68A */ s16 unk_68A; - /* 0x68C */ char pad68C[0x48]; + /* 0x68C */ Vec3f unk68C; + /* 0x698 */ Vec3f unk698; + /* 0x6A4 */ f32 unk6A4; + /* 0x6A8 */ char pad6A8[4]; + /* 0x6AC */ s16 unk6AC; + /* 0x6B0 */ f32 unk6B0; + /* 0x6B4 */ u16 unk6B4; + /* 0x6B6 */ u16 unk6B6; + /* 0x6B8 */ u16 unk6B8; + /* 0x6BA */ char pad6BA[2]; + /* 0x6BC */ u16 unk6BC; + /* 0x6BE */ u16 unk6BE; + /* 0x6C0 */ u16 unk6C0; + /* 0x6C2 */ u16 unk6C2; + /* 0x6C4 */ u8 unk6C4; + /* 0x6C8 */ Vec3f unk6C8; } EnKnight; // size = 0x6D4 #endif // Z_EN_KNIGHT_H diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c index c8e0bdd42..8f539118a 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c @@ -5,6 +5,8 @@ */ #include "z_en_minideath.h" +#include "overlays/actors/ovl_En_Death/z_en_death.h" +#include "objects/object_death/object_death.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10) @@ -25,78 +27,124 @@ void func_808CB094(EnMinideath* this, PlayState* play); void func_808CB22C(EnMinideath* this, PlayState* play); void func_808CB454(EnMinideath* this, PlayState* play); void func_808CB59C(EnMinideath* this, PlayState* play); -void func_808CB6D4(EnMinideath* this, PlayState* play); -void func_808CB7CC(EnMinideath* this, PlayState* play); +void EnMinideath_Die(EnMinideath* this, PlayState* play); +void EnMinideath_Dead(EnMinideath* this, PlayState* play); -#if 0 -ActorInit En_Minideath_InitVars = { - /**/ ACTOR_EN_MINIDEATH, - /**/ ACTORCAT_ENEMY, - /**/ FLAGS, - /**/ OBJECT_DEATH, - /**/ sizeof(EnMinideath), - /**/ EnMinideath_Init, - /**/ EnMinideath_Destroy, - /**/ EnMinideath_Update, - /**/ NULL, +void func_808CA34C(EnMinideath* this); +void func_808CA7D4(EnMinideath* this); +void func_808CA8E0(EnMinideath* this); +void func_808CAAC8(EnMinideath* this); +void func_808CAB90(EnMinideath* this); +void func_808CAE00(EnMinideath* this); +void func_808CAF08(EnMinideath* this); +void EnMinideath_SetupDead(EnMinideath* this); + +const ActorInit En_Minideath_InitVars = { + ACTOR_EN_MINIDEATH, + ACTORCAT_ENEMY, + FLAGS, + OBJECT_DEATH, + sizeof(EnMinideath), + (ActorFunc)EnMinideath_Init, + (ActorFunc)EnMinideath_Destroy, + (ActorFunc)EnMinideath_Update, + (ActorFunc)NULL, }; // static ColliderJntSphElementInit sJntSphElementsInit[3] = { static ColliderJntSphElementInit D_808CBF50[3] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 15 }, 100 }, }, }; // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_808CBFBC = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_808CBF50, // sJntSphElementsInit, + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(D_808CBF50), + D_808CBF50, // sJntSphElementsInit, }; +typedef enum { + DMGEFF_NONE = 0, + DMGEFF_STUN = 1, + DMGEFF_FIRE_ARROW = 2, + DMGEFF_ICE_ARROW = 3, + DMGEFF_LIGHT_ARROW = 4, + DMGEFF_ZORA_BARRIER = 5 +} EnMinideathDamageEffect; + // static DamageTable sDamageTable = { static DamageTable D_808CBFCC = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(1, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(1, 0x0), - /* Goron punch */ DMG_ENTRY(1, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(1, 0x0), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(1, 0x5), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* Sword beam */ DMG_ENTRY(0, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0x0), + /* Deku Nut */ DMG_ENTRY(0, DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(0, DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(1, DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(1, DMGEFF_ZORA_BARRIER), + /* Normal shield */ DMG_ENTRY(0, DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DMGEFF_NONE), }; // sColChkInfoInit @@ -108,80 +156,754 @@ static InitChainEntry D_808CBFF4[] = { ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), }; -#endif +static s32 sItemDropTimer; +s32 D_808CC254; +s32 D_808CC258; +s32 D_808CC25C; -extern ColliderJntSphElementInit D_808CBF50[3]; -extern ColliderJntSphInit D_808CBFBC; -extern DamageTable D_808CBFCC; -extern CollisionCheckInfoInit D_808CBFEC; -extern InitChainEntry D_808CBFF4[]; +void EnMinideath_Init(Actor* thisx, PlayState* play) { + EnMinideath* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Init.s") + Actor_ProcessInitChain(thisx, D_808CBFF4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Destroy.s") + this->unk_158 = thisx->world.pos.y - thisx->parent->world.pos.y; + this->spawnShapeRot = thisx->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA268.s") + thisx->shape.rot.y = thisx->parent->shape.rot.y; + thisx->world.rot.y = thisx->parent->shape.rot.y; + thisx->flags &= ~ACTOR_FLAG_TARGETABLE; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA308.s") + Collider_InitAndSetJntSph(play, &this->collider, thisx, &D_808CBFBC, this->colliderElements); + CollisionCheck_SetInfo(&thisx->colChkInfo, &D_808CBFCC, &D_808CBFEC); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA34C.s") + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA458.s") + func_808CA34C(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA7D4.s") + this->number = thisx->params; + thisx->params = 0; + this->unk_149 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA860.s") + if (gSaveContext.eventInf[6] & 8) { + this->collider.base.atFlags |= AT_ON; + this->unk_149 = true; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA8E0.s") + func_808CABB0(this, play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CA8F4.s") + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + Math_Vec3f_Sum(&thisx->world.pos, &this->unk_160[i].unk_10, &this->unk_160[i].unk_4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAAC8.s") + func_808CAB90(this); + } else { + func_808CA7D4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAAEC.s") +void EnMinideath_Destroy(Actor* thisx, PlayState* play) { + EnMinideath* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAB90.s") + Collider_DestroyJntSph(play, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CABB0.s") +void EnMinideath_DropCollectible(Vec3f* spawnPos, PlayState* play) { + if (sItemDropTimer == 0 && Rand_ZeroOne() < 0.3f) { + if (Rand_ZeroOne() < 0.5f) { + Item_DropCollectible(play, spawnPos, ITEM00_ARROWS_10); + } else { + Item_DropCollectible(play, spawnPos, ITEM00_MAGIC_JAR_BIG); + } + sItemDropTimer = 800; // wait 40 seconds before next drop + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAC54.s") +void func_808CA308(EnMinideath* this, s32 arg1) { + if (this->unk_149 != arg1) { + this->unk_149 = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CACD8.s") + if (arg1 == true) { + this->actor.parent->params++; + } else { + this->actor.parent->params--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAE00.s") +void func_808CA34C(EnMinideath* this) { + MiniDeathStruct* phi_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAE18.s") + for (phi_s0 = this->unk_160, i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + phi_s0->unk_10.x = Rand_CenteredFloat(80.0f); + phi_s0->unk_10.y = Rand_ZeroFloat(40.0f); + phi_s0->unk_10.z = Rand_CenteredFloat(80.0f); + phi_s0->animFrame = (s32)Rand_ZeroFloat(9.0f) % MINIDEATH_ANIM_LENGTH; + phi_s0->unk_1C = ((s32)Rand_Next() >> 17); + phi_s0->unk_1E = ((s32)Rand_Next() >> 16); + phi_s0->unk_1 = 0; + phi_s0->unk_22 = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAF08.s") +void func_808CA458(EnMinideath* this, PlayState* play) { + s16 temp_s1; + MiniDeathStruct* phi_s0; + f32 phi_fv0; + f32 phi_fa0; + s32 i; + s32 phi_s7; + s32 phi_s3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CAF68.s") + phi_s3 = 0; + phi_s7 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB07C.s") + phi_s0 = this->unk_160; + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + if (phi_s0->unk_1 == 0) { + phi_s0->unk_10.x += 3.0f * Math_CosS(phi_s0->unk_1C) * Math_SinS(phi_s0->unk_1E); + phi_s0->unk_10.y += 3.0f * Math_SinS(phi_s0->unk_1C); + phi_s0->unk_10.z += 3.0f * Math_CosS(phi_s0->unk_1C) * Math_CosS(phi_s0->unk_1E); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB094.s") + if (this->actionFunc == func_808CA860) { + phi_fv0 = 100.0f; + phi_fa0 = SQ(phi_fv0); + } else if (this->actionFunc == func_808CB094 || this->actionFunc == func_808CB454) { + phi_fv0 = 20.0f; + phi_fa0 = SQ(20.0f); + } else { + phi_fv0 = 40.0f; + phi_fa0 = SQ(40.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB0C8.s") + if (phi_s0->unk_10.y < 0.0f || phi_fv0 < phi_s0->unk_10.y || + phi_fa0 < SQ(phi_s0->unk_10.x) + SQ(phi_s0->unk_10.z)) { + temp_s1 = Math_Atan2S_XY(sqrtf(SQ(phi_s0->unk_10.x) + SQ(phi_s0->unk_10.z)), phi_s0->unk_10.y); + phi_s0->unk_1C = -1 * temp_s1 + ((s32)Rand_Next() >> 19); + temp_s1 = Math_Atan2S_XY(phi_s0->unk_10.z, phi_s0->unk_10.x); + phi_s0->unk_1E = temp_s1 + ((s32)Rand_Next() >> 19) + 0x8000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB22C.s") + phi_s3++; + } else if (phi_s0->unk_1 == 1) { + phi_s0->unk_4.y += phi_s0->unk_10.y; + phi_s0->unk_1E += 0x1800; + phi_s0->unk_10.y -= 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB418.s") + if (phi_s0->unk_4.y < this->actor.parent->home.pos.y) { + phi_s0->unk_4.y = this->actor.parent->home.pos.y; + func_800B3030(play, &phi_s0->unk_4, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(play, &phi_s0->unk_4, 11, NA_SE_EN_EXTINCT); + EnMinideath_DropCollectible(&phi_s0->unk_4, play); + phi_s0->unk_1 = 2; + } + } else if (phi_s0->unk_1 == 2) { + if (phi_s0->unk_22 > 0) { + phi_s0->unk_22--; + } else if (this->actionFunc == func_808CABB0) { + Math_Vec3f_Diff(&this->actor.parent->focus.pos, &this->actor.world.pos, &phi_s0->unk_10); + phi_s0->unk_1 = 0; + this->collider.elements[i].info.bumperFlags |= BUMP_ON; + this->collider.elements[i].info.toucherFlags |= TOUCH_ON; + phi_s7 = 1; + phi_s3++; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB454.s") + if (phi_s7 && phi_s3 > 1) { + func_808CA308(this, true); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB524.s") +void func_808CA7D4(EnMinideath* this) { + this->actor.speed = 6.0f; + this->actor.world.pos.x = Rand_CenteredFloat(600.0f) + this->actor.parent->world.pos.x; + this->actor.world.pos.z = Rand_CenteredFloat(600.0f) + this->actor.parent->world.pos.z; + this->actor.shape.rot.y = (s32)Rand_Next() >> 16; + this->actor.shape.rot.x = 0; + this->unk_150.y = this->actor.shape.rot.y; + this->actionFunc = func_808CA860; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB59C.s") +void func_808CA860(EnMinideath* this, PlayState* play) { + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = ((s32)Rand_Next() >> 18) + this->actor.wallYaw; + } + if (this->actor.params == MINIDEATH_ACTION_7) { + func_808CA8E0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB6A8.s") +void func_808CA8E0(EnMinideath* this) { + this->actionFunc = func_808CA8F4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB6D4.s") +void func_808CA8F4(EnMinideath* this, PlayState* play) { + EnDeath* parent; + Vec3f sp38; + s32 phi_v0; + s16 angle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB7B8.s") + Math_StepToF(&this->actor.speed, 15.0f, 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB7CC.s") + if (this->actor.child == NULL) { + phi_v0 = 0; + angle = 0; + } else { + angle = 0x5555; + if (this->number == 6) { + phi_v0 = 1; + } else if (this->number == 12) { + phi_v0 = 2; + angle = -0x5556; + } else { + phi_v0 = -1; + Math_Vec3f_Copy(&sp38, &this->actor.child->world.pos); + angle = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB810.s") + if (phi_v0 != -1) { + parent = (EnDeath*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/func_808CB8F4.s") + angle += parent->coreRotation; + sp38.x = this->actor.parent->world.pos.x + Math_SinS(angle) * parent->coreVelocity; + sp38.z = this->actor.parent->world.pos.z + Math_CosS(angle) * parent->coreVelocity; + sp38.y = this->actor.parent->world.pos.y + phi_v0 * 20; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_WorldYawTowardPoint(&this->actor, &sp38), 2, 0x1000, 0x100); + if (this->actor.parent->scale.z > 0.0f) { + sp38.y = this->actor.parent->world.pos.y + this->unk_158; + } + Math_SmoothStepToS(&this->actor.shape.rot.x, Actor_WorldPitchTowardPoint(&this->actor, &sp38), 2, 0x1000, 0x100); + if (this->actor.params == MINIDEATH_ACTION_8) { + func_808CAAC8(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Minideath/EnMinideath_Update.s") +void func_808CAAC8(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CAAEC; + this->actor.speed = 5.0f; +} + +void func_808CAAEC(EnMinideath* this, PlayState* play) { + Actor_WorldDistXYZToPoint(&this->actor, &this->actor.parent->focus.pos); + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_WorldYawTowardPoint(&this->actor, &this->actor.parent->focus.pos), 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, Actor_WorldPitchTowardPoint(&this->actor, &this->actor.parent->focus.pos), + 0x800); + if (this->actor.params == MINIDEATH_ACTION_9) { + this->collider.base.atFlags |= AT_ON; + func_808CAF08(this); + } +} + +void func_808CAB90(EnMinideath* this) { + this->actor.shape.rot.x = 0; + this->actionFunc = func_808CABB0; + this->actor.speed = 0.0f; +} + +void func_808CABB0(EnMinideath* this, PlayState* play) { + s16 sp1E = this->spawnShapeRot + this->actor.parent->shape.rot.y; + + this->actor.world.pos.x = this->actor.parent->world.pos.x + Math_SinS(sp1E) * 60.0f; + this->actor.world.pos.z = this->actor.parent->world.pos.z + Math_CosS(sp1E) * 60.0f; + this->actor.world.pos.y = this->actor.parent->world.pos.y + this->unk_158; + this->actor.shape.rot.y = this->actor.parent->shape.rot.y; +} + +void func_808CAC54(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actor.speed = 8.0f; + func_800BE33C(&this->actor.parent->world.pos, &this->actor.world.pos, &this->unk_150, false); + if (D_808CC258 != 0) { + this->timer = D_808CC258; + } else { + this->timer = 200; + } + func_808CA308(this, false); + this->actionFunc = func_808CACD8; +} + +void func_808CACD8(EnMinideath* this, PlayState* play) { + f32 temp_fv0; + f32 temp_fv1; + + Math_StepToF(&this->actor.speed, 6.0f, 0.5f); + + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = ((s32)Rand_Next() >> 18) + this->actor.wallYaw; + } + + if (Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480)) { + temp_fv0 = this->actor.world.pos.y; + temp_fv1 = this->actor.parent->home.pos.y; + + if (temp_fv0 < temp_fv1 + 50.0f) { + this->unk_150.x = -0x800 - ((u32)Rand_Next() >> 20); + } else if (temp_fv0 > temp_fv1 + 200.0f) { + this->unk_150.x = ((u32)Rand_Next() >> 20) + 0x800; + } + } + + if (this->timer == 0) { + func_808CAE00(this); + } else { + this->timer--; + } +} + +void func_808CAE00(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CAE18; +} + +void func_808CAE18(EnMinideath* this, PlayState* play) { + s32 pad; + f32 temp_fv0 = Actor_WorldDistXYZToPoint(&this->actor, &this->actor.parent->focus.pos); + f32 phi_fa0 = temp_fv0 * 0.016666668f; + + if (phi_fa0 > 1.0f) { + phi_fa0 = 1.0f; + } + Math_StepToF(&this->actor.speed, 6.0f * phi_fa0, 0.5f); + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_WorldYawTowardPoint(&this->actor, &this->actor.parent->focus.pos), 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, Actor_WorldPitchTowardPoint(&this->actor, &this->actor.parent->focus.pos), + 0x800); + if (temp_fv0 < 30.0f) { + func_808CAF08(this); + } +} + +void func_808CAF08(EnMinideath* this) { + s32 phi_v0; + + this->actor.speed = 0.0f; + func_808CA308(this, true); + + for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(this->unk_160); phi_v0++) { + this->unk_160[phi_v0].unk_22 = 0; + } + this->actionFunc = func_808CAF68; +} + +void func_808CAF68(EnMinideath* this, PlayState* play) { + Vec3f target; + f32 dist; + s16 sp26; + s32 done; + + done = Math_ScaledStepToS(&this->actor.shape.rot.y, this->spawnShapeRot + this->actor.parent->shape.rot.y, 0x800); + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x800); + sp26 = this->spawnShapeRot + this->actor.parent->shape.rot.y; + target.x = this->actor.parent->world.pos.x + Math_SinS(sp26) * 60.0f; + target.z = this->actor.parent->world.pos.z + Math_CosS(sp26) * 60.0f; + target.y = this->actor.parent->world.pos.y + this->unk_158; + + dist = Math_Vec3f_StepTo(&this->actor.world.pos, &target, 10.0f); + if (done && dist < 20.0f) { + func_808CAB90(this); + } +} + +void func_808CB07C(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actionFunc = func_808CB094; +} + +void func_808CB094(EnMinideath* this, PlayState* play) { + Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.parent->focus.pos, 5.0f); +} + +void func_808CB0C8(EnMinideath* this, PlayState* play) { + s32 phi_a2; + s32 phi_v1; + s32 phi_a1; + + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->actor.speed = 8.0f; + + if (this->number >= 10) { + phi_v1 = 19 - this->number; + phi_a1 = 1; + phi_a2 = 0; + } else { + phi_v1 = 9 - this->number; + phi_a1 = -1; + phi_a2 = 0x200; + } + this->actor.shape.rot.y = this->actor.parent->shape.rot.y + (phi_a1 * 0x4000) + ((phi_v1 * 0x2000) * phi_a1); + this->actor.shape.rot.x = (phi_a2 - phi_v1 * 0x400) + 0xC00; + + this->actor.world.pos.x = this->actor.parent->focus.pos.x + Math_SinS(this->actor.shape.rot.y) * 60.0f; + this->actor.world.pos.z = this->actor.parent->focus.pos.z + Math_CosS(this->actor.shape.rot.y) * 60.0f; + this->actor.world.pos.y = this->actor.parent->focus.pos.y - Math_SinS(this->actor.shape.rot.x) * 60.0f; + + func_808CA34C(this); + this->timer = 100; + func_808CA308(this, false); + + D_808CC254 = 0; + + if (this->actor.child == NULL || this->number == 9) { + this->unk_15C = &GET_PLAYER(play)->actor; + } else { + this->unk_15C = this->actor.child; + } + this->actionFunc = func_808CB22C; +} + +void func_808CB22C(EnMinideath* this, PlayState* play) { + Vec3f sp34; + s16 sp32 = 0; + + Math_StepToF(&this->actor.speed, 6.0f, 0.2f); + if (this->timer > 0) { + this->timer--; + } + + if (this->unk_15C->id != ACTOR_EN_MINIDEATH) { + if (this->timer == 0) { + this->unk_15C = this->actor.parent; + } + Math_Vec3f_Copy(&sp34, &this->unk_15C->focus.pos); + if (Actor_WorldDistXYZToPoint(&this->actor, &sp34) > 200.0f) { + if (this->number < 10) { + sp32 = -0x1C00; + } else { + sp32 = 0x1C00; + } + sp34.y += 50.0f; + } + } else if (((EnMinideath*)this->unk_15C)->actionFunc != func_808CB22C) { + Math_Vec3f_Copy(&sp34, &this->actor.parent->focus.pos); + } else { + Math_Vec3f_Copy(&sp34, &this->unk_15C->focus.pos); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_WorldYawTowardPoint(&this->actor, &sp34) + sp32, 5, 0xC00, 0x80); + Math_SmoothStepToS(&this->actor.shape.rot.x, Actor_WorldPitchTowardPoint(&this->actor, &sp34), 5, 0xC00, 0x80); + if ((this->collider.base.atFlags & AT_HIT) && this->timer > 0) { + D_808CC254 += 1; + } + if (this->timer == 0 && Actor_WorldDistXYZToPoint(&this->actor, &this->actor.parent->focus.pos) < 50.0f) { + func_808CAF08(this); + } +} + +void func_808CB418(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->timer = 10; + func_808CA34C(this); + this->actionFunc = func_808CB454; +} + +void func_808CB454(EnMinideath* this, PlayState* play) { + Vec3f target; + + if (this->timer > 0) { + this->timer--; + } + target.x = (Math_SinS(this->actor.parent->shape.rot.y) * 20.0f) + this->actor.parent->focus.pos.x; + target.z = (Math_CosS(this->actor.parent->shape.rot.y) * 20.0f) + this->actor.parent->focus.pos.z; + target.y = this->actor.parent->focus.pos.y; + Math_Vec3f_StepTo(&this->actor.world.pos, &target, 5.0f); + if (this->timer == 0 && ((EnMinideath*)this->actor.child)->actionFunc != func_808CB22C) { + func_808CAB90(this); + } +} + +void func_808CB524(EnMinideath* this) { + s32 i; + + this->actor.params = MINIDEATH_ACTION_CONTINUE; + func_808CA308(this, false); + this->collider.base.atFlags &= ~AT_ON; + + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + this->unk_160[i].unk_1 = 0; + } + + this->unk_150.y = this->actor.shape.rot.y; + this->unk_150.x = this->actor.shape.rot.x; + this->actionFunc = func_808CB59C; +} + +void func_808CB59C(EnMinideath* this, PlayState* play) { + f32 temp_fv0; + f32 temp_fv1; + + Math_StepToF(&this->actor.speed, 5.0f, 0.2f); + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_150.y, 0x480) && (this->actor.bgCheckFlags & 8)) { + // Fly away from walls + this->unk_150.y = ((s32)Rand_Next() >> 0x12) + this->actor.wallYaw; + } + if (Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480)) { + temp_fv0 = this->actor.world.pos.y; + temp_fv1 = this->actor.parent->home.pos.y; + if (temp_fv0 < (temp_fv1 + 50.0f)) { + this->unk_150.x = -0x800 - ((u32)Rand_Next() >> 20); + } else if (temp_fv0 > (temp_fv1 + 200.0f)) { + this->unk_150.x = ((u32)Rand_Next() >> 20) + 0x800; + } + } +} + +void EnMinideath_SetupDie(EnMinideath* this) { + this->actor.params = MINIDEATH_ACTION_CONTINUE; + this->unk_150.x = 0x4000; + this->actionFunc = EnMinideath_Die; + this->actor.gravity = -0.5f; +} + +void EnMinideath_Die(EnMinideath* this, PlayState* play) { + MiniDeathStruct* phi_s0; + s32 i; + s32 phi_s2 = 0; + + Math_StepToF(&this->actor.speed, 0.0f, 0.2f); + Math_ScaledStepToS(&this->actor.shape.rot.x, this->unk_150.x, 0x480); + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + + if (this->actor.bgCheckFlags & 1) { + this->actor.speed = 0.0f; + + for (phi_s0 = this->unk_160, i = 0; i < ARRAY_COUNT(this->unk_160); i++, phi_s0++) { + if (Math_StepToF(&phi_s0->unk_10.y, 0.0f, 7.0f)) { + phi_s2++; + } + } + + if (phi_s2 == ARRAY_COUNT(this->unk_160)) { + EnMinideath_SetupDead(this); + } + } +} + +void EnMinideath_SetupDead(EnMinideath* this) { + this->actionFunc = EnMinideath_Dead; +} + +void EnMinideath_Dead(EnMinideath* this, PlayState* play) { + if (this->actor.parent->update == NULL) { + Actor_Kill(&this->actor); + } else { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } +} + +void EnMinideath_SetNextAction(EnMinideath* this, PlayState* play) { + s16 action = this->actor.params; + + if (action == MINIDEATH_ACTION_6) { + func_808CB524(this); + } else if (action == MINIDEATH_ACTION_2) { + func_808CAE00(this); + } else if (action == MINIDEATH_ACTION_3) { + func_808CB07C(this); + } else if (action == MINIDEATH_ACTION_4) { + if (this->number == 0 || this->number == 10) { + func_808CB418(this); + } else { + func_808CB0C8(this, play); + } + } else if (action == MINIDEATH_ACTION_1) { + func_808CAC54(this); + } else if (action == MINIDEATH_ACTION_DIE) { + EnMinideath_SetupDie(this); + } +} + +void func_808CB8F4(EnMinideath* this, PlayState* play) { + s32 temp_a0_2; + EnMinideath* temp_a0_3; + s32 phi_a2; + s32 phi_v0_2; + s32 phi_a0; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actor.colChkInfo.damageEffect == DMGEFF_STUN) { + if (this->actionFunc == func_808CABB0 || this->actionFunc == func_808CAF68) { + D_808CC258 = 5; + } else if (this->actionFunc == func_808CB22C) { + EnMinideath** miniDeaths = (EnMinideath**)((EnDeath*)this->actor.parent)->miniDeaths; + + for (temp_a0_2 = this->number - 1; temp_a0_2 >= 0; temp_a0_2--) { + temp_a0_3 = miniDeaths[temp_a0_2]; + + if (temp_a0_3->unk_15C == &this->actor) { + temp_a0_3->unk_15C = this->unk_15C; + break; + } + } + + this->timer = 0; + this->unk_15C = &GET_PLAYER(play)->actor; + } + } else { + for (phi_a2 = 0; phi_a2 < ARRAY_COUNT(this->colliderElements); phi_a2++) { + if (this->collider.elements[phi_a2].info.bumperFlags & BUMP_HIT) { + this->collider.elements[phi_a2].info.bumperFlags &= ~(BUMP_ON | BUMP_HIT); + this->collider.elements[phi_a2].info.toucherFlags &= ~(TOUCH_ON | TOUCH_HIT); + this->unk_160[phi_a2].unk_10.y = -1.0f; + this->unk_160[phi_a2].unk_1 = 1; + this->unk_160[phi_a2].unk_1E = this->actor.shape.rot.y; + this->unk_160[phi_a2].unk_22 = 60; + + if ((this->actionFunc == func_808CABB0 || this->actionFunc == func_808CAF68) && + this->actor.colChkInfo.damageEffect == DMGEFF_LIGHT_ARROW) { + D_808CC258 = 200; + } + } + } + + phi_a0 = 0; + for (phi_v0_2 = 0; phi_v0_2 < ARRAY_COUNT(this->unk_160); phi_v0_2++) { + if (this->unk_160[phi_v0_2].unk_1 != 0) { + phi_a0++; + } + } + + if (phi_a0 > 1) { + func_808CA308(this, false); + } + + if (D_808CC25C == 0) { + Actor_PlaySfx(&this->actor, NA_SE_EN_FFLY_DEAD); + D_808CC25C = 1; + } + } + } +} + +void EnMinideath_Update(Actor* thisx, PlayState* play) { + EnMinideath* this = THIS; + s32 pad; + ColliderJntSphElement* elem; + s32 temp; + s32 i; + MiniDeathStruct* phi_s0; + EnMinideath* phi_s0_3; + + if (sItemDropTimer > 0) { + sItemDropTimer--; + } + + if (this->actionFunc != EnMinideath_Dead) { + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++) { + if (this->unk_160[i].unk_1 == 0) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_BAT_FLY - SFX_FLAG); + break; + } + } + } + + func_808CB8F4(this, play); + + EnMinideath_SetNextAction(this, play); + this->actionFunc(this, play); + + if (this->actionFunc != EnMinideath_Dead) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -this->actor.shape.rot.x; + + if (this->actionFunc == EnMinideath_Die) { + Actor_MoveWithGravity(&this->actor); + } else { + Actor_MoveWithoutGravity(&this->actor); + } + + if (this->actionFunc != func_808CABB0 && this->actionFunc != func_808CAF68) { + Actor_UpdateBgCheckInfo(play, &this->actor, 30.0f, 50.0f, 80.0f, 7); + } + + if (this->actionFunc != EnMinideath_Die) { + func_808CA458(this, play); + } + + Actor_SetFocus(&this->actor, 0.0f); + + phi_s0 = this->unk_160; + elem = this->collider.elements; + for (i = 0; i != ARRAY_COUNT(this->colliderElements); i++) { + if (phi_s0->unk_1 == 0) { + Math_Vec3f_Sum(&this->actor.world.pos, &phi_s0->unk_10, &phi_s0->unk_4); + + if (this->actionFunc != EnMinideath_Die) { + phi_s0->animFrame++; + if (phi_s0->animFrame == MINIDEATH_ANIM_LENGTH) { + phi_s0->animFrame = 0; + } + } + + elem->dim.worldSphere.center.x = phi_s0->unk_4.x; + elem->dim.worldSphere.center.y = phi_s0->unk_4.y; + elem->dim.worldSphere.center.z = phi_s0->unk_4.z; + } + phi_s0++; + elem++; + } + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + this->attackTimer = 40; + Actor_PlaySfx(&this->actor, NA_SE_EN_FFLY_ATTACK); + } + if (this->collider.base.atFlags & AT_ON) { + temp = (this->actionFunc == func_808CABB0) ? (play->gameplayFrames % 4) : 4; + + if (temp == 4 || temp == (this->number & 3)) { + if (this->attackTimer == 0 && this->actor.parent->shape.rot.x == 0) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); + } + if (this->actionFunc != func_808CB094) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); + } + } + } + if (this->attackTimer > 0) { + this->attackTimer--; + } + if (this->number == 19) { + phi_s0_3 = NULL; + D_808CC25C = 0; + + if (D_808CC258 != 0) { + do { + phi_s0_3 = + (EnMinideath*)SubS_FindActor(play, &phi_s0_3->actor, ACTORCAT_ENEMY, ACTOR_EN_MINIDEATH); + if (phi_s0_3 != NULL) { + func_808CAC54(phi_s0_3); + phi_s0_3 = (EnMinideath*)phi_s0_3->actor.next; + } + } while (phi_s0_3 != NULL); + + play->envCtx.lightSettingOverride = 28; + + if (D_808CC258 == 5) { + ((EnDeath*)this->actor.parent)->unk_2FC = 5; + } else { + ((EnDeath*)this->actor.parent)->unk_2FC = 20; + } + D_808CC258 = 0; + } else if (D_808CC254 >= 5) { + do { + phi_s0_3 = + (EnMinideath*)SubS_FindActor(play, &phi_s0_3->actor, ACTORCAT_ENEMY, ACTOR_EN_MINIDEATH); + if (phi_s0_3 != NULL) { + phi_s0_3->timer = 0; + phi_s0_3 = (EnMinideath*)phi_s0_3->actor.next; + } + } while (phi_s0_3 != NULL); + D_808CC254 = 0; + } + } + } +} diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h index 0a08318ab..2c1c35869 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h @@ -7,10 +7,47 @@ struct EnMinideath; typedef void (*EnMinideathActionFunc)(struct EnMinideath*, PlayState*); +// "animation" length +#define MINIDEATH_ANIM_LENGTH 9 + +typedef enum { + MINIDEATH_ACTION_CONTINUE, // continue with current action until it is changed + MINIDEATH_ACTION_1, // scatter after light arrows? + MINIDEATH_ACTION_2, // gomess damaged + MINIDEATH_ACTION_3, + MINIDEATH_ACTION_4, // chase player? + MINIDEATH_ACTION_DIE, // dead? + MINIDEATH_ACTION_6, + MINIDEATH_ACTION_7, + MINIDEATH_ACTION_8, + MINIDEATH_ACTION_9 +} MinideathAction; + +typedef struct { + /* 0x00 */ u8 animFrame; + /* 0x01 */ u8 unk_1; + /* 0x04 */ Vec3f unk_4; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ s16 unk_1C; + /* 0x1E */ s16 unk_1E; + /* 0x20 */ char unk_20[0x2]; + /* 0x22 */ s16 unk_22; +} MiniDeathStruct; // size = 0x24 + typedef struct EnMinideath { - /* 0x000 */ Actor actor; - /* 0x144 */ EnMinideathActionFunc actionFunc; - /* 0x148 */ char unk_148[0x164]; + /* 0x0000 */ Actor actor; + /* 0x0144 */ EnMinideathActionFunc actionFunc; + /* 0x0148 */ u8 number; + /* 0x0149 */ u8 unk_149; + /* 0x014A */ s16 timer; + /* 0x014C */ s16 spawnShapeRot; + /* 0x014E */ s16 attackTimer; + /* 0x0150 */ Vec3s unk_150; // move direction? + /* 0x0158 */ f32 unk_158; + /* 0x015C */ Actor* unk_15C; + /* 0x0160 */ MiniDeathStruct unk_160[3]; + /* 0x01CC */ ColliderJntSph collider; + /* 0x01EC */ ColliderJntSphElement colliderElements[3]; } EnMinideath; // size = 0x2AC #endif // Z_EN_MINIDEATH_H diff --git a/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c index ae491fbf0..aa1ed5f10 100644 --- a/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c +++ b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c @@ -5,6 +5,7 @@ */ #include "z_en_wdhand.h" +#include "objects/object_wdhand/object_wdhand.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY) @@ -15,7 +16,22 @@ void EnWdhand_Destroy(Actor* thisx, PlayState* play); void EnWdhand_Update(Actor* thisx, PlayState* play); void EnWdhand_Draw(Actor* thisx, PlayState* play); -#if 0 +void func_80AF4FF8(EnWdhand* this, PlayState* play); +void func_80AF4A88(EnWdhand* this, PlayState* play); +void func_80AF4C64(EnWdhand* this, PlayState* play); +void func_80AF4F30(EnWdhand* this, PlayState* play); +void func_80AF4FF8(EnWdhand* this, PlayState* play); +void func_80AF520C(EnWdhand* this, PlayState* play); +void func_80AF5820(EnWdhand* this, PlayState* play); + +void func_80AF4608(EnWdhand* this, Vec3f* dst); +void func_80AF4964(EnWdhand* this); +void func_80AF4ED0(EnWdhand* this); +void func_80AF4C18(EnWdhand* this); +void func_80AF4F6C(EnWdhand* this); +void func_80AF5130(EnWdhand* this, PlayState* play); +void func_80AF488C(Vec3s* dst, Vec3f* src); + ActorInit En_Wdhand_InitVars = { /**/ ACTOR_EN_WDHAND, /**/ ACTORCAT_ENEMY, @@ -63,7 +79,7 @@ static ColliderJntSphElementInit D_80AF63E0[7] = { // static ColliderJntSphInit sJntSphInit = { static ColliderJntSphInit D_80AF64DC = { { COLTYPE_HIT0, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_80AF63E0, // sJntSphElementsInit, + ARRAY_COUNT(D_80AF63E0), D_80AF63E0, // sJntSphElementsInit, }; // sColChkInfoInit @@ -105,63 +121,641 @@ static DamageTable D_80AF64F4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; +Vec3f D_80AF6514 = { 0.0f, 0.0f, 0.0f }; +Vec3f D_80AF6520 = { 0.0f, 0.05f, 0.0f }; + +void EnWdhand_Init(Actor* thisx, PlayState* play) { + EnWdhand* this = THIS; + s32 i; + Vec3f sp4C; + + SkelAnime_InitFlex(play, &this->unk144, &object_wdhand_Skel_001E20, &object_wdhand_Anim_000854, this->unk188, this->unk1B8, 8); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &D_80AF64F4, &D_80AF64EC); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecY(3.0f, &this->unk25C[1]); + Matrix_MtxFCopy(&this->unk21C, Matrix_GetCurrent()); + Matrix_MtxFToYXZRot(&this->unk21C, &this->actor.shape.rot, 0); + Matrix_Transpose(&this->unk21C); + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80AF4608(this, &sp4C); + this->actor.speed = sp4C.z; + this->actor.velocity.y = sp4C.y; + this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speed; + this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speed; + Collider_InitAndSetJntSph(play, &this->unk274, &this->actor, &D_80AF64DC, this->unk294); + + for (i = 0; i < ARRAY_COUNT(this->unk294); i++) { + ColliderJntSphElement* elem = &this->unk274.elements[i]; + elem->dim.worldSphere.radius = elem->dim.modelSphere.radius; + func_80AF488C(&elem->dim.worldSphere.center, &this->actor.world.pos); + } + + for (i = 0; i < 3; i++) { + this->unk210[i] = 1.0f; + } + + this->unk1EC[0].x = -1; + this->unk1EC[0].y = 0; + this->actor.world.rot.x = 0; + this->actor.world.rot.z = Math_Atan2S_XY(this->unk21C.mf[2][1], this->unk21C.mf[0][1]); + this->actor.hintId = 0xA; + func_80AF4964(this); +} + +void EnWdhand_Destroy(Actor* thisx, PlayState* play) { + EnWdhand* this = THIS; + + Collider_DestroyJntSph(play, &this->unk274); +} + +void func_80AF4608(EnWdhand *this, Vec3f* dst) { + s32 var_v0; + + var_v0 = this->actor.params & 0x7F; + if (var_v0 == 0x7F) { + var_v0 = 0x28; + } + dst->y = var_v0 * 0.2f; + + var_v0 = (this->actor.params >> 7) & 0x7F; + if (var_v0 == 0x7F) { + var_v0 = 0x28; + } + dst->z = var_v0 * 0.2f; + + dst->x = 0.0f; +} + +void func_80AF4670(EnWdhand* this, Player* player, s16* arg2, s16* arg3) { + Vec3f sp24; + Vec3f sp18; + + Math_Vec3f_Diff(&player->bodyPartsPos[3], &this->actor.world.pos, &sp24); + Matrix_Put(&this->unk21C); + Matrix_MultVec3f(&sp24, &sp18); + *arg3 = Actor_WorldYawTowardPoint(&this->actor, &sp18); + *arg2 = Actor_WorldPitchTowardPoint(&this->actor, &sp18) + 0x4000; +} + +void func_80AF46F0(EnWdhand* this, s32 arg1, s32 arg2, Vec3f* arg3) { + MtxF* sp24 = Matrix_GetCurrent(); + f32 scale; + + Matrix_RotateZYX(this->unk1EC[arg1 + 1].x, this->unk1EC[arg1 + 1].y, 0, MTXMODE_APPLY); + if (arg2 != 0) { + Matrix_RotateYS((s16) (this->unk1EC[arg1 + 1].y * -1), MTXMODE_APPLY); + } + if (arg1 == 3) { + if (this->unk20C > 1.0f) { + if (this->unk20C > 1.5f) { + scale = 1.5f; + } else { + scale = this->unk20C; + } + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + } + } else { + if ((this->unk210[arg1] < 1.0f) || (this->unk20C > 1.0f)) { + if (this->unk210[arg1] < 0.1f) { + Matrix_Scale(0.0f, this->unk20C * this->unk210[arg1], 0.0f, MTXMODE_APPLY); + } else { + Matrix_Scale(1.0f, this->unk20C * this->unk210[arg1], 1.0f, MTXMODE_APPLY); + } + } + } + sp24->mf[3][0] = arg3->x; + sp24->mf[3][1] = arg3->y; + sp24->mf[3][2] = arg3->z; +} + +void func_80AF488C(Vec3s* dst, Vec3f* src) { + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; +} + +s16 func_80AF48D0(EnWdhand* this, s32 arg1) { + return this->unk1EC[arg1 + 1].z * Math_SinF((this->unk1EC[0].z - (arg1 * 0x14)) * 0.07853982f); +} + +void func_80AF4964(EnWdhand* this) { + s32 var_s0; + + Animation_MorphToLoop(&this->unk144, &object_wdhand_Anim_000854, -5.0f); + if (this->actionFunc != func_80AF4FF8) { + this->unk1EC[0].z = 0x50; + this->unk1EC[1].y = Rand_Next() >> 0x10; + + for (var_s0 = 1; var_s0 < 4; var_s0++) { + this->unk1EC[var_s0 + 1].y = this->unk1EC[var_s0].y + (s32)Rand_ZeroFloat((f32)0x2000) + 0x8000; + } + + for (var_s0 = 0; var_s0 < 4; var_s0++) { + this->unk1EC[var_s0 + 1].z = Rand_S16Offset(0x1800, 0x1000); + } + } + + for (var_s0 = 0; var_s0 < 4; var_s0++) { + this->unk1EC[var_s0 + 1].x = func_80AF48D0(this, var_s0); + } + + this->actionFunc = func_80AF4A88; + this->unk20C = 1.0f; +} + +void func_80AF4A88(EnWdhand* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s32 var_s1; + s16 sp4E; + s16 sp4C; + + SkelAnime_Update(&this->unk144); + + this->unk1EC[0].z--; + + for (var_s1 = 0; var_s1 < 4; var_s1++) { + this->unk1EC[var_s1 + 1].x = func_80AF48D0(this, var_s1); + if (this->unk1EC[0].z == 0x14 * var_s1) { + if (var_s1 != 0) { + this->unk1EC[var_s1 + 1].y = this->unk1EC[var_s1].y + (s32)Rand_CenteredFloat(16384.0f); + this->unk1EC[var_s1 + 1].y -= 0x8000; + } else { + this->unk1EC[1].y += (s16)(s32)Rand_CenteredFloat(16384.0f); + } + this->unk1EC[var_s1 + 1].z = Rand_S16Offset(0x1800, 0x1000); + } + } + + if (this->unk1EC[0].z == 0) { + this->unk1EC[0].z = 0x50; + } + + if (!(player->stateFlags2 & 0x80) && (this->actor.xyzDistToPlayerSq < SQ(120.75f))) { + func_80AF4670(this, player, &sp4E, &sp4C); + if (ABS_ALT(sp4E) <= 0x4000) { + func_80AF4C18(this); + } + } +} + +void func_80AF4C18(EnWdhand* this) { + Animation_MorphToPlayOnce(&this->unk144, &object_wdhand_Anim_000534, -5.0f); + this->unk1EC[0].z = 5; + this->actionFunc = func_80AF4C64; +} + +void func_80AF4C64(EnWdhand* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s32 var_s0 = 1; + s32 var_s1; + s16 sp6A; + s16 sp68; + + SkelAnime_Update(&this->unk144); + if (this->unk1EC[0].z > 0) { + this->unk1EC[0].z--; + if (this->unk1EC[0].z == 0) { + this->unk274.base.atFlags |= 1; + } + } else { + Math_StepToF(&this->unk20C, 1.5f, 0.05f); + func_80AF4670(this, player, &sp6A, &sp68); + + for (var_s1 = 0; var_s1 < 4; var_s1++) { + s16 var_v1 = sp68 - this->unk1EC[1 + var_s1].y; + + if (ABS_ALT(var_v1) < 0x4000) { + var_s0 &= Math_ScaledStepToS(&this->unk1EC[1 + var_s1].x, sp6A, (s16)(s32)((var_s1 * 0.1f + 1.0f) * 1920.0f)); + var_s0 &= Math_ScaledStepToS(&this->unk1EC[1 + var_s1].y, sp68, 0x800); + } else { + var_s0 &= Math_ScaledStepToS(&this->unk1EC[1 + var_s1].x, -sp6A, (s16)(s32)((var_s1 * 0.1f + 1.0f) * 1920.0f)); + var_s0 &= Math_ScaledStepToS(&this->unk1EC[1 + var_s1].y, sp68 + 0x8000, 0x800); + } + } + + if ((this->unk274.base.atFlags & 2) && (play->grabPlayer(play, player) != 0)) { + func_80AF5130(this, play); + } else if (var_s0 != 0) { + func_80AF4ED0(this); + } + + if (this->unk274.base.atFlags & 2) { + this->unk274.base.atFlags &= ~2; + } + } +} + +void func_80AF4ED0(EnWdhand* this) { + Animation_PlayOnce(&this->unk144, &object_wdhand_Anim_0000F4); + this->unk274.base.atFlags &= ~1; + this->unk274.base.atFlags &= ~2; + this->actionFunc = func_80AF4F30; + this->unk20C = 1.5f; +} + +void func_80AF4F30(EnWdhand* this, PlayState* play) { + if (SkelAnime_Update(&this->unk144) != 0) { + func_80AF4F6C(this); + } +} + +void func_80AF4F6C(EnWdhand* this) { + s32 var_s0; + + Animation_MorphToLoop(&this->unk144, &object_wdhand_Anim_000854, -10.0f); + + for (var_s0 = 0; var_s0 < 4; var_s0++) { + this->unk1EC[1 + var_s0].z = Rand_S16Offset(0x1800, 0x1000); + } + this->unk1EC[0].z = 0x50; + this->actionFunc = func_80AF4FF8; +} + +void func_80AF4FF8(EnWdhand* this, PlayState* play) { + s32 var_s0; + s32 var_s5; + + SkelAnime_Update(&this->unk144); + + this->unk1EC[0].z--; + + var_s5 = Math_ScaledStepToS(&this->unk1EC[1].x, func_80AF48D0(this, 0), 0x200); + + for (var_s0 = 1; var_s0 < 4; var_s0++) { + var_s5 &= Math_ScaledStepToS(&this->unk1EC[1 + var_s0].x, func_80AF48D0(this, var_s0), 0x300); + if (0x14 * var_s0 == this->unk1EC[0].z) { + this->unk1EC[1 + var_s0].z = Rand_S16Offset(0x1800, 0x1000); + } + } + + if (this->unk1EC[0].z == 0) { + this->unk1EC[0].z = 0x50; + this->unk1EC[1].z = Rand_S16Offset(0x1800, 0x1000); + } + + Math_StepToF(&this->unk20C, 1.0f, 0.05f); + + if (var_s5 != 0) { + func_80AF4964(this); + } +} + +void func_80AF5130(EnWdhand* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s32 var_s0; + + this->unk274.base.atFlags &= ~1; + this->unk274.base.atFlags &= ~2; + this->unk274.base.ocFlags1 &= ~1; + Animation_PlayOnce(&this->unk144, &object_wdhand_Anim_0000F4); + + for (var_s0 = 0; var_s0 < 4; var_s0++) { + this->unk1EC[1 + var_s0].z = Rand_S16Offset(0x2000, 0x1000); + } + this->unk1EC[0].z = 0x50; + player->actor.parent = &this->actor; + Matrix_Transpose(&this->unk21C); + this->unk20C = 1.5f; + + Actor_PlaySfx(&this->actor, NA_SE_EN_HANDW_GET); + this->actionFunc = func_80AF520C; +} + +#ifdef NON_MATCHING +void func_80AF520C(EnWdhand* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Vec3f sp68; + f32 var_fv1; + s32 var_s1; + + SkelAnime_Update(&this->unk144); + this->unk1EC[0].z--; + player->av2.actionVar2 = 0; + + for (var_s1 = 0; var_s1 < 4; var_s1++) { + if (this->unk1EC[0].z < 0x4C) { + this->unk1EC[1 + var_s1].x = (s16)(s32)(Math_SinF(this->unk1EC[var_s1].z * 0.3926991f) * this->unk1EC[1 + var_s1].z); + } else { + Math_ScaledStepToS(&this->unk1EC[1 + var_s1].x, (s16)(s32)(Math_SinF(this->unk1EC[var_s1].z * 0.3926991f) * this->unk1EC[1 + var_s1].z), 0x400); + } + if (!(this->unk1EC[var_s1].z & 0xF)) { + if (this->unk1EC[var_s1].z == 0x10) { + this->unk1EC[1 + var_s1].y = 0; + } else if (var_s1 != 0) { + this->unk1EC[1 + var_s1].y = this->unk1EC[var_s1].y + (s32)Rand_CenteredFloat(12288.0f); + } else { + this->unk1EC[1].y += (s32)Rand_CenteredFloat(12288.0f); + } + this->unk1EC[1 + var_s1].z = Rand_S16Offset(0x2000, 0x1000); + } + } + + if (this->unk1EC[0].z < 4) { + Math_StepToF(&this->unk20C, 1.5f, 0.125f); + } else if (this->unk1EC[0].z < 0x10) { + Math_StepToF(&this->unk20C, 2.0f, 0.041666668f); + } + + if (this->unk1EC[0].z == 0) { + this->unk274.base.ocFlags1 |= 1; + func_80AF4F6C(this); + } else if (this->unk1EC[0].z >= 4) { + Matrix_Put(&this->unk21C); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + Matrix_MultVecY(300.0f, &sp68); + + for (var_s1 = 0; var_s1 < 3; var_s1++) { + Matrix_Push(); + func_80AF46F0(this, var_s1, 0, &sp68); + Matrix_MultVecY(2300.0f, &sp68); + Matrix_Pop(); + } + + func_80AF46F0(this, 3, 1, &sp68); + Matrix_MtxFToYXZRot(Matrix_GetCurrent(), &player->actor.shape.rot, 0); + + if (this->unk20C > 1.0f) { + if (this->unk20C > 1.5f) { + var_fv1 = 1.5f; + } else { + var_fv1 = this->unk20C; + } + Matrix_RotateZS((s16)(s32)((var_fv1 - 1.0f) * -32768.0f), MTXMODE_APPLY); + } + Matrix_MultVecY(1000.0f, &player->actor.world.pos); + + if ((this->unk1EC[0].z == 4) && (&this->actor == player->actor.parent)) { + player->av2.actionVar2 = 100; + player->actor.parent = NULL; + Matrix_Transpose(&this->unk21C); + player->actor.shape.rot.x = 0; + player->actor.shape.rot.z = 0; + player->actor.world.pos.x += 2.0f * this->actor.velocity.x; + player->actor.world.pos.y += 2.0f * this->actor.velocity.y; + player->actor.world.pos.z += 2.0f * this->actor.velocity.z; + func_800B8D50(play, &this->actor, this->actor.speed, this->actor.world.rot.y, this->actor.velocity.y, 0); + Actor_PlaySfx(&this->actor, NA_SE_EN_HANDW_RELEASE); + } else if (this->unk1EC[0].z == 2) { + Animation_PlayOnce(&this->unk144, &object_wdhand_Anim_000364); + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF520C.s") #endif -extern ColliderJntSphElementInit D_80AF63E0[7]; -extern ColliderJntSphInit D_80AF64DC; -extern CollisionCheckInfoInit D_80AF64EC; -extern DamageTable D_80AF64F4; +s32 func_80AF5650(EnWdhand* this, s32 arg1) { + this->unk210[arg1] -= 0.1f; + if (this->unk210[arg1] <= 0.05f) { + this->unk210[arg1] = 0.05f; + return true; + } + return false; +} -extern UNK_TYPE D_060000F4; -extern UNK_TYPE D_06000364; -extern UNK_TYPE D_06000534; -extern UNK_TYPE D_06000854; -extern UNK_TYPE D_060014C0; +void func_80AF56A0(EnWdhand* this) { + s32 var_s0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Init.s") + this->actor.flags &= ~1; + this->actor.flags |= 0x10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Destroy.s") + for (var_s0 = 0; var_s0 < ARRAY_COUNT(this->unk294); var_s0++) { + if (this->unk274.elements[var_s0].info.bumperFlags & 2) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4608.s") + this->unk1EC[0].y = (s16) ((s32) ((s32) (var_s0 + 1) / 2) % 4); + this->unk1EC[0].x = this->unk1EC[0].y - 1; + Matrix_Put(&this->unk21C); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + Matrix_MultVecY(300.0f, &this->unk25C[1]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4670.s") + for (var_s0 = 0; var_s0 < this->unk1EC[0].y; var_s0++) { + Matrix_Push(); + func_80AF46F0(this, var_s0, 0, &this->unk25C[1]); + Matrix_MultVecY(2300.0f, &this->unk25C[1]); + Matrix_Pop(); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF46F0.s") + this->actor.velocity.y = 2.45f; + this->actor.velocity.x = 2.0f * Math_SinS(this->actor.world.rot.z); + this->actor.velocity.z = 2.0f * Math_CosS(this->actor.world.rot.z); + this->unk1EC[0].z = 5; + this->actionFunc = func_80AF5820; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF488C.s") +#ifdef NON_MATCHING +void func_80AF5820(EnWdhand* this, PlayState* play) { + Vec3f spA0; + Vec3f sp94; + Vec3f sp70; + s16 temp_s0_6; + s32 temp_s5; + s32 var_s0; + s32 var_s2; + Vec3s* temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF48D0.s") + temp = &this->unk274.elements[6].dim.worldSphere.center; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4964.s") + spA0.x = (this->unk25C[1].x - temp->x) * 0.5f; + spA0.y = (this->unk25C[1].y - temp->y) * 0.5f; + spA0.z = (this->unk25C[1].z - temp->z) * 0.5f; + Matrix_RotateXS(0x100, MTXMODE_NEW); + Matrix_MultVec3f(&spA0, &sp94); + this->unk25C[1].x = spA0.x + sp94.x + temp->x; + this->unk25C[1].y = spA0.y + sp94.y + temp->y; + this->unk25C[1].z = spA0.z + sp94.z + temp->z; + if (this->actor.velocity.y > -2.0f) { + this->actor.velocity.y += -0.15f; + } + Math_Vec3f_Sum(&this->unk25C[1], &this->actor.velocity, &this->unk25C[1]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4A88.s") + this->actor.world.rot.x += 0x100; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4C18.s") + if (this->unk1EC[0].x >= 0 && func_80AF5650(this, this->unk1EC[0].x)) { + this->unk1EC[0].x -= 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4C64.s") + if (this->unk1EC[0].y < 3) { + if (func_80AF5650(this, this->unk1EC[0].y)) { + this->unk1EC[0].y += 1; + } + Matrix_RotateZYX(this->actor.world.rot.x, this->actor.world.rot.z, 0, MTXMODE_NEW); + Matrix_RotateYS(-this->actor.world.rot.z, MTXMODE_APPLY); + Matrix_Mult(&this->unk21C, MTXMODE_APPLY); + func_80AF46F0(this, this->unk1EC[0].y, 0, &this->unk25C[1]); + Matrix_MultVecY(2.3f / this->unk210[this->unk1EC[0].y], &this->unk25C[1]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4ED0.s") + this->unk1EC[0].z--; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4F30.s") + temp_s5 = this->unk1EC[0].x + 1; + for (var_s2 = 0; var_s2 < temp_s5; var_s2++) { + if (this->unk1EC[0].z > 0) { + Math_ScaledStepToS(&this->unk1EC[1 + var_s2].x, (s16)(s32)(Math_SinF(this->unk1EC[var_s2].z * 0.8975979f) * this->unk1EC[1 + var_s2].y), 0x200); + } else if (Rand_ZeroOne() < 0.65f) { + this->unk1EC[1 + var_s2].x = this->unk1EC[1 + var_s2].y + Math_SinF(this->unk1EC[var_s2].z * 0.8975979f); + } + if ((this->unk1EC[var_s2].z % 7) == 0) { + if (var_s2 != 0) { + this->unk1EC[1 + var_s2].x = this->unk1EC[var_s2].y + (s32)Rand_CenteredFloat(12288.0f); + } else { + this->unk1EC[1].y += (s32) Rand_CenteredFloat(12288.0f); + } + this->unk1EC[1 + var_s2].y = Rand_S16Offset((s16) ((var_s2 << 8) + 0xC00), 0x800); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4F6C.s") + if ((this->unk1EC[0].x < 0) && (this->unk1EC[0].y >= 3)) { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.001f) != 0) { + for (var_s0 = 0; var_s0 < 2; var_s0++) { + for (var_s2 = 0; var_s2 < 5; var_s2++) { + D_80AF6514.y = Rand_ZeroOne() + 1.0f; + temp_s0_6 = Rand_S16Offset(0x28, 0x28); + sp70.x = Rand_CenteredFloat(12.0f) + this->unk25C[var_s2].x; + sp70.y = Rand_CenteredFloat(12.0f) + this->unk25C[var_s2].y; + sp70.z = Rand_CenteredFloat(12.0f) + this->unk25C[var_s2].z; + EffectSsDtBubble_SpawnColorProfile(play, &sp70, &D_80AF6514, &D_80AF6520, temp_s0_6, 25, 2, 1); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4FF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5130.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF520C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5650.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF56A0.s") + Actor_Kill(&this->actor); + } else { + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + } + } + for (var_s0 = 0; var_s0 < 2; var_s0++) { + D_80AF6514.y = Rand_ZeroOne() + 1.0f; + EffectSsDtBubble_SpawnColorProfile(play, &this->unk25C[var_s0], &D_80AF6514, &D_80AF6520, Rand_S16Offset(40, 40), 25, 2, 1); + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5820.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5E3C.s") +void func_80AF5E3C(EnWdhand* this, PlayState* play) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Update.s") + if (this->unk274.base.acFlags & 2) { + Player* player = GET_PLAYER(play); + s32 temp = ~1; + this->unk274.base.acFlags &= temp; + this->unk274.base.acFlags &= ~2; + this->unk274.base.atFlags &= temp; + this->unk274.base.ocFlags1 &= temp; + Actor_SetDropFlagJntSph(&this->actor, &this->unk274); + Enemy_StartFinishingBlow(play, &this->actor); + if ((player->stateFlags2 & 0x80) && (&this->actor == player->actor.parent)) { + player->av2.actionVar2 = 100; + player->actor.parent = NULL; + player->actor.shape.rot.x = 0; + player->actor.shape.rot.z = 0; + func_800B8D50(play, &this->actor, this->actor.speed, this->actor.world.rot.y, this->actor.velocity.y, 0U); + } else { + Matrix_Transpose(&this->unk21C); + } + func_80AF56A0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5FE4.s") +void EnWdhand_Update(Actor* thisx, PlayState* play) { + EnWdhand* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Draw.s") + func_80AF5E3C(this, play); + + this->actionFunc(this, play); + + if (this->unk274.base.atFlags & 1) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk274.base); + } + if (this->unk274.base.acFlags & 1) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk274.base); + } + if (this->unk274.base.ocFlags1 & 1) { + CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk274.base); + } +} + +void func_80AF5FE4(EnWdhand* this, s32 arg1, Vec3f* arg2) { + func_80AF46F0(this, arg1, 1, arg2); + Matrix_MultVecY(575.0f, arg2); + func_80AF488C(&this->unk274.elements[2 * arg1].dim.worldSphere.center, arg2); + Matrix_MultVecY(1725.0f, arg2); + func_80AF488C(&this->unk274.elements[2 * arg1 + 1].dim.worldSphere.center, arg2); + Matrix_MultVecY(2300.0f, arg2); +} + +void EnWdhand_Draw(Actor* thisx, PlayState* play) { + EnWdhand* this = THIS; + Vec3f sp90; + Gfx* dl; + s32 var; + s32 var_s1; + + OPEN_DISPS(play->state.gfxCtx); + + dl = POLY_OPA_DISP; + + gSPDisplayList(&dl[0], &gSetupDLs[25]); // same problem as ovl_En_Knight. TODO: This may be an issue + gSPMatrix(&dl[1], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[2], object_wdhand_DL_0014C0); + + Matrix_MultVecY(300.0f, &sp90); + + dl = &dl[3]; + + var = this->unk1EC[0].x + 1; + for (var_s1 = 0; var_s1 < var; var_s1++) { + Matrix_Push(); + func_80AF5FE4(this, var_s1, &sp90); + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_wdhand_DL_0015B0); + Matrix_Pop(); + } + + Math_Vec3f_Copy(&this->unk25C[0], &sp90); + Math_Vec3f_Copy(&sp90, &this->unk25C[1]); + if (this->actor.world.rot.x != 0) { + Matrix_RotateZYX(this->actor.world.rot.x, this->actor.world.rot.z, 0, MTXMODE_NEW); + Matrix_RotateYS(-this->actor.world.rot.z, MTXMODE_APPLY); + Matrix_Mult(&this->unk21C, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + } + + for (var_s1 = this->unk1EC[0].y; var_s1 < 3; var_s1++) { + Matrix_Push(); + func_80AF5FE4(this, var_s1, &sp90); + gSPMatrix(dl++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(dl++, object_wdhand_DL_0015B0); + Matrix_Pop(); + } + + func_80AF46F0(this, 3, 1, &sp90); + if (this->unk20C > 1.0f) { + s32 pad; + f32 var_fv1; + + if (this->unk20C > 1.5f) { + var_fv1 = 1.5f; + } else { + var_fv1 = this->unk20C; + } + Matrix_RotateZS((s16)(s32)((var_fv1 - 1.0f) * -32768.0f), MTXMODE_APPLY); + } + if (this->actor.scale.x < 0.01f) { + Matrix_Translate(0.0f, (10.0f / this->actor.scale.x) - 1000.0f, 0.0f, MTXMODE_APPLY); + } + Math_Vec3f_Copy(&this->actor.focus.pos, &sp90); + Matrix_MultVecY(1000.0f, &sp90); + func_80AF488C(&this->unk274.elements[6].dim.worldSphere.center, &sp90); + + POLY_OPA_DISP = dl; + SkelAnime_DrawFlexOpa(play, this->unk144.skeleton, this->unk144.jointTable, this->unk144.dListCount, NULL, NULL, &this->actor); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.h b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.h index 5eb02fa1a..8a1cd297d 100644 --- a/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.h +++ b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.h @@ -9,9 +9,17 @@ typedef void (*EnWdhandActionFunc)(struct EnWdhand*, PlayState*); typedef struct EnWdhand { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xA4]; + /* 0x144 */ SkelAnime unk144; + /* 0x188 */ Vec3s unk188[8]; + /* 0x1B8 */ Vec3s unk1B8[8]; /* 0x1E8 */ EnWdhandActionFunc actionFunc; - /* 0x1EC */ char unk_1EC[0x268]; + /* 0x1EC */ Vec3s unk1EC[5]; + /* 0x20C */ f32 unk20C; + /* 0x20C */ f32 unk210[3]; + /* 0x21C */ MtxF unk21C; + /* 0x25C */ Vec3f unk25C[2]; + /* 0x274 */ ColliderJntSph unk274; + /* 0x294 */ ColliderJntSphElement unk294[7]; } EnWdhand; // size = 0x454 #endif // Z_EN_WDHAND_H diff --git a/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c b/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c index c8f5a74c7..6ab2f2b78 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c +++ b/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c @@ -97,12 +97,12 @@ void EffectSsFhgFlash_Update(PlayState* play, u32 index, EffectSs* this) { s32 pad; Vec3f* bodyPartPos; BossHakugin* goht = (BossHakugin*)this->actor; - s32 gohtIndex = goht->unk_191 - 3; + s32 gohtIndex = goht->unk_0191 - 3; if (gohtIndex < 0) { - bodyPartPos = &goht->unk_2F00[this->rParams][12].unk_00; + bodyPartPos = &goht->unk_3158[this->rParams - FHGFLASH_SHOCK_GOHT_2][12].unk_00; } else { - bodyPartPos = &goht->unk_2F00[this->rParams][gohtIndex].unk_00; + bodyPartPos = &goht->unk_3158[this->rParams - FHGFLASH_SHOCK_GOHT_2][gohtIndex].unk_00; } this->pos.x = Rand_CenteredFloat(70.0f) + bodyPartPos->x; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 77f9cf453..a970f5131 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -6209,7 +6209,7 @@ 0x808C96C8:("EnDeath_Draw",), 0x808CA0B0:("EnMinideath_Init",), 0x808CA23C:("EnMinideath_Destroy",), - 0x808CA268:("func_808CA268",), + 0x808CA268:("EnMinideath_DropCollectible",), 0x808CA308:("func_808CA308",), 0x808CA34C:("func_808CA34C",), 0x808CA458:("func_808CA458",), @@ -6239,7 +6239,7 @@ 0x808CB6D4:("func_808CB6D4",), 0x808CB7B8:("func_808CB7B8",), 0x808CB7CC:("func_808CB7CC",), - 0x808CB810:("func_808CB810",), + 0x808CB810:("EnMinideath_SetNextAction",), 0x808CB8F4:("func_808CB8F4",), 0x808CBB18:("EnMinideath_Update",), 0x808CC260:("EnVm_Init",), @@ -12970,8 +12970,8 @@ 0x80B0B548:("func_80B0B548",), 0x80B0B660:("func_80B0B660",), 0x80B0BAE0:("BossHakugin_Update",), - 0x80B0C000:("func_80B0C000",), - 0x80B0C1BC:("func_80B0C1BC",), + 0x80B0C000:("BossHakugin_OverrideLimbDraw",), + 0x80B0C1BC:("BossHakugin_PostLimbDraw",), 0x80B0C398:("func_80B0C398",), 0x80B0C570:("func_80B0C570",), 0x80B0C7B0:("func_80B0C7B0",), @@ -12979,9 +12979,9 @@ 0x80B0CCD8:("func_80B0CCD8",), 0x80B0CF24:("func_80B0CF24",), 0x80B0D0D4:("BossHakugin_Draw",), - 0x80B0D2B8:("func_80B0D2B8",), - 0x80B0D69C:("func_80B0D69C",), - 0x80B0D750:("func_80B0D750",), + 0x80B0D2B8:("BossHakugin_FillShadowTex",), + 0x80B0D69C:("BossHakugin_GenShadowTex",), + 0x80B0D750:("BossHakugin_DrawShadowTex",), 0x80B0D9CC:("func_80B0D9CC",), 0x80B0DFA8:("func_80B0DFA8",), 0x80B0E548:("func_80B0E548",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 86aeba900..25dae3d08 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -10210,11 +10210,11 @@ 0x809F1C40:("Boss_05_InitVars","UNK_TYPE1","",0x1), 0x809F1C60:("D_809F1C60","UNK_TYPE2","",0x2), 0x809F1C8C:("D_809F1C8C","UNK_TYPE2","",0x2), - 0x809F1CB8:("D_809F1CB8","UNK_TYPE1","",0x1), - 0x809F1CC0:("D_809F1CC0","UNK_TYPE1","",0x1), - 0x809F1CC4:("D_809F1CC4","UNK_TYPE1","",0x1), - 0x809F1CD0:("D_809F1CD0","UNK_TYPE1","",0x1), - 0x809F1CDC:("D_809F1CDC","UNK_TYPE1","",0x1), + 0x809F1CB8:("D_809F1CB8","s8","[12]",0xC), + 0x809F1CC4:("D_809F1CC4","Vec3f","",0xC), + 0x809F1CD0:("D_809F1CD0","Vec3f","",0xC), + 0x809F1CDC:("D_809F1CDC","Vec3f","",0xC), + 0x809F1CE8:("D_809F1CE8","s32","[]",0x38), 0x809F1D20:("D_809F1D20","f32","",0x4), 0x809F1D24:("D_809F1D24","f32","",0x4), 0x809F1D28:("D_809F1D28","f32","",0x4), @@ -13219,8 +13219,7 @@ 0x80AF64DC:("D_80AF64DC","UNK_TYPE1","",0x1), 0x80AF64EC:("D_80AF64EC","UNK_TYPE1","",0x1), 0x80AF64F4:("D_80AF64F4","UNK_TYPE1","",0x1), - 0x80AF6514:("D_80AF6514","UNK_TYPE1","",0x1), - 0x80AF6518:("D_80AF6518","f32","",0x4), + 0x80AF6514:("D_80AF6514","Vec3f","",0xC), 0x80AF6520:("D_80AF6520","UNK_TYPE1","",0x1), 0x80AF6530:("D_80AF6530","f32","",0x4), 0x80AF6534:("D_80AF6534","f32","",0x4), @@ -13424,13 +13423,7 @@ 0x80B0EA60:("D_80B0EA60","UNK_TYPE1","",0x1), 0x80B0EA80:("D_80B0EA80","UNK_TYPE1","",0x1), 0x80B0EA88:("D_80B0EA88","UNK_TYPE4","",0x4), - 0x80B0EA8C:("D_80B0EA8C","UNK_TYPE1","",0x1), - 0x80B0EA94:("D_80B0EA94","UNK_TYPE1","",0x1), - 0x80B0EA95:("D_80B0EA95","UNK_TYPE1","",0x1), - 0x80B0EA9A:("D_80B0EA9A","UNK_TYPE1","",0x1), - 0x80B0EA9C:("D_80B0EA9C","UNK_TYPE1","",0x1), - 0x80B0EAA4:("D_80B0EAA4","UNK_TYPE1","",0x1), - 0x80B0EAA5:("D_80B0EAA5","UNK_TYPE1","",0x1), + 0x80B0EA8C:("sLimbToBodyParts","s8","[]", 0x20), 0x80B0EAAC:("D_80B0EAAC","UNK_TYPE1","",0x1), 0x80B0EAB0:("D_80B0EAB0","UNK_TYPE1","",0x1), 0x80B0EAC4:("D_80B0EAC4","UNK_TYPE1","",0x1), @@ -13453,8 +13446,8 @@ 0x80B0EB88:("D_80B0EB88","UNK_TYPE4","",0x4), 0x80B0EBA4:("D_80B0EBA4","UNK_TYPE4","",0x4), 0x80B0EBC4:("D_80B0EBC4","UNK_TYPE4","",0x4), - 0x80B0EBFC:("D_80B0EBFC","UNK_TYPE4","",0x4), - 0x80B0EC38:("D_80B0EC38","UNK_TYPE1","",0x1), + 0x80B0EBFC:("sParentShadowBodyParts","UNK_TYPE4","",0x4), + 0x80B0EC38:("sShadowSizes","UNK_TYPE1","",0x1), 0x80B0EC50:("D_80B0EC50","f32","",0x4), 0x80B0EC54:("D_80B0EC54","f32","",0x4), 0x80B0EC58:("D_80B0EC58","f32","",0x4), diff --git a/tools/m2ctx.py b/tools/m2ctx.py index 23875eef0..49e065f8e 100755 --- a/tools/m2ctx.py +++ b/tools/m2ctx.py @@ -75,13 +75,9 @@ def custom_replacements(output): def import_c_file(in_file) -> str: in_file = os.path.relpath(in_file, root_dir) - cpp_command = ["gcc", "-E", "-P", "-undef", "-dM", *CPP_FLAGS, in_file] - cpp_command2 = ["gcc", "-E", "-P", "-undef", *CPP_FLAGS, in_file] + cpp_command = ["gcc", "-E", "-P", "-Iinclude", "-Iassets", "-Isrc", "-undef", "-D__sgi", "-D_LANGUAGE_C", + "-DNON_MATCHING", "-DM2CTX", "-D_Static_assert(x, y)=", "-D__attribute__(x)=", in_file] - with tempfile.NamedTemporaryFile(suffix=".c") as tmp: - stock_macros = subprocess.check_output(["gcc", "-E", "-P", "-undef", "-dM", tmp.name], cwd=root_dir, encoding="utf-8") - - out_text = "" try: out_text += subprocess.check_output(cpp_command, cwd=root_dir, encoding="utf-8") out_text += subprocess.check_output(cpp_command2, cwd=root_dir, encoding="utf-8") diff --git a/tools/sfxconvert.py b/tools/sfxconvert.py index fbd7aa755..a19764417 100755 --- a/tools/sfxconvert.py +++ b/tools/sfxconvert.py @@ -51,6 +51,8 @@ def lookup_sfx(idnum, repo): else: id = idnum idfix,sfxFlag = fix_sfx_flag(id) + if idfix is None: + return id with open(repo + os.sep + 'include' + os.sep + 'sfx.h','r') as sfxfile: for line in sfxfile: if(line.count(idfix)): @@ -63,6 +65,10 @@ def fix_sfx_flag(id): return splitdata[0].strip(), ' -' + splitdata[1] if id.endswith("U"): id = id[:-1] + try: + id_hex = int(id, 16) + except ValueError: + return None,None if not(int(id, 16) & 0x800): newid = '0x' + format(int(id,16) + 0x800,'X') sfxFlag = ' - SFX_FLAG' diff --git a/undefined_syms.txt b/undefined_syms.txt index ebf92a005..034e500f0 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -283,23 +283,6 @@ D_06042330 = 0x06042330; D_06043330 = 0x06043330; D_06045B30 = 0x06045B30; -// ovl_Boss_Hakugin - -D_06002054 = 0x06002054; -D_0600319C = 0x0600319C; -D_06010488 = 0x06010488; -D_06010500 = 0x06010500; -D_06011100 = 0x06011100; -D_06011178 = 0x06011178; -D_06011208 = 0x06011208; -D_06011278 = 0x06011278; -D_06012ED0 = 0x06012ED0; -D_06012F40 = 0x06012F40; -D_06013158 = 0x06013158; -D_060134D0 = 0x060134D0; -D_06013828 = 0x06013828; -D_06014040 = 0x06014040; - // ovl_Dm_Tsg D_06002D30 = 0x06002D30;