From f21f393fccf41f4aa1297f6f1966abbf70cb7030 Mon Sep 17 00:00:00 2001 From: Isghj <42048411+isghj5@users.noreply.github.com> Date: Wed, 1 Sep 2021 15:44:42 -0700 Subject: [PATCH] EnBigpo (Big Poh) (#250) * EnBigpo: start * EnBigpo: uhh, this struct is weird * EnBigpo: progress * EnBigpo: so many of these functions are tiny * EnBigpo nasty four loop function * EnBigpo: hate draw functions * EnBigpo: all functions attempted * EnBigpo: data migrated, does not OK, 2 bytes off... * Multi: Attempting to OK, issues * EnBigpo: more docs * EnBigpo: more docs2 * EnBigpo: more docs and cleaning * EnBigpo: removed data to try to find the issues, matched a draw function thanks to Tharo * EnBigpo: progress? maybe not * EnBigpo: matched another function * EnBigpo: overwrite limbdraw matches now * EnBigpo: one more nonmatching rejected * EnBigPo: not actual progress, probably * Match Init, down to single stack pointer on second func * EnBigPo OK * EnBigpo: docs and cleaning * EnBigpo: more docs and cleaning * EnBigpo: back to OK with no warnings * EnBigpo: more docs and cleaning * EnBigpo: docs and cleaning * EnBigpo: hmm, rename_sym doesn't like renaming system functions but I'm 98% sure I know what these are * Multiple: changed some function names, maybe changed too much... hmm * EnBigpo: even more changes to docs * EnBigpo: formater pass * EnBigpo: small fixes * EnBigpo: c file description * Apply suggestions from code review Apply camera suggestions from eng124 Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * EnBigpo: updating all requested changes and reverting one incorrect macro * Apply suggestions from code review Some of eng124's recommendations, need to add the last by hand Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * EnBigpo: back to OK * EnBigpo: Minor cleanup changes * Functions fixed: added function changes to actorfixer and fixed dinofos * EnBigpo: BINANG_ROT180 * Apply suggestions from code review First batch of requested changes, the simpler ones that shouldn't require checking Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: Anghelo Carvajal * EnBigpo: fixes to recommended changes, back to OK * EnBigpo: move idleTimer docs out of struct * Sprite: removed old commented out pragma, it matches, I still dont get it * EnBigpo: more changes I had to check first * EnBigpo: more requested changes, and some macro uses found * EnBigpo: forgot a requested change * Update src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * EnBigPo: missed a disphead array access * Apply suggestions from code review More requested changes Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * EnBigpo: more hex to dec * EnBigpo: more hex to dec 2 * Update src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * EnBigpo: build being weird * EnBigpo: weird, rename_sym didn't catch this earlier * Tools: fixed actorfixer to use Play_CameraSetAtEye forgot I blew this change away trying to get build again, * Update src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h Co-authored-by: Kenix3 * EnBigpo: cutscene functions changed name to indicate they are stages * EnBigpo: Rename Particles to Effect * EnBigpo: changed draw function names, changed function comment format * EnBigpo: renamed limbdraw functions, formater pass Co-authored-by: isghj8 Co-authored-by: engineer124 Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: Anghelo Carvajal Co-authored-by: Kenix3 --- include/functions.h | 8 +- include/macros.h | 3 + include/z64actor.h | 1 - spec | 3 +- src/code/code_800F0390.c | 2 +- src/code/z_actor.c | 4 +- src/code/z_effect_soft_sprite_old_init.c | 4 - src/code/z_en_item00.c | 8 +- src/code/z_play.c | 2 +- .../actors/ovl_Bg_Icicle/z_bg_icicle.c | 2 +- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c | 1603 +++++++++++++++-- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h | 63 +- .../actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 2 +- .../actors/ovl_En_Dekunuts/z_en_dekunuts.c | 8 +- .../actors/ovl_En_Dinofos/z_en_dinofos.c | 16 +- .../actors/ovl_En_Firefly/z_en_firefly.c | 2 +- .../actors/ovl_En_Invadepoh/z_en_invadepoh.c | 4 +- .../actors/ovl_En_Minifrog/z_en_minifrog.c | 2 +- .../actors/ovl_En_Nutsball/z_en_nutsball.c | 4 +- .../actors/ovl_En_Pametfrog/z_en_pametfrog.c | 26 +- src/overlays/actors/ovl_En_Sb/z_en_sb.c | 6 +- .../actors/ovl_En_Suttari/z_en_suttari.c | 4 +- .../actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c | 18 +- .../actors/ovl_Obj_Kibako/z_obj_kibako.c | 12 +- .../actors/ovl_Obj_Kibako2/z_obj_kibako2.c | 2 +- tools/actorfixer.py | 4 + tools/disasm/functions.txt | 84 +- 27 files changed, 1594 insertions(+), 303 deletions(-) diff --git a/include/functions.h b/include/functions.h index cae98a46c2..18fc730880 100644 --- a/include/functions.h +++ b/include/functions.h @@ -871,7 +871,7 @@ Actor* func_800BB498(ActorContext* actorCtx, Actor* actor, GlobalContext* global // void func_800BB59C(void); // void func_800BB604(void); // void func_800BB8EC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -void func_800BBA88(GlobalContext* globalCtx, Actor* actor); +void Enemy_StartFinishingBlow(GlobalContext* globalCtx, Actor* actor); // void func_800BBAC0(void); void func_800BBB74(s16* arg1, UNK_TYPE1 arg2, UNK_TYPE1 arg3, UNK_TYPE4 arg4); // void func_800BBC20(void); @@ -911,7 +911,7 @@ void func_800BDFC0(GlobalContext* globalCtx, Gfx* dl); void func_800BE03C(GlobalContext* globalCtx, Gfx* dl); Actor* func_800BE0B8(GlobalContext* globalCtx, Actor* inActor, s16 arg2, u8 arg3, f32 arg4); // void func_800BE184(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); -u8 func_800BE22C(Actor* actor); +u8 Actor_ApplyDamage(Actor* actor); // returns current health void func_800BE258(Actor* actor, UNK_PTR arg1); void func_800BE2B8(Actor* actor, ColliderJntSph* jntSphere); void func_800BE33C(Vec3f* arg0, Vec3f* arg1, Vec3s* arg2, s32 arg3); @@ -1640,7 +1640,7 @@ void EffFootmark_Draw(GlobalContext* globalCtx); void func_800F0390(GlobalContext* globalCtx); void func_800F03C0(GlobalContext* globalCtx); void func_800F048C(GlobalContext* globalCtx, Vec3f* param_2, u8 param_3, u16 param_4, u8 param_5); -void func_800F0568(GlobalContext* globalCtx, Vec3f* position, s32 param_3, u16 sfxId); +void Audio_PlaySoundAtPosition(GlobalContext* globalCtx, Vec3f* position, s32 param_3, u16 sfxId); // void func_800F0590(void); // void func_800F05C0(void); // void func_800F07C0(void); @@ -3035,7 +3035,7 @@ void func_80169590(GlobalContext* globalCtx, s16 param_2, s16 param_3); void func_80169600(GlobalContext* globalCtx, s16 param_2); // void func_80169668(void); Camera* Play_GetCamera(GlobalContext* globalCtx, s16 index); -s32 func_8016970C(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye); +s32 Play_CameraSetAtEye(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye); // void func_8016981C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_80169940(void); // void func_80169988(void); diff --git a/include/macros.h b/include/macros.h index 6188a085fd..be3ec0c93e 100644 --- a/include/macros.h +++ b/include/macros.h @@ -19,6 +19,7 @@ // Currently most often called ctxt in MM, TODO: Refactor names when its used #define ACTIVE_CAM globalCtx->cameraPtrs[globalCtx->activeCamera] #define MAIN_CAM 0 +#define SUBCAM_FREE 0 #define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \ (curState)->nextGameStateInit = (GameStateFunc)newInit; \ @@ -26,6 +27,8 @@ #define PLAYER ((Player*)globalCtx->actorCtx.actorList[ACTORCAT_PLAYER].first) +#define FIRST_ENEMY ((Actor*)globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first) + // linkAge still exists in MM, but is always set to 0 (always adult) // There are remnants of these macros from OOT, but they are essentially useless //#define LINK_IS_CHILD (gSaveContext.linkAge != 0) diff --git a/include/z64actor.h b/include/z64actor.h index a39411bbbb..48c53e8a21 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -236,7 +236,6 @@ typedef struct { /* 0x15A */ s16 pad15A; } DynaPolyActor; // size = 0x15C - typedef enum { /* 0x00 */ ITEM00_RUPEE_GREEN, /* 0x01 */ ITEM00_RUPEE_BLUE, diff --git a/spec b/spec index 5d50fef94f..2668615840 100644 --- a/spec +++ b/spec @@ -4252,8 +4252,7 @@ beginseg name "ovl_En_Bigpo" compress include "build/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.o" - include "build/data/ovl_En_Bigpo/ovl_En_Bigpo.data.o" - include "build/data/ovl_En_Bigpo/ovl_En_Bigpo.reloc.o" + include "build/src/overlays/actors/ovl_En_Bigpo/ovl_En_Bigpo_reloc.o" endseg beginseg diff --git a/src/code/code_800F0390.c b/src/code/code_800F0390.c index 423b9048c3..f495cfe5ea 100644 --- a/src/code/code_800F0390.c +++ b/src/code/code_800F0390.c @@ -6,6 +6,6 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F048C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F0568.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/Audio_PlaySoundAtPosition.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F0590.s") diff --git a/src/code/z_actor.c b/src/code/z_actor.c index fd6580f51a..b13f220436 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -766,7 +766,7 @@ void Actor_FreeOverlay(ActorOverlay* entry) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB8EC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBA88.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Enemy_StartFinishingBlow.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBAC0.s") @@ -866,7 +866,7 @@ Actor* func_800BE0B8(GlobalContext* globalCtx, Actor* inActor, s16 arg2, u8 arg3 #pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE184.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE22C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_ApplyDamage.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE258.s") diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c index 51b382c880..39cc4af73e 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -566,7 +566,6 @@ void EffectSsHahen_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, * - due to how life is implemented it is capped at 200. Any value over 200 is accepted, but the fragment will * only live for 200 frames */ -#ifdef NON_MATCHING void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstScale, s16 unused, s16 scale, s16 randScaleRange, s16 count, s16 objId, s16 life, Gfx* dList) { s32 i; @@ -585,9 +584,6 @@ void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstSca life, dList); } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsHahen_SpawnBurst.s") -#endif extern Vec3f D_801AE3E0; diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index 467fcb5974..13be40c0ab 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -871,7 +871,7 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102); if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) { - func_800F0568(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } else { // TODO: fix cast, this actor is not an EnItem00 @@ -880,7 +880,7 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); if (param20000 == 0) { if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) { - func_800F0568(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } } @@ -947,7 +947,7 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); } if (Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F) == 0) { - func_800F0568(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } else { params = func_800A7650(params); @@ -1105,7 +1105,7 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 if (gSaveContext.health < 0x11) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, 2); - func_800F0568(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); return; } diff --git a/src/code/z_play.c b/src/code/z_play.c index 05b0c8b407..8f15c577a2 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -86,7 +86,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCamera.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016970C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetAtEye.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016981C.s") diff --git a/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c b/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c index af2fb5220f..5af83aad27 100644 --- a/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c +++ b/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c @@ -107,7 +107,7 @@ void BgIcicle_Break(BgIcicle* this, GlobalContext* globalCtx, f32 arg2) { s32 j; s32 i; - func_800F0568(globalCtx, &this->dyna.actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); for (i = 0; i < 2; i++) { for (j = 0; j < 10; j++) { diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c index c2640bf31d..ce3e557f71 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -1,3 +1,9 @@ +/* + * File z_en_bigpo.c + * Overlay: ovl_En_Bigpi + * Description: Big Poe. Leader of the Poes, found under Dampe's house and in Beneath the Well + */ + #include "z_en_bigpo.h" #define FLAGS 0x00001215 @@ -7,35 +13,88 @@ void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx); void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx); +void EnBigpo_UpdateFire(Actor* thisx, GlobalContext* globalCtx); -void func_80B61AF8(EnBigpo* this, GlobalContext* globalCtx); -void func_80B61B70(EnBigpo* this, GlobalContext* globalCtx); -void func_80B61CFC(EnBigpo* this, GlobalContext* globalCtx); -void func_80B61DA4(EnBigpo* this, GlobalContext* globalCtx); -void func_80B61F04(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62084(EnBigpo* this, GlobalContext* globalCtx); -void func_80B621CC(EnBigpo* this, GlobalContext* globalCtx); -void func_80B623BC(EnBigpo* this, GlobalContext* globalCtx); -void func_80B6259C(EnBigpo* this, GlobalContext* globalCtx); -void func_80B627B4(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62830(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62920(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62A68(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62B10(EnBigpo* this, GlobalContext* globalCtx); -void func_80B62F10(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63264(EnBigpo* this, GlobalContext* globalCtx); -void func_80B6330C(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63410(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63474(EnBigpo* this, GlobalContext* globalCtx); -void func_80B636E4(EnBigpo* this, GlobalContext* globalCtx); -void func_80B6382C(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63854(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63888(EnBigpo* this, GlobalContext* globalCtx); -void func_80B638D4(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63980(EnBigpo* this, GlobalContext* globalCtx); -void func_80B63AC4(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_InitWellBigpo(EnBigpo* this); +void EnBigpo_HitStun(EnBigpo* this); +void EnBigpo_InitDampeMainPo(EnBigpo* this); +void EnBigpo_ChangeToFireCounting(EnBigpo* this); +void EnBigpo_InitHiddenFire(EnBigpo* this); +void EnBigpo_SetupFireRevealed(EnBigpo* this); + +void EnBigpo_SetupSpawnCutscene(EnBigpo* this); +void EnBigpo_SpawnCutsceneStage1(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SpawnCutsceneStage2(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SpawnCutsceneStage3(EnBigpo* this); +void EnBigpo_SpawnCutsceneStage4(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SpawnCutsceneStage5(EnBigpo* this); +void EnBigpo_SpawnCutsceneStage6(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SpawnCutsceneStage7(EnBigpo* this); +void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx); + +void EnBigpo_LowerCutsceneSubCamera(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_WellWaitForProximity(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_WaitCutsceneQueue(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupWarpOut(EnBigpo* this); +void EnBigpo_WarpingOut(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupWarpIn(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_WarpingIn(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupIdleFlying(EnBigpo* this); +void EnBigpo_IdleFlying(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupSpinUp(EnBigpo* this); +void EnBigpo_SpinningUp(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupSpinAttack(EnBigpo* this); +void EnBigpo_SpinAttack(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupSpinDown(EnBigpo* this); +void EnBigpo_SpinningDown(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_CheckHealth(EnBigpo* this, GlobalContext* globalCtx); +s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupDeath(EnBigpo* this); +void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_LanternFalling(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SpawnScoopSoul(EnBigpo* this); +void EnBigpo_ScoopSoulAppearing(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupScoopSoulIdle(EnBigpo* this); +void EnBigpo_ScoopSoulIdle(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupScoopSoulLeaving(EnBigpo* this); +void EnBigpo_ScoopSoulFadingAway(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_Die(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SelectRandomFireLocations(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_FireCounting(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupFlameCirclePositions(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_SetupFlameCircleCutscene(EnBigpo* this); +void EnBigpo_FlameCircleCutscene(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_UpdateColor(EnBigpo* this); +void EnBigpo_FlickerLanternLight(EnBigpo* this); +void EnBigpo_SetupRevealedFireIdle(EnBigpo* this); +void EnBigpo_RevealedFireIdle(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_DoNothing(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_WaitingForDampe(EnBigpo* this, GlobalContext* globalCtx); +void EnBigpo_RevealedFireGrowing(EnBigpo* this, GlobalContext* globalCtx); + +// draw funcs +void EnBigpo_PostLimbDraw(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, struct Actor* actor, + Gfx** gfx); +void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx); +void EnBigpo_DrawScoopSoul(Actor* thisx, GlobalContext* globalCtx); +void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx); +void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx); +void EnBigpo_RevealedFire(Actor* thisx, GlobalContext* globalCtx); + +extern AnimationHeader D_06001360; +extern SkeletonHeader D_06005C18; +extern AnimationHeader D_06000924; +extern AnimationHeader D_06000924; +extern AnimationHeader D_06000454; +extern Gfx D_060041A0; +extern Gfx D_06001BB0; +extern Gfx D_060058B8; +extern Gfx D_060042C8; +extern Gfx D_060043F8; + +extern const ActorInit En_Bigpo_InitVars; -#if 0 const ActorInit En_Bigpo_InitVars = { ACTOR_EN_BIGPO, ACTORCAT_ENEMY, @@ -48,18 +107,29 @@ const ActorInit En_Bigpo_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B65010 = { - { COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_NONE | AC_TYPE_PLAYER, OC1_NONE | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT3, + AT_NONE | AT_TYPE_ENEMY, + AC_NONE | AC_TYPE_PLAYER, + OC1_NONE | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 35, 100, 10, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80B6503C = { 10, 35, 100, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 10, 35, 100, 50 }; -// static DamageTable sDamageTable = { -static DamageTable D_80B65044 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -94,161 +164,1332 @@ static DamageTable D_80B65044 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B65064[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 90, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 3200, ICHAIN_STOP), }; -#endif +// used in the burning death actionfunc +static Vec3f D_80B6506C = { 0.0f, 3.0f, 0.0f }; + +// bytes per limb, used in draw func? bit over my head +static u8 D_80B65078[] = { + -1, 4, -1, 0, -1, 1, -1, 2, 5, 3, +}; + +// used in limbdraw +static Vec3f D_80B65084[] = { + { 2000.0f, 4000.0f, 0.0f,}, + {-1000.0f, 1500.0f, -2000.0f,}, + {-1000.0f, 1500.0f, 2000.0f,}, +}; + +void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnBigpo* this = (EnBigpo*)thisx; + EnBigpoFireEffect* firesPtr; + s32 i; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + // thisx req to match + this->switchFlags = GET_BIGPO_SWITCHFLAGS(thisx); + thisx->params &= 0xFF; + if (thisx->params == ENBIGPO_POSSIBLEFIRE) { + if (Flags_GetSwitch(globalCtx, this->switchFlags)) { + Actor_MarkForDeath(&this->actor); + } else { + thisx->update = Actor_Noop; + EnBigpo_InitHiddenFire(this); + } + return; + } + + SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005C18, &D_06000924, this->jointTable, this->morphTable, + ENBIGPO_LIMBCOUNT); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&thisx->colChkInfo, &sDamageTable, &sColChkInfoInit); + + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + firesPtr = &this->fires[i]; + firesPtr->light = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &firesPtr->info); + + Lights_PointNoGlowSetInfo(&firesPtr->info, thisx->home.pos.x, thisx->home.pos.y, thisx->home.pos.z, 255, 255, + 255, 0); + } + + ActorShape_Init(&thisx->shape, 0.0f, func_800B3FC0, 45.0f); + thisx->bgCheckFlags |= 0x400; + this->savedHeight = thisx->home.pos.y + 100.0f; + this->mainColor.r = 255; + this->mainColor.g = 255; + this->mainColor.b = 210; + this->mainColor.a = 0; // fully invisible + + if ((this->switchFlags != 0xFF) && (Flags_GetSwitch(globalCtx, this->switchFlags))) { + Actor_MarkForDeath(&this->actor); + } + + if (thisx->params == ENBIGPO_REGULAR) { // the well poe, starts immediately + thisx->flags &= ~0x10; // always update OFF + this->unkBool204 = true; + EnBigpo_InitWellBigpo(this); + } else if (thisx->params == ENBIGPO_SUMMONED) { // dampe type + EnBigpo_InitDampeMainPo(this); + } +} + +void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + GlobalContext* globalCtx2; + s32 fireCount; + + if ((this->actor.params != ENBIGPO_POSSIBLEFIRE) && (this->actor.params != ENBIGPO_CHOSENFIRE) && + (this->actor.params != ENBIGPO_REVEALEDFIRE) && (this->actor.params != ENBIGPO_UNK5)) { + // if NOT a fire type, *ENBIGPO_REGULAR and ENBIGPO_SUMMONED combat types only) + if (1) {} + globalCtx2 = globalCtx; + for (fireCount = 0; fireCount < ARRAY_COUNT(this->fires); fireCount++) { + LightContext_RemoveLight(globalCtx2, &globalCtx2->lightCtx, this->fires[fireCount].light); + } + Collider_DestroyCylinder(globalCtx2, &this->collider); + } +} + +void func_80B61914(EnBigpo* this) { + EnBigpoFireEffect* firePtr; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + firePtr = &this->fires[i]; + firePtr->pos.x = (Math_SinS(this->actor.shape.rot.y) * this->fireRadius) + this->actor.world.pos.x; + firePtr->pos.z = (Math_CosS(this->actor.shape.rot.y) * this->fireRadius) + this->actor.world.pos.z; + this->actor.shape.rot.y += 0x5555; + } +} + +void EnBigpo_UpdateSpin(EnBigpo* this) { + s16 oldYaw = this->actor.shape.rot.y; + + this->actor.shape.rot.y += this->rotVelocity; + if ((oldYaw < 0) && (this->actor.shape.rot.y > 0)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL); // spinning sfx during spin attack + } +} + +// Lowers the position/eye of the camera during the Big Poe spawn cutscene +void EnBigpo_LowerCutsceneSubCamera(EnBigpo* this, GlobalContext* globalContext) { + Camera* subCam; + + if (this->cutsceneSubCamId != SUBCAM_FREE) { + subCam = Play_GetCamera(globalContext, this->cutsceneSubCamId); + subCam->eye.y -= this->actor.velocity.y; + if (this->actor.velocity.y > 0.0f) { + subCam->eye.x -= 1.5f * Math_SinS(this->actor.yawTowardsPlayer); + subCam->eye.z -= 1.5f * Math_CosS(this->actor.yawTowardsPlayer); + } + Play_CameraSetAtEye(globalContext, this->cutsceneSubCamId, &this->actor.focus.pos, &subCam->eye); + } +} + +void EnBigpo_InitWellBigpo(EnBigpo* this) { + this->actor.flags &= ~0x1; // targetable OFF + this->actionFunc = EnBigpo_WellWaitForProximity; + this->fireRadius = 200.0f; +} + +void EnBigpo_WellWaitForProximity(EnBigpo* this, GlobalContext* globalCtx) { + if (this->actor.xzDistToPlayer < 200.0f) { + EnBigpo_SetupSpawnCutscene(this); + } +} + +void EnBigpo_SetupSpawnCutscene(EnBigpo* this) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = EnBigpo_WaitCutsceneQueue; +} + +void EnBigpo_WaitCutsceneQueue(EnBigpo* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_Start(this->actor.cutscene, &this->actor); + func_800B724C(globalCtx, &this->actor, 7); + this->cutsceneSubCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + if (this->actor.params == ENBIGPO_REGULAR) { // and SUMMONED, got switched earlier + EnBigpo_SpawnCutsceneStage1(this, globalCtx); + } else { // ENBIGPO_REVEALEDFIRE + EnBigpo_SetupFlameCirclePositions(this, globalCtx); + } + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +/* + * stage 1: fires are set to draw, size set to tiny, camera pointed + */ +void EnBigpo_SpawnCutsceneStage1(EnBigpo* this, GlobalContext* globalCtx) { + s32 i; + + this->actor.draw = EnBigpo_DrawCircleFlames; + this->actor.shape.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); + func_80B61914(this); + + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + this->fires[i].pos.y = this->actor.world.pos.y; + } + + this->actor.scale.x = 0.0f; + this->actor.scale.y = 0.015f; + this->actor.scale.z = 0.0f; + + if (this->cutsceneSubCamId != SUBCAM_FREE) { + Vec3f subCamEye; + + subCamEye.x = ((this->actor.world.pos.x - this->fires[0].pos.x) * 1.8f) + this->actor.world.pos.x; + subCamEye.y = this->actor.world.pos.y + 150.0f; + subCamEye.z = ((this->actor.world.pos.z - this->fires[0].pos.z) * 1.8f) + this->actor.world.pos.z; + Play_CameraSetAtEye(globalCtx, this->cutsceneSubCamId, &this->actor.focus.pos, &subCamEye); + } + this->actionFunc = EnBigpo_SpawnCutsceneStage2; +} + +/* + * stage 2: fires are growing to full size + */ +void EnBigpo_SpawnCutsceneStage2(EnBigpo* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.001f)) { + EnBigpo_SpawnCutsceneStage3(this); + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = ((0.01f - this->actor.scale.x) * 0.5f) + 0.01f; +} + +/* + * stage 3: switch to fires rotating + */ +void EnBigpo_SpawnCutsceneStage3(EnBigpo* this) { + this->rotVelocity = 0x1000; + this->actionFunc = EnBigpo_SpawnCutsceneStage4; + this->fireRadius = 200.0f; + this->actor.velocity.y = 0.0f; +} + +/* + * stage 4: fires are circling inward toward each other + */ +void EnBigpo_SpawnCutsceneStage4(EnBigpo* this, GlobalContext* globalCtx) { + s32 i; + + if (Math_StepToF(&this->fireRadius, 30.0f, 5.0f)) { + this->rotVelocity += 0x80; + this->actor.velocity.y += 0.25f; + } + this->actor.shape.rot.y += this->rotVelocity; + func_80B61914(this); + + if (1) {} + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + this->fires[i].pos.y += this->actor.velocity.y; + } + + this->actor.world.pos.y += this->actor.velocity.y; + EnBigpo_LowerCutsceneSubCamera(this, globalCtx); + if (this->actor.velocity.y >= 4.0f) { + EnBigpo_SpawnCutsceneStage5(this); + } +} + +/* + * stage 5: fires have touched, they start to rise, + * big poe starts to visibly appear + */ +void EnBigpo_SpawnCutsceneStage5(EnBigpo* this) { + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06001360); + this->actor.draw = EnBigpo_DrawMainBigpo; + Actor_SetScale(&this->actor, 0.014f); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + this->actionFunc = EnBigpo_SpawnCutsceneStage6; +} + +/* + * stage 6: big poe becoming more visible in the flames + * and flames dissapearing + */ +void EnBigpo_SpawnCutsceneStage6(EnBigpo* this, GlobalContext* globalCtx) { + s32 i; + s32 alphaPlus; // color alpha + 10 + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + this->actor.shape.rot.y += this->rotVelocity; + alphaPlus = this->mainColor.a + 10; // decrease transparency + func_80B61914(this); + if (alphaPlus >= 90) { + this->rotVelocity -= 0x80; + this->actor.velocity.y -= 0.25f; + if (alphaPlus >= 180) { + Math_ScaledStepToS(&this->actor.world.rot.y, 0, 0x180); + } + } + this->actor.world.pos.y += this->actor.velocity.y; + + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + this->fires[i].pos.y += this->actor.velocity.y; + } + + EnBigpo_LowerCutsceneSubCamera(this, globalCtx); + if (alphaPlus >= 255) { + this->mainColor.a = 255; // fully visible + EnBigpo_SpawnCutsceneStage7(this); + } else { + this->mainColor.a = alphaPlus; + } +} + +/* + * stage 7: big poe now fully visible + */ +void EnBigpo_SpawnCutsceneStage7(EnBigpo* this) { + this->idleTimer = 15; + if (this->unkBool204 == false) { + func_801A2E54(0x38); + this->unkBool204 = true; + } + this->actionFunc = EnBigpo_SpawnCutsceneStage8; +} + +/* + * stage 8: count 15 frames, animating, then start dampe cutscene if hes here + * also sets the main camera to align with the subCamera + * and switches back from the subCamera back to the main camera + */ +void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx) { + Actor* dampe; + Camera* subCam; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + this->idleTimer--; + if (this->idleTimer == 0) { + subCam = Play_GetCamera(globalCtx, this->cutsceneSubCamId); + Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye); + this->cutsceneSubCamId = SUBCAM_FREE; + if (this->actor.params == ENBIGPO_SUMMONED) { + dampe = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_TK); + if (dampe != NULL) { + // if dampe exists, switch to viewing his running away cutscene + dampe->params = this->actor.cutscene; + } else { + ActorCutscene_Stop(this->actor.cutscene); + } + } else { // ENBIGPO_REGULAR + ActorCutscene_Stop(this->actor.cutscene); + } + func_800B724C(globalCtx, &this->actor, 6); + EnBigpo_SetupIdleFlying(this); // setup idle flying + } +} + +void EnBigpo_SetupWarpOut(EnBigpo* this) { + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; + this->rotVelocity = 0x2000; + this->idleTimer = 32; + this->actor.flags &= ~0x1; // targetable OFF + this->actor.speedXZ = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR); + this->actionFunc = EnBigpo_WarpingOut; +} + +void EnBigpo_WarpingOut(EnBigpo* this, GlobalContext* globalCtx) { + DECR(this->idleTimer); + this->actor.shape.rot.y += this->rotVelocity; + if (this->idleTimer < 16) { + Math_ScaledStepToS(&this->rotVelocity, 0, 0x200); + } + this->mainColor.a = this->idleTimer * (255.0f / 32.0f); + if (this->idleTimer == 0) { + this->mainColor.a = 0; // fully invisible + EnBigpo_SetupWarpIn(this, globalCtx); + } +} + +void EnBigpo_SetupWarpIn(EnBigpo* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + f32 distance = CLAMP_MIN(this->actor.xzDistToPlayer, 200.0f); + s16 randomYaw = (Rand_Next() >> 0x14) + this->actor.yawTowardsPlayer; + + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06001360); + this->rotVelocity = 0x2000; + this->actor.world.pos.x = (Math_SinS(randomYaw) * distance) + player->actor.world.pos.x; + this->actor.world.pos.z = (Math_CosS(randomYaw) * distance) + player->actor.world.pos.z; + this->actionFunc = EnBigpo_WarpingIn; +} + +void EnBigpo_WarpingIn(EnBigpo* this, GlobalContext* globalCtx) { + this->idleTimer++; + this->actor.shape.rot.y -= this->rotVelocity; + if (this->idleTimer >= 16) { + // after 16th frame, start slowing rotation + Math_ScaledStepToS(&this->rotVelocity, 0, 0x200); + } + + this->mainColor.a = this->idleTimer * (255.0f / 32.0f); + if (this->idleTimer == 32) { + this->mainColor.a = 255; // fully visible + if (this->unkBool204 == false) { + func_801A2E54(0x38); + this->unkBool204 = true; + } + EnBigpo_SetupIdleFlying(this); + } +} + +void EnBigpo_SetupIdleFlying(EnBigpo* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000924, -5.0f); + // if poe missed attack, idle 4 seconds, otherwise its reappearing: attack immediately + this->idleTimer = (this->actionFunc == EnBigpo_SpinningDown) ? 80 : 0; + this->hoverHeightCycleTimer = 40; + this->actor.velocity.y = 0.0f; + this->savedHeight = this->actor.world.pos.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->collider.base.acFlags |= AC_ON; + this->collider.base.ocFlags1 |= OC1_ON; + this->actor.flags |= 0x1; // targetable ON + this->actionFunc = EnBigpo_IdleFlying; +} + +void EnBigpo_IdleFlying(EnBigpo* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + DECR(this->idleTimer); + + // flight position calculations + this->hoverHeightCycleTimer = (this->hoverHeightCycleTimer == 0) ? 40 : (this->hoverHeightCycleTimer - 1); + Math_StepToF(&this->savedHeight, player->actor.world.pos.y + 100.0f, 1.5f); + this->actor.world.pos.y = (sin_rad(this->hoverHeightCycleTimer * (M_PI / 20)) * 10.0f) + this->savedHeight; + Math_StepToF(&this->actor.speedXZ, 3.0f, 0.2f); + func_800B9010(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG); + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 300.0f) { + this->unk208 = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + } + + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk208, 0x200) && (Rand_ZeroOne() < 0.075f)) { + this->unk208 += (s16)((((u32)Rand_Next() >> 0x14) + 0x1000) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1)); + } + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (this->idleTimer == 0) { + // poe's break is done, time to attack + EnBigpo_SetupSpinUp(this); + } +} + +void EnBigpo_SetupSpinUp(EnBigpo* this) { + this->collider.base.colType = COLTYPE_METAL; + this->collider.base.acFlags |= AC_HARD; + this->collider.info.bumper.dmgFlags &= ~0x8000; + this->collider.base.atFlags |= AT_ON; + this->rotVelocity = 0x800; + this->actionFunc = EnBigpo_SpinningUp; + this->actor.speedXZ = 0.0f; +} + +void EnBigpo_SpinningUp(EnBigpo* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + this->rotVelocity += 0x200; + EnBigpo_UpdateSpin(this); + if (this->rotVelocity >= 0x3C00) { + EnBigpo_SetupSpinAttack(this); + } +} + +void EnBigpo_SetupSpinAttack(EnBigpo* this) { + // set flying direction at player (not spinning direction) + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actionFunc = EnBigpo_SpinAttack; +} + +void EnBigpo_SpinAttack(EnBigpo* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s16 yawDiff; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_StepToF(&this->actor.speedXZ, 10.0f, 1.0f); + Math_SmoothStepToF(&this->actor.world.pos.y, player->actor.world.pos.y, 0.3f, 7.5f, 1.0f); + EnBigpo_UpdateSpin(this); + yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + // because acFlags AC_HARD and COLTYPE_METAL, if we hit it means we contacted as attack + if ((this->collider.base.atFlags & AT_HIT) || + ((ABS_ALT(yawDiff) > 0x4000) && (this->actor.xzDistToPlayer > 50.0f))) { + // hit the player OR the poe has missed and flew past player + EnBigpo_SetupSpinDown(this); + } +} + +/* + * if po misses, has to spin down before idle flying + */ +void EnBigpo_SetupSpinDown(EnBigpo* this) { + this->collider.base.atFlags &= ~AT_ON; + this->actionFunc = EnBigpo_SpinningDown; +} + +void EnBigpo_SpinningDown(EnBigpo* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_SmoothStepToF(&this->actor.world.pos.y, player->actor.world.pos.y + 100.0f, 0.3f, 5.0f, 1.0f); + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); + if (Math_ScaledStepToS(&this->rotVelocity, 0, 0x200)) { + // spin down complete, re-allow hittable + this->collider.base.colType = COLTYPE_HIT3; + this->collider.base.acFlags &= ~AC_HARD; + this->collider.info.bumper.dmgFlags |= 0x8000; + EnBigpo_SetupIdleFlying(this); + } + EnBigpo_UpdateSpin(this); +} + +/* + * hit by player, stunned + * called by EnBigpo_ApplyDamage + */ +void EnBigpo_HitStun(EnBigpo* this) { + SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06000454, -6.0f); + func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x10); + this->collider.base.acFlags &= ~AC_ON; + func_800BE504(&this->actor, &this->collider); + this->actionFunc = EnBigpo_CheckHealth; + this->actor.speedXZ = 5.0f; +} + +/* + * check if just damaged or dead + */ +void EnBigpo_CheckHealth(EnBigpo* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + if (this->actor.colChkInfo.health == 0) { + EnBigpo_SetupDeath(this); + } else { + EnBigpo_SetupWarpOut(this); + } + } +} + +void EnBigpo_SetupDeath(EnBigpo* this) { + this->idleTimer = 0; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.hintId = 0xFF; + this->collider.base.ocFlags1 &= ~OC1_ON; + this->actionFunc = EnBigpo_BurnAwayDeath; +} + +/* + * from [red damaged poe] to [burning up poe] to [shinking into the lantern] + */ +void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx) { + Vec3f tempVec; + f32 unkTemp2; // dont really know what these unktemps are doing + s16 cam; + s16 unkTemp; + s16 modifiedTimer; + + this->idleTimer++; + if (this->idleTimer < 8) { + cam = func_800DFCDC(ACTIVE_CAM) + 0x4800; + if (this->idleTimer < 5) { + unkTemp = (this->idleTimer << 0xC) - 0x4000; + // 1.4.0...1 is NOT 1.4, the rodata demands it + tempVec.y = (((Math_SinS(unkTemp) * 23.0f) + 40.0f) * 1.4000001f) + this->actor.world.pos.y; + unkTemp2 = Math_CosS(unkTemp) * 32.2f; + tempVec.x = (Math_SinS(cam) * unkTemp2) + this->actor.world.pos.x; + tempVec.z = (Math_CosS(cam) * unkTemp2) + this->actor.world.pos.z; + + } else { + tempVec.y = this->actor.world.pos.y + ((40.0f + (15.0f * (this->idleTimer - 5))) * 1.4000001f); + tempVec.x = (Math_SinS(cam) * 32.2f) + this->actor.world.pos.x; + tempVec.z = (Math_CosS(cam) * 32.2f) + this->actor.world.pos.z; + } + + // not sure what we're turning this into, but its based on the timer + modifiedTimer = ((f32)((this->idleTimer * 10) + 80) * 1.4000001f); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + tempVec.x = (2.0f * this->actor.world.pos.x) - tempVec.x; + tempVec.z = (2.0f * this->actor.world.pos.z) - tempVec.z; + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + tempVec.x = this->actor.world.pos.x; + tempVec.z = this->actor.world.pos.z; + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + + } else if (this->idleTimer >= 28) { + EnBigpo_SetupLanternDrop(this, globalCtx); + + } else if (this->idleTimer >= 19) { + this->actor.scale.x = ((28 - this->idleTimer) * 0.014f) * 0.1f; + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; + this->actor.world.pos.y += 5.0f; + } + + if (this->idleTimer < 18) { + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); // burning sfx + } + if (this->idleTimer == 18) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); + } +} + +void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx) { + this->actor.draw = EnBigpo_DrawLantern; + this->actor.shape.shadowDraw = NULL; + this->actor.world.pos.x = this->drawMtxF.wx; + this->actor.world.pos.y = this->drawMtxF.wy; + this->actor.world.pos.z = this->drawMtxF.wz; + + Actor_SetScale(&this->actor, 0.014f); + this->actor.gravity = -1.0f; + this->actor.shape.yOffset = 1500.0f; + this->actor.shape.rot.x = -0x8000; + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y -= 15.0f; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_MISC); + this->actor.flags &= ~(0x1 | 0x4); // targetable OFF, enemy music OFF + this->actor.bgCheckFlags &= ~0x400; + this->actionFunc = EnBigpo_LanternFalling; +} + +void EnBigpo_LanternFalling(EnBigpo* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 1 || this->actor.floorHeight == BGCHECK_Y_MIN) { + if (this->switchFlags != 0xFF) { + Actor_SetSwitchFlag(globalCtx, this->switchFlags); + } + + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_BIGPO, 10, &D_060041A0); + EnBigpo_SpawnScoopSoul(this); + } +} + +void EnBigpo_AdjustPoAlpha(EnBigpo* this, s32 alphaDiff) { + s32 newAlpha = this->mainColor.a + alphaDiff; + f32 lowerAlpha; + f32 newXYScale; + + this->mainColor.a = (newAlpha < 0) ? 0 : ((newAlpha > 255) ? 255 : newAlpha); + + lowerAlpha = this->mainColor.a * (1.0f / 255.0f); + if (alphaDiff < 0) { + newXYScale = (0.0056000003f * lowerAlpha) + 0.0014000001f; + this->actor.scale.x = newXYScale; + this->actor.scale.z = newXYScale; + this->actor.scale.y = (0.007f - (0.007f * lowerAlpha)) + 0.007f; + lowerAlpha = lowerAlpha; + } else { + Actor_SetScale(&this->actor, lowerAlpha * 0.007f); + this->actor.world.pos.y = this->savedHeight + (lowerAlpha * 15.0f); + lowerAlpha = 1.0f; + } + + this->mainColor.r = 255.0f * lowerAlpha; + this->mainColor.g = 200.0f * lowerAlpha; + this->mainColor.b = 0; +} + +void EnBigpo_SpawnScoopSoul(EnBigpo* this) { + this->actor.draw = EnBigpo_DrawScoopSoul; + this->actor.shape.yOffset = 0.0f; + this->actor.shape.rot.x = 0; + this->actor.shape.rot.y = 0; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->mainColor.a = 0; // fully invisible + this->actor.scale.x = 0.0f; + this->actor.scale.y = 0.0f; + this->savedHeight = this->actor.world.pos.y; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND); // misnamed? + this->actionFunc = EnBigpo_ScoopSoulAppearing; +} + +void EnBigpo_ScoopSoulAppearing(EnBigpo* this, GlobalContext* globalCtx) { + this->savedHeight += 2.0f; + EnBigpo_AdjustPoAlpha(this, 20); // increase visibility + if (this->mainColor.a == 255) { // fully visible + EnBigpo_SetupScoopSoulIdle(this); + } +} + +void EnBigpo_SetupScoopSoulIdle(EnBigpo* this) { + this->savedHeight = this->actor.world.pos.y; + Actor_SetHeight(&this->actor, -10.0f); + this->idleTimer = 400; // 20 seconds + this->actor.flags |= 0x1; // targetable ON + this->actionFunc = EnBigpo_ScoopSoulIdle; +} + +void EnBigpo_ScoopSoulIdle(EnBigpo* this, GlobalContext* globalCtx) { + DECR(this->idleTimer); + if (Actor_HasParent(&this->actor, globalCtx)) { + Actor_MarkForDeath(&this->actor); + } else if (this->idleTimer == 0) { + // took too long, soul is leaving + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + EnBigpo_SetupScoopSoulLeaving(this); + } else { + func_800B8A1C(&this->actor, globalCtx, 0xBA, 35.0f, 60.0f); + this->actor.world.pos.y = (sin_rad(this->idleTimer * (M_PI / 20)) * 5.0f) + this->savedHeight; + } +} + +void EnBigpo_SetupScoopSoulLeaving(EnBigpo* this) { + this->actor.flags &= ~(0x1 | 0x10000); // targetable OFF and unknown OFF + this->actionFunc = EnBigpo_ScoopSoulFadingAway; +} + +void EnBigpo_ScoopSoulFadingAway(EnBigpo* this, GlobalContext* globalCtx) { + EnBigpo_AdjustPoAlpha(this, -13); + if (this->mainColor.a == 0) { // fully invisible + Actor_MarkForDeath(&this->actor); + } +} + +void EnBigpo_InitDampeMainPo(EnBigpo* this) { + this->actor.flags &= ~0x1; // targetable OFF + this->actionFunc = EnBigpo_SelectRandomFireLocations; +} + +/* + * dampe fires are in 3/N random locations, here we pick them randomly + */ +void EnBigpo_SelectRandomFireLocations(EnBigpo* this, GlobalContext* globalCtx) { + Actor* enemyPtr; + EnBigpo* randomFirePo; + s32 fireIndex; + s32 randomIndex; + s32 fireCount = 0; + + // count the number of possible fires we can find (4 in vanilla) + for (enemyPtr = FIRST_ENEMY; enemyPtr != NULL; enemyPtr = enemyPtr->next) { + if (enemyPtr->id == ACTOR_EN_BIGPO && enemyPtr->params == ENBIGPO_POSSIBLEFIRE) { + fireCount++; + } + } + + // if not enough fires exist, just starting fighting immediately + if (fireCount < ARRAY_COUNT(this->fires)) { + this->actor.draw = EnBigpo_DrawMainBigpo; + Actor_SetScale(&this->actor, 0.014f); + EnBigpo_SetupWarpIn(this, globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.world.pos.y += 100.0f; + return; + } + + // for available possiblefires, pick three to be random fires + for (fireIndex = 0; fireIndex < ARRAY_COUNT(this->fires); fireIndex++, fireCount--) { + enemyPtr = FIRST_ENEMY; + randomIndex = ((s32)Rand_ZeroFloat(fireCount)) % fireCount; + + while (enemyPtr != NULL) { + if (enemyPtr->id == ACTOR_EN_BIGPO && enemyPtr->params == ENBIGPO_POSSIBLEFIRE) { + if (randomIndex == 0) { + randomFirePo = (EnBigpo*)enemyPtr; + randomFirePo->actor.params = ENBIGPO_CHOSENFIRE; + Math_Vec3f_Copy(&this->fires[fireIndex].pos, &randomFirePo->actor.world.pos); + randomFirePo->actor.parent = (Actor*)this; + randomFirePo->actor.update = EnBigpo_UpdateFire; + func_800BC154(globalCtx, &globalCtx->actorCtx, &randomFirePo->actor, ACTORCAT_PROP); + randomFirePo->unk20C = fireIndex; + randomFirePo->actor.flags &= ~0x1; // targetable OFF + // make invisible by size: 0 + Actor_SetScale(&randomFirePo->actor, 0); + + if (this->actor.child == NULL) { + this->actor.child = &randomFirePo->actor; + } else { + randomFirePo->actor.child = this->actor.child; + this->actor.child = &randomFirePo->actor; + } + break; + } else { + randomIndex--; + } + } + enemyPtr = enemyPtr->next; + } + } + + // remove unused fires + for (enemyPtr = FIRST_ENEMY; enemyPtr != NULL; enemyPtr = enemyPtr->next) { + if (enemyPtr->id == ACTOR_EN_BIGPO && enemyPtr->params == ENBIGPO_POSSIBLEFIRE) { + randomFirePo = (EnBigpo*)enemyPtr; + randomFirePo->actionFunc = EnBigpo_Die; + randomFirePo->actor.update = EnBigpo_UpdateFire; + } + } + + EnBigpo_ChangeToFireCounting(this); +} + +void EnBigpo_ChangeToFireCounting(EnBigpo* this) { + this->actionFunc = EnBigpo_FireCounting; +} + +/* + * count fires already found by Dampe, + * once enough: spawn big poe for fight + */ +void EnBigpo_FireCounting(EnBigpo* this, GlobalContext* globalCtx) { + EnBigpo* firePo; + s32 activatedFireCount = 0; + + for (firePo = (EnBigpo*)this->actor.child; firePo; firePo = (EnBigpo*)firePo->actor.child) { + if (firePo->actor.params == ENBIGPO_REVEALEDFIRE && firePo->actionFunc == EnBigpo_RevealedFireIdle) { + activatedFireCount++; + } + } + + if (activatedFireCount == ARRAY_COUNT(this->fires)) { // all fires found + EnBigpo_SetupSpawnCutscene(this); + } +} + +void EnBigpo_SetupFlameCirclePositions(EnBigpo* this, GlobalContext* globalCtx) { + EnBigpo* firePo; + Vec3f subCamEye; + + this->idleTimer = 39; + for (firePo = (EnBigpo*)this->actor.child; firePo; firePo = (EnBigpo*)firePo->actor.child) { + EnBigpo_SetupFlameCircleCutscene(firePo); + } + + // Setup sub camera + if (this->cutsceneSubCamId != SUBCAM_FREE) { + subCamEye.x = (Math_SinS(this->actor.yawTowardsPlayer) * 360.0f) + this->actor.world.pos.x; + subCamEye.y = this->actor.world.pos.y + 150.0f; + subCamEye.z = (Math_CosS(this->actor.yawTowardsPlayer) * 360.0f) + this->actor.world.pos.z; + Play_CameraSetAtEye(globalCtx, this->cutsceneSubCamId, &this->actor.focus.pos, &subCamEye); + } + + this->actionFunc = EnBigpo_DoNothing; +} + +void EnBigpo_DoNothing(EnBigpo* this, GlobalContext* globalCtx) { +} + +void EnBigpo_InitHiddenFire(EnBigpo* this) { + this->actor.draw = NULL; + this->actionFunc = EnBigpo_WaitingForDampe; +} + +/* + * idle until dampe finds this file by + * changing this file params from ENBIGPO_POSSIBLEFIRE into ENBIGPO_REVEALEDFIRE + */ +void EnBigpo_WaitingForDampe(EnBigpo* this, GlobalContext* globalCtx) { + if (this->actor.params == ENBIGPO_REVEALEDFIRE) { + EnBigpo_SetupFireRevealed(this); + } +} + +void EnBigpo_Die(EnBigpo* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} + +void EnBigpo_SetupFireRevealed(EnBigpo* this) { + this->actor.draw = EnBigpo_RevealedFire; + this->idleTimer = 15; + this->actionFunc = EnBigpo_RevealedFireGrowing; +} + +void EnBigpo_RevealedFireGrowing(EnBigpo* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f)) { + this->idleTimer--; + if (this->idleTimer == 0) { + EnBigpo_SetupRevealedFireIdle(this); + } + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = ((0.01f - this->actor.scale.x) * 0.5f) + 0.01f; +} + +void EnBigpo_SetupRevealedFireIdle(EnBigpo* this) { + this->idleTimer = 10000; // 8 minutes until the fire leaves + this->actionFunc = EnBigpo_RevealedFireIdle; +} + +void EnBigpo_RevealedFireIdle(EnBigpo* this, GlobalContext* globalCtx) { + if (this->idleTimer > 0) { + if (this->idleTimer == 0) { + //! @bug: unreachable code + this->actor.params = ENBIGPO_UNK5; + return; + } + } else { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.001f)) { + this->actor.params = ENBIGPO_CHOSENFIRE; + EnBigpo_InitHiddenFire(this); + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = ((0.01f - this->actor.scale.x) * 0.5f) + 0.01f; + } +} + +void EnBigpo_SetupFlameCircleCutscene(EnBigpo* this) { + s16 flameHeight; + + this->idleTimer = 40; // 2 seconds + flameHeight = this->actor.parent->yawTowardsPlayer + this->unk20C * 0x5555; + this->actor.home.pos.x = Math_SinS(flameHeight) * 30.0f + this->actor.parent->world.pos.x; + this->actor.home.pos.y = this->actor.parent->world.pos.y; + this->actor.home.pos.z = Math_CosS(flameHeight) * 30.0f + this->actor.parent->world.pos.z; + this->actionFunc = EnBigpo_FlameCircleCutscene; +} + +/* + * every frame, swirl the flames toward big poe as summoned + */ +void EnBigpo_FlameCircleCutscene(EnBigpo* this, GlobalContext* globalCtx) { + Vec3f posDiff; + f32 magnitude; + + this->idleTimer--; + if (this->idleTimer == 0) { + EnBigpo* parentPoh = (EnBigpo*)this->actor.parent; + Actor_SetSwitchFlag(globalCtx, this->switchFlags); + Math_Vec3f_Copy(&parentPoh->fires[this->unk20C].pos, &this->actor.world.pos); + Actor_MarkForDeath(&this->actor); + if (this->unk20C == 0) { + parentPoh->actor.draw = EnBigpo_DrawCircleFlames; + Actor_SetScale(&parentPoh->actor, 0.01f); + EnBigpo_SpawnCutsceneStage3(parentPoh); + parentPoh->fireRadius = 30.0f; + } + } else { + Math_Vec3f_Diff(&this->actor.world.pos, &this->actor.home.pos, &posDiff); + magnitude = Math3D_Vec3fMagnitude(&posDiff); + if (magnitude > 0.0001f) { + Math_Vec3f_Scale(&posDiff, 1.0f / magnitude); + } + magnitude = magnitude / this->idleTimer; + this->actor.world.pos.x -= magnitude * posDiff.x; + this->actor.world.pos.y -= magnitude * posDiff.y; + this->actor.world.pos.z -= magnitude * posDiff.z; + } +} + +void EnBigpo_UpdateColor(EnBigpo* this) { + s32 bplus5; + s32 bminus5; + + if (this->actionFunc == EnBigpo_CheckHealth) { + if (this->actor.colorFilterTimer & 2) { + this->mainColor.r = 0; + this->mainColor.g = 0; + this->mainColor.b = 0; + } else { + this->mainColor.r = 80; // teal? what about the red health? + this->mainColor.g = 255; + this->mainColor.b = 225; + } + } else { + this->mainColor.r = CLAMP_MAX(this->mainColor.r + 5, 255); + this->mainColor.g = CLAMP_MAX(this->mainColor.g + 5, 255); + + // this might be a triple ternary but it matches and is easier to read spread out + bplus5 = this->mainColor.b + 5; + if (this->mainColor.b >= 211) { + bminus5 = this->mainColor.b - 5; + if (bminus5 < 210) { + this->mainColor.b = 210; + } else { + this->mainColor.b = bminus5; + } + } else { + if (bplus5 >= 211) { + this->mainColor.b = 210; + } else { + this->mainColor.b = bplus5; + } + } + } +} + +void EnBigpo_FlickerLanternLight(EnBigpo* this) { + f32 rand = Rand_ZeroOne(); + + this->lanternColor.r = ((s32)(rand * 30.0f)) + 225; + this->lanternColor.g = ((s32)(rand * 100.0f)) + 155; + this->lanternColor.b = ((s32)(rand * 160.0f)) + 95; + this->lanternColor.a = ((s32)(rand * 30.0f)) + 220; +} + +s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx) { + if ((this->collider.base.acFlags & AC_HIT) && !(this->collider.base.acFlags & AC_HARD)) { + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actor.colChkInfo.damageEffect == 0xF) { + return true; + } + + if (Actor_ApplyDamage(&this->actor) == 0) { + this->actor.flags &= ~0x1; // targetable OFF + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + if (this->actor.params == ENBIGPO_SUMMONED) { // dampe type + func_801A2ED8(); + } + } else { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE); + } + + // light arrows + if (this->actor.colChkInfo.damageEffect == 4) { + this->unk21C = 4.0f; + this->unk220 = 1.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.info.bumper.hitPos.x, + this->collider.info.bumper.hitPos.y, this->collider.info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_LARGE_LIGHT_RAYS); + } + EnBigpo_HitStun(this); + return true; + } + return false; +} + +void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + s32 pad; + ColliderCylinder* thisCollider; + + if ((this->actor.flags & 0x2000) == 0x2000) { + this->hoverHeightCycleTimer = 0; + this->savedHeight = this->actor.world.pos.y; + } + + if (EnBigpo_ApplyDamage(this, globalCtx) == 0) { + if ((this->actor.isTargeted) && (this->actionFunc != EnBigpo_WarpingOut) && + !(this->collider.base.acFlags & AC_HARD) && (this->actor.category == ACTORCAT_ENEMY)) { + this->unk20C++; + } else { + this->unk20C = 0; + } + if (this->unk20C == 40) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + EnBigpo_SetupWarpOut(this); + } + } + + this->actionFunc(this, globalCtx); + if ((this->actionFunc != EnBigpo_SpawnCutsceneStage6) && (this->actionFunc != EnBigpo_SpawnCutsceneStage4)) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + if (this->actionFunc == EnBigpo_LanternFalling) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 27.0f, 60.0f, 4); + } + + if (this->actor.draw == EnBigpo_DrawScoopSoul) { + Actor_SetHeight(&this->actor, -10.0f); + } else { + Actor_SetHeight(&this->actor, 42.0f); + } + + EnBigpo_UpdateColor(this); + EnBigpo_FlickerLanternLight(this); + + this->actor.shape.shadowAlpha = this->mainColor.a; + thisCollider = &this->collider; + Collider_UpdateCylinder(&this->actor, thisCollider); + if (this->collider.base.ocFlags1 & OC1_ON) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &thisCollider->base); + } + if (this->collider.base.atFlags & AT_ON) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &thisCollider->base); + } + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &thisCollider->base); + } + + if (this->unk21C > 0.0f) { + Math_StepToF(&this->unk21C, 0.0f, 0.05f); + if (this->mainColor.a != 255) { // NOT fully visible + if (this->mainColor.a * (1.0f / 255.0f) < this->mainColor.a) { + this->unk21C = this->mainColor.a * (1.0f / 255.0f); + } + } + this->unk220 = ((this->unk21C + 1.0f) * 0.5f); + this->unk220 = CLAMP_MAX(this->unk220, 1.0f); + } +} + +/* + * alt update func: the revealed fires under dampe's house + */ +void EnBigpo_UpdateFire(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + this->actor.shape.rot.y = BINANG_ROT180(func_800DFCDC(ACTIVE_CAM)); + this->actionFunc(this, globalCtx); +} + +s32 EnBigpo_OverrideLimbDraw(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor, Gfx** gfx) { + EnBigpo* this = (EnBigpo*)actor; + // not fully invisible + if (!(this->mainColor.a != 0 && limbIndex != 7) || + (this->actionFunc == EnBigpo_BurnAwayDeath && this->idleTimer >= 2)) { + *dList = NULL; + } + return 0; +} + +void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor, Gfx** gfx) { + EnBigpo* this = (EnBigpo*)actor; + s8 limbByte; + Vec3f* v1ptr; // todo: figure out better names + Vec3f* v2ptr; + Vec3f unusedVec; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->actionFunc == EnBigpo_BurnAwayDeath) && (this->idleTimer >= 2) && (limbIndex == 8)) { + gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList((*gfx)++, &D_060058B8); + } + + if (limbIndex == 7) { + // we scale the vec3f... then do nothing with it? + SysMatrix_GetStateTranslationAndScaledY(1400.0f, &unusedVec); + if ((this->actionFunc == EnBigpo_BurnAwayDeath) && (this->idleTimer > 18)) { + if (actor->scale.x != 0.0f) { + Matrix_Scale(0.014f / actor->scale.x, 0.014f / actor->scale.x, 0.014f / actor->scale.x, 1); + } + } + SysMatrix_CopyCurrentState(&this->drawMtxF); + } + + limbByte = D_80B65078[limbIndex]; + if (limbByte != -1) { + if (limbByte < 3) { + SysMatrix_GetStateTranslation(&this->limbPos[limbByte]); + return; + } + if (limbByte == 3) { + SysMatrix_GetStateTranslationAndScaledX(3000.0f, &this->limbPos[limbByte]); + return; + } + if (limbByte == 4) { + SysMatrix_GetStateTranslationAndScaledY(-2000.0f, &this->limbPos[limbByte]); + return; + } + + v2ptr = &this->limbPos[limbByte + 1]; + v1ptr = D_80B65084; + SysMatrix_GetStateTranslationAndScaledX(-4000.0f, &this->limbPos[limbByte]); + + for (i = limbByte + 1; i < ARRAY_COUNT(this->limbPos); i++) { + SysMatrix_MultiplyVector3fByState(v1ptr, v2ptr); + v2ptr++; + v1ptr++; + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + Gfx* dispHead; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { + // fully visible OR fully transparent + dispHead = POLY_OPA_DISP; + gSPDisplayList(dispHead, &sSetupDL[6 * 0x19]); + gSPSegment(&dispHead[1], 0x0C, &D_801AEFA0); + gSPSegment(&dispHead[2], 0x08, + Gfx_EnvColor(globalCtx->state.gfxCtx, this->mainColor.r, this->mainColor.g, this->mainColor.b, + this->mainColor.a)); + POLY_OPA_DISP = SkelAnime_Draw2(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, + EnBigpo_OverrideLimbDraw, EnBigpo_PostLimbDraw, &this->actor, &dispHead[3]); + + } else { + dispHead = POLY_XLU_DISP; + gSPDisplayList(dispHead, &sSetupDL[6 * 0x19]); + gSPSegment(&dispHead[1], 0x0C, &D_801AEF88); + gSPSegment(&dispHead[2], 0x08, + Gfx_EnvColor(globalCtx->state.gfxCtx, this->mainColor.r, this->mainColor.g, this->mainColor.b, + this->mainColor.a)); + POLY_XLU_DISP = SkelAnime_Draw2(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, + EnBigpo_OverrideLimbDraw, EnBigpo_PostLimbDraw, &this->actor, &dispHead[3]); + } + + // 71.428566f might be 500/7 context unknown + func_800BE680(globalCtx, &this->actor, this->limbPos, 9, this->actor.scale.x * 71.428566f * this->unk220, 0, + this->unk21C, 0x14); + + SysMatrix_SetCurrentState(&this->drawMtxF); + EnBigpo_DrawLantern(&this->actor, globalCtx); + if (this->actionFunc == EnBigpo_SpawnCutsceneStage6) { + EnBigpo_DrawCircleFlames(&this->actor, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigpo_DrawScoopSoul(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, + (globalCtx->gameplayFrames * -15) % 512, 0x20, 0x80)); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 170, this->mainColor.a); + + gDPSetEnvColor(POLY_XLU_DISP++, this->mainColor.r, this->mainColor.g, this->mainColor.b, 255); + + Lights_PointNoGlowSetInfo(&this->fires[0].info, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, this->mainColor.r, this->mainColor.g, this->mainColor.b, + this->mainColor.a * 2); + + Matrix_RotateY(BINANG_ROT180(func_800DFCDC(ACTIVE_CAM)), MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, &D_06001BB0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +/* + * this matches without OPENDISPS but with it has stack issues, + * might be able to find an alternative match with the macros, so far no success + */ +void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + f32 magnitude; + f32 magnitude2; + Gfx* dispHead; + Vec3f vec1; + Vec3f vec2; + Camera* cam = ACTIVE_CAM; + + if (cam != NULL) { + Math_Vec3f_Diff(&cam->eye, &cam->at, &vec1); + magnitude = Math3D_Vec3fMagnitude(&vec1); + magnitude2 = (magnitude > 1.0f) ? (20.0f / magnitude) : (20.0f); + Math_Vec3f_Scale(&vec1, magnitude2); + } else { + Math_Vec3f_Copy(&vec1, &D_801D15B0); + } + + { + GraphicsContext* gfx = globalCtx->state.gfxCtx; + + // fully visible OR fully transparent + if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { + Scene_SetRenderModeXlu(globalCtx, 0, 1); + dispHead = gfx->polyOpa.p; + } else { + Scene_SetRenderModeXlu(globalCtx, 1, 2); + dispHead = gfx->polyXlu.p; + } + + gSPDisplayList(&dispHead[0], &sSetupDL[6 * 0x19]); + + gSPSegment(&dispHead[1], 0x0A, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 0, 255, this->mainColor.a)); + + SysMatrix_GetStateTranslationAndScaledY(1400.0f, &vec2); + Lights_PointGlowSetInfo(&this->fires[0].info, vec2.x + vec1.x, vec2.y + vec1.y, vec2.z + vec1.z, + this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, this->lanternColor.a); + + gDPSetEnvColor(&dispHead[2], this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, + this->mainColor.a); + + gSPMatrix(&dispHead[3], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(&dispHead[4], &D_060042C8); + + gSPDisplayList(&dispHead[5], &D_060043F8); + + // fully transparent OR fully invisible + if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { + gfx->polyOpa.p = &dispHead[6]; + } else { + gfx->polyXlu.p = &dispHead[6]; + } + } +} -extern ColliderCylinderInit D_80B65010; -extern CollisionCheckInfoInit D_80B6503C; -extern DamageTable D_80B65044; -extern InitChainEntry D_80B65064[]; +void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + s32 pad[3]; + s16 fireRadius; + MtxF* mtfxPtr; + s32 i; -extern UNK_TYPE D_06000454; -extern UNK_TYPE D_06000924; -extern UNK_TYPE D_06001360; -extern UNK_TYPE D_06001BB0; -extern UNK_TYPE D_060041A0; -extern UNK_TYPE D_060042C8; -extern UNK_TYPE D_060058B8; + mtfxPtr = SysMatrix_GetCurrentState(); + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/EnBigpo_Init.s") + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_RotateY(BINANG_ROT180(func_800DFCDC(ACTIVE_CAM)), MTXMODE_NEW); + if (this->actionFunc == EnBigpo_SpawnCutsceneStage6) { + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + fireRadius = 500; + } else { + Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); + fireRadius = (s16)(thisx->scale.x * 500.0f * 100.0f); + } + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, + (globalCtx->gameplayFrames * -20) % 512, 0x20, 0x80)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/EnBigpo_Destroy.s") + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 170, 255, 255, 255 - this->mainColor.a); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 255); + + for (i = 0; i < ARRAY_COUNT(this->fires); i++) { + EnBigpoFireEffect* firePtr = &this->fires[i]; + Lights_PointNoGlowSetInfo(&this->fires[i].info, this->fires[i].pos.x, this->fires[i].pos.y, + this->fires[i].pos.z, 170, 255, 255, fireRadius); + mtfxPtr->wx = firePtr->pos.x; + mtfxPtr->wy = firePtr->pos.y; + mtfxPtr->wz = firePtr->pos.z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, &D_0407D590); // flame displaylist + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigpo_RevealedFire(Actor* thisx, GlobalContext* globalCtx) { + EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* parent = (EnBigpo*)thisx->parent; + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, + (globalCtx->gameplayFrames * -20) % 512, 0x20, 0x80)); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 170, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 255); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61914.s") + Lights_PointNoGlowSetInfo(&parent->fires[this->unk20C].info, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, 170, 255, 255, (s32)(thisx->scale.x * 500.0f * 100.0f)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B619B4.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B619FC.s") + gSPDisplayList(POLY_XLU_DISP++, &D_0407D590); // flame displaylist -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61AC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61AF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61B38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61B70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61C04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61CFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61D74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61E9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B61F04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62034.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62084.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62154.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B621CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B622E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B623BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B624F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6259C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6275C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B627B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62814.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62830.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62900.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62920.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B629E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62A68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62AD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62B10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62E38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62F10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B62FCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B631F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63264.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B632BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6330C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B633E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63410.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63450.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63474.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B636D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B636E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63758.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6382C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6383C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63854.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B638AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B638D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63964.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63980.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63A18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63AC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63C28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63D0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B63D88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/EnBigpo_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64190.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B641E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64240.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64470.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B6467C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64880.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigpo/func_80B64DFC.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h index 72f386f405..9ae87f9f39 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h @@ -5,15 +5,66 @@ struct EnBigpo; -typedef void (*EnBigpoActionFunc)(struct EnBigpo*, GlobalContext*); +typedef void (*EnBigPoActionFunc)(struct EnBigpo*, GlobalContext*); + +typedef struct EnBigpoFireEffect { + /* 0x00 */ Vec3f pos; + /* 0x0C */ LightNode* light; + /* 0x10 */ LightInfo info; // size 0xE +} EnBigpoFireEffect; // size = 0x20 + +#define ENBIGPO_LIMBCOUNT 10 + + +// idleTimer gets reused: +// * after dampe reveals a fire, 8 minutes of frames before it goes away again +// * used by flames and regular bigpo to count frames during the appearance cutscene +// * when idle flying around, frames until next attack +// * when spinning in/out of reality, counts frames from start +// * in burning death, counts frames from death start +// * after scoop spawned, idle timer used to count down to actor disapear typedef struct EnBigpo { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xBC]; - /* 0x0200 */ EnBigpoActionFunc actionFunc; - /* 0x0204 */ char unk_204[0x194]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[ENBIGPO_LIMBCOUNT]; + /* 0x1C4 */ Vec3s morphTable[ENBIGPO_LIMBCOUNT]; + /* 0x200 */ EnBigPoActionFunc actionFunc; + /* 0x204 */ u8 unkBool204; // need to know what func_801A2E54 does to know what this is + /* 0x206 */ s16 idleTimer; // frame counter + /* 0x208 */ s16 unk208; // facing rotY? + /* 0x20A */ s16 rotVelocity; + /* 0x20C */ s16 unk20C; // is this counting the number of frames the player is ztargeting them? + /* 0x20E */ s16 cutsceneSubCamId; + /* 0x210 */ s16 switchFlags; + /* 0x212 */ s16 hoverHeightCycleTimer; // sin wave up and down bobbing + /* 0x214 */ f32 fireRadius; // distance from center during conjunction cutscene + /* 0x218 */ f32 savedHeight; // actual height while flying moves as part of bobbing + // both unk21C and unk220 are passed to func_800BE680, probably need that to know what they are + /* 0x21C */ f32 unk21C; // tied to color alpha, decremented to zero + /* 0x220 */ f32 unk220; // created from unk21C + /* 0x224 */ Vec3f limbPos[9]; + /* 0x290 */ Color_RGBA8 mainColor; + /* 0x294 */ Color_RGBA8 lanternColor; + /* 0x298 */ UNK_TYPE1 pad298[0x14]; + /* 0x2AC */ ColliderCylinder collider; + /* 0x2F8 */ MtxF drawMtxF; + // the three fires that merge to become big po + // also the fires dampe digs up under his house + /* 0x338 */ EnBigpoFireEffect fires[3]; } EnBigpo; // size = 0x398 -extern const ActorInit En_Bigpo_InitVars; +// well ver is regular, dampe basement ver is summoned +// on spawn, 3/possible fires are turned into chosenfire +enum EnBigpoType { + /* 0 */ ENBIGPO_REGULAR, + /* 1 */ ENBIGPO_SUMMONED, + /* 2 */ ENBIGPO_POSSIBLEFIRE, + /* 3 */ ENBIGPO_CHOSENFIRE, + /* 4 */ ENBIGPO_REVEALEDFIRE, + /* 5 */ ENBIGPO_UNK5, +}; + +#define GET_BIGPO_SWITCHFLAGS(thisx) ((u8)(thisx->params >> 0x8)) #endif // Z_EN_BIGPO_H diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index 0f23074539..aee46c2f11 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -571,7 +571,7 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { } if (this->camId != 0) { - func_8016970C(globalCtx, this->camId, &this->at, &this->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->at, &this->eye); } } diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index fcf906cc7b..4dd5512591 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -548,7 +548,7 @@ void func_808BE4D4(EnDekunuts* this, GlobalContext* globalCtx) { sp40.y = this->actor.world.pos.y + 18.0f; sp40.z = this->actor.world.pos.z; EffectSsDeadDb_Spawn(globalCtx, &sp40, &D_801D15B0, &D_801D15B0, &D_808BEF90, &D_808BEF94, 200, 0, 13); - func_800F0568(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); sp40.y = this->actor.world.pos.y + 10.0f; EffectSsHahen_SpawnBurst(globalCtx, &sp40, 3.0f, 0, 12, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xE0); @@ -582,8 +582,8 @@ void func_808BE73C(EnDekunuts* this, GlobalContext* globalCtx) { if ((this->unk_18E != 10) || !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { func_808BD3B4(this, globalCtx); if ((this->actor.colChkInfo.mass == 50) || (this->actor.params != ENDEKUNUTS_GET_FF00_0)) { - if ((this->actor.params != ENDEKUNUTS_GET_FF00_1) && !func_800BE22C(&this->actor)) { - func_800BBA88(globalCtx, &this->actor); + if ((this->actor.params != ENDEKUNUTS_GET_FF00_1) && !Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); } if (this->actor.params == ENDEKUNUTS_GET_FF00_1) { @@ -639,7 +639,7 @@ void func_808BE73C(EnDekunuts* this, GlobalContext* globalCtx) { func_808BDE7C(this); } else if (this->actor.colChkInfo.health != 0) { this->actor.colChkInfo.health = 0; - func_800BBA88(globalCtx, &this->actor); + Enemy_StartFinishingBlow(globalCtx, &this->actor); func_808BE294(this, 0); } } diff --git a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c index baf690fab4..1673ae7274 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c @@ -384,7 +384,7 @@ void func_8089ABF4(EnDinofos* this, GlobalContext* globalCtx) { if (this->camId != 0) { Camera* camera = Play_GetCamera(globalCtx, this->camId); - func_8016970C(globalCtx, 0, &camera->at, &camera->eye); + Play_CameraSetAtEye(globalCtx, 0, &camera->at, &camera->eye); this->camId = 0; ActorCutscene_Stop(this->actor.cutscene); if (this->actor.colChkInfo.health == 0) { @@ -506,7 +506,7 @@ void func_8089B288(EnDinofos* this, GlobalContext* globalCtx) { this->unk_290--; Math_Vec3f_StepTo(&camera->eye, &this->unk_2BC, this->unk_2AC); Math_Vec3f_StepTo(&camera->at, &this->unk_2C8, this->unk_2A8); - func_8016970C(globalCtx, this->camId, &camera->at, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); if (this->unk_290 == 0) { func_8089B320(this); } @@ -540,7 +540,7 @@ void func_8089B3D4(EnDinofos* this, GlobalContext* globalCtx) { sp28.y = camera->at.y; } - func_8016970C(globalCtx, this->camId, &sp28, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &sp28, &camera->eye); if (this->actor.bgCheckFlags & 1) { func_8089B4A4(this); } @@ -565,7 +565,7 @@ void func_8089B580(EnDinofos* this, GlobalContext* globalCtx) { this->unk_290++; if (this->unk_290 < 8) { - func_8016970C(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); } if (this->skelAnime.animCurrentFrame > 35.0f) { @@ -574,7 +574,7 @@ void func_8089B580(EnDinofos* this, GlobalContext* globalCtx) { } Math_Vec3f_StepTo(&camera->eye, &this->unk_2BC, 10.0f); - func_8016970C(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); if (this->skelAnime.animCurrentFrame <= 55.0f) { func_800B9010(&this->actor, NA_SE_EN_DODO_J_FIRE - SFX_FLAG); } @@ -1231,7 +1231,7 @@ void func_8089D318(EnDinofos* this, GlobalContext* globalCtx) { sp24.x = (Math_SinS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.x; sp24.y = this->actor.focus.pos.y; sp24.z = (Math_CosS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.z; - func_8016970C(globalCtx, this->camId, &this->actor.focus.pos, &sp24); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &sp24); func_8089CFAC(this); } else { func_8089B100(this, globalCtx); @@ -1284,8 +1284,8 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { return false; } - if (!func_800BE22C(&this->actor)) { - func_800BBA88(globalCtx, &this->actor); + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); D_8089E350--; if (D_8089E350 == 0) { if (D_8089E34C != -1) { diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index 8b87fbbf55..6c2fcb01b0 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -645,7 +645,7 @@ void EnFirefly_UpdateDamage(EnFirefly* this, GlobalContext* globalCtx) { this->unk_2E8.y = 0.55f; EnFirefly_SetupStunned(this); } else { - func_800BBA88(globalCtx, &this->actor); + Enemy_StartFinishingBlow(globalCtx, &this->actor); this->actor.colChkInfo.health = 0; this->actor.flags &= ~1; diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index 5d58eacde2..1b3cf562f2 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -2307,7 +2307,7 @@ void func_80B479E8(EnInvadepoh* this, GlobalContext* globalCtx) { } if (this->actionTimer == 8) { - func_800BBA88(globalCtx, &this->actor); + Enemy_StartFinishingBlow(globalCtx, &this->actor); } this->actionTimer--; @@ -2372,7 +2372,7 @@ void func_80B47D30(Actor* thisx, GlobalContext* globalCtx) { thisx->gravity = 0.0f; thisx->velocity.y = acAttached->velocity.y * 0.5f; thisx->velocity.y = CLAMP(thisx->velocity.y, -30.0f, 30.0f); - func_800F0568(globalCtx, &thisx->world.pos, 50, NA_SE_EN_INVADER_DEAD); + Audio_PlaySoundAtPosition(globalCtx, &thisx->world.pos, 50, NA_SE_EN_INVADER_DEAD); func_80B47830(this); } diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c index a620514087..41d80f6375 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -289,7 +289,7 @@ void EnMinifrog_ReturnFrogCutscene(EnMinifrog* this, GlobalContext* globalCtx) { default: func_801477B4(globalCtx); EnMinifrog_SetCamera(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_NPC_FADEAWAY); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_NPC_FADEAWAY); if (this->actor.cutscene != -1) { if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { ActorCutscene_Stop(this->actor.cutscene); diff --git a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c index 1205e0cebb..45c8b9bf0c 100644 --- a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c +++ b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c @@ -115,9 +115,9 @@ void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { spawnBurstPos.z = this->actor.world.pos.z; EffectSsHahen_SpawnBurst(globalCtx, &spawnBurstPos, 6.0f, 0, 7, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); if (this->actor.params == 1) { - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_NUTS_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_NUTS_BROKEN); } else { - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK); } Actor_MarkForDeath(&this->actor); } diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c index 36cb76b0cd..8ca3604693 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -354,7 +354,7 @@ void EnPametfrog_ShakeCamera(EnPametfrog* this, GlobalContext* globalCtx, f32 ma eye.x = (Math_SinS(y) * magShakeXZ) + camera->at.x; eye.y = camera->at.y + magShakeY; eye.z = (Math_CosS(y) * magShakeXZ) + camera->at.z; - func_8016970C(globalCtx, this->camId, &camera->at, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &eye); } void EnPametfrog_StopCutscene(EnPametfrog* this, GlobalContext* globalCtx) { @@ -362,7 +362,7 @@ void EnPametfrog_StopCutscene(EnPametfrog* this, GlobalContext* globalCtx) { if (this->camId != 0) { camera = Play_GetCamera(globalCtx, this->camId); - func_8016970C(globalCtx, 0, &camera->at, &camera->eye); + Play_CameraSetAtEye(globalCtx, 0, &camera->at, &camera->eye); this->camId = 0; ActorCutscene_Stop(this->cutscene); func_800B724C(globalCtx, &this->actor, 6); @@ -531,7 +531,7 @@ void EnPametfrog_SetupFallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx eye.x = (Math_SinS(yaw) * 300.0f) + this->actor.focus.pos.x; eye.y = this->actor.focus.pos.y + 100.0f; eye.z = (Math_CosS(yaw) * 300.0f) + this->actor.focus.pos.z; - func_8016970C(globalCtx, this->camId, &this->actor.focus.pos, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &eye); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE); this->actionFunc = EnPametfrog_FallOffSnapper; } @@ -861,7 +861,7 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { eye.x = this->actor.world.pos.x + (xzDist * this->unk_2DC.x); eye.y = (this->actor.world.pos.y + this->actor.home.pos.y) * 0.5f; eye.z = this->actor.world.pos.z + (xzDist * this->unk_2DC.z); - func_8016970C(globalCtx, this->camId, &this->actor.world.pos, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, &eye); } this->actionFunc = EnPametfrog_FallInAir; @@ -879,7 +879,7 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) { } else { this->spinYaw += 0xF00; if (this->camId != 0) { - func_8016970C(globalCtx, this->camId, &this->actor.world.pos, &Play_GetCamera(globalCtx, this->camId)->eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, &Play_GetCamera(globalCtx, this->camId)->eye); } if (this->actor.bgCheckFlags & 1) { @@ -927,7 +927,7 @@ void EnPametfrog_SetupDefeatGekko(EnPametfrog* this, GlobalContext* globalCtx) { eye.x = this->actor.child->focus.pos.x + 150.0f * Math_SinS(yaw); eye.y = this->actor.child->focus.pos.y + 20.0f; eye.z = this->actor.child->focus.pos.z + 150.0f * Math_CosS(yaw); - func_8016970C(globalCtx, this->camId, &this->actor.child->focus.pos, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.child->focus.pos, &eye); this->actor.params = GEKKO_DEFEAT; this->timer = 38; this->actionFunc = EnPametfrog_DefeatGekko; @@ -952,7 +952,7 @@ void EnPametfrog_SetupDefeatSnapper(EnPametfrog* this, GlobalContext* globalCtx) eye.x = this->actor.world.pos.x + Math_SinS(yaw) * 150.0f; eye.y = this->actor.world.pos.y + 20.0f; eye.z = this->actor.world.pos.z + Math_CosS(yaw) * 150.0f; - func_8016970C(globalCtx, this->camId, &this->actor.world.pos, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, &eye); this->timer = 20; this->actionFunc = EnPametfrog_DefeatSnapper; } @@ -983,7 +983,7 @@ void EnPametfrog_SetupSpawnFrog(EnPametfrog* this, GlobalContext* globalCtx) { vec1.z = (Math_CosS(yaw) * 20.0f) + this->actor.world.pos.z; this->collider.base.ocFlags1 &= ~OC1_ON; func_800B0DE0(globalCtx, &vec1, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 800, 50); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); for (i = 0; i < 25; i++) { @@ -1211,7 +1211,7 @@ void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { eye.y = at.y + 4.0f; // Zooms in on Gekko - func_8016970C(globalCtx, this->camId, &at, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); this->timer = 0; this->actor.hintId = 0x5F; this->actionFunc = EnPametfrog_CallSnapper; @@ -1243,7 +1243,7 @@ void EnPametfrog_SetupSnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx) eye.z = (Math_CosS(yaw) * 500.0f) + at.z; // Zooms in on Snapper spawn point - func_8016970C(globalCtx, this->camId, &at, &eye); + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); this->quake = Quake_Add(ACTIVE_CAM, 6); Quake_SetSpeed(this->quake, 18000); Quake_SetQuakeValues(this->quake, 2, 0, 0, 0); @@ -1288,7 +1288,7 @@ void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) if ((this->drawEffect != GEKKO_DRAW_EFFECT_FROZEN) || !(this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { if (this->actor.params == GEKKO_PRE_SNAPPER) { - if (func_800BE22C(&this->actor) == 0) { + if (Actor_ApplyDamage(&this->actor) == 0) { func_801A2ED8(); } @@ -1321,10 +1321,10 @@ void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) } EnPametfrog_SetupDamage(this); } - } else if (func_800BE22C(&this->actor) == 0) { + } else if (Actor_ApplyDamage(&this->actor) == 0) { this->collider.base.acFlags &= ~AC_ON; EnPametfrog_ApplyMagicArrowEffects(this, globalCtx); - func_800BBA88(globalCtx, &this->actor); + Enemy_StartFinishingBlow(globalCtx, &this->actor); this->actor.flags &= ~1; func_801A2ED8(); EnPametfrog_SetupCutscene(this); diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/src/overlays/actors/ovl_En_Sb/z_en_sb.c index 98d078e793..673a5445f9 100644 --- a/src/overlays/actors/ovl_En_Sb/z_en_sb.c +++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.c @@ -332,7 +332,7 @@ void EnSb_UpdateDamage(EnSb* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == 0xF) { hitPlayer = 0; if (this->vulnerableTimer != 0) { - func_800BE22C(&this->actor); + Actor_ApplyDamage(&this->actor); func_800BCB70(&this->actor, 0x4000, 0xFF, 0x2000, 80); hitPlayer = 1; } @@ -343,8 +343,8 @@ void EnSb_UpdateDamage(EnSb* this, GlobalContext* globalCtx) { this->isDrawn = true; } this->isDead = true; - func_800BBA88(globalCtx, &this->actor); - func_800F0568(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EN_BEE_FLY); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EN_BEE_FLY); return; } hitPoint.x = this->collider.info.bumper.hitPos.x; diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c index 46ed92635e..fa872c109c 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -154,7 +154,7 @@ void EnSuttari_UpdateCollider(EnSuttari* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == 0xF) { this->flags1 |= 0x100; this->flags1 &= ~0x40; - func_800BBA88(globalCtx, &this->actor); + Enemy_StartFinishingBlow(globalCtx, &this->actor); } else if (this->actor.colChkInfo.damageEffect == 0xE) { this->flags1 |= 0x200; this->flags1 &= ~0x40; @@ -1196,7 +1196,7 @@ void func_80BAD380(EnSuttari* this, GlobalContext* globalCtx) { this->actor.speedXZ = 0.0f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_SMALL_EXPLOSION); - func_800F0568(globalCtx, &this->actor.world.pos, 30, NA_SE_IT_BOMB_EXPLOSION); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_IT_BOMB_EXPLOSION); Actor_MarkForDeath(&this->actor); return; } diff --git a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c index 01ab0f206c..df8a039e77 100644 --- a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c +++ b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c @@ -166,11 +166,9 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { Player* player = PLAYER; Player* player2 = PLAYER; - // in oot func_800F0568 is Audio_PlaySoundAtPosition - if ((this->actor.bgCheckFlags & 0x20) && (this->actor.yDistToWater > 15.0f)) { EnTuboTrap_SpawnEffectsInWater(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_BOMB_DROP_WATER); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_BOMB_DROP_WATER); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -179,8 +177,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (this->collider.base.atFlags & AT_BOUNCED) { this->collider.base.atFlags &= ~AT_BOUNCED; EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_SHIELD_REFLECT_SW); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_SHIELD_REFLECT_SW); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -189,8 +187,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -201,8 +199,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (&player->actor == this->collider.base.at) { EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); - func_800F0568(globalCtx, &player2->actor.world.pos, 40, NA_SE_PL_BODY_HIT); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &player2->actor.world.pos, 40, NA_SE_PL_BODY_HIT); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -211,7 +209,7 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 8) || (this->actor.bgCheckFlags & 1)) { EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); } diff --git a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c index 44fd407bb8..53c7083688 100644 --- a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c +++ b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c @@ -273,13 +273,13 @@ void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx) { } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.yDistToWater > 19.0f)) { ObjKibako_WaterBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); Actor_MarkForDeath(&this->actor); } else if (this->collider.base.acFlags & AC_HIT) { ObjKibako_AirBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); Actor_MarkForDeath(&this->actor); } else { Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); @@ -377,14 +377,14 @@ void ObjKibako_Thrown(ObjKibako* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 0xB) || (atHit) || (this->timer <= 0)) { ObjKibako_AirBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); Actor_MarkForDeath(&this->actor); } else { if (this->actor.bgCheckFlags & 0x40) { ObjKibako_WaterBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - func_800F0568(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); - func_800F0568(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); Actor_MarkForDeath(&this->actor); } else { if (this->actor.velocity.y < -0.05f) { diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c index eb5fa284ca..dd87d150d3 100644 --- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c +++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c @@ -212,7 +212,7 @@ s32 ObjKibako2_ShouldBreak(ObjKibako2* this) { void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx) { if (ObjKibako2_ShouldBreak(this)) { ObjKibako2_Break(this, globalCtx); - func_800F0568(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); this->dyna.actor.flags |= 0x10; func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); this->dyna.actor.draw = NULL; diff --git a/tools/actorfixer.py b/tools/actorfixer.py index 4d8ed07895..3f5bade7f6 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -16,6 +16,10 @@ animdict ={ "func_8012404c": "Player_RemoveMask", "Actor_SpawnWithParentAndCutscene": "Actor_SpawnAsChildAndCutscene", "Actor_SpawnWithParent": "Actor_SpawnAsChild", + "func_800BE22C": "Actor_ApplyDamage", + "func_800F0568": "Audio_PlaySoundAtPosition", + "func_8016970C": "Play_CameraSetAtEye", + "func_800BBA88": "Enemy_StartFinishingBlow", } def replace_anim(file): diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index d1213221ca..71745a5821 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -843,7 +843,7 @@ 0x800BB59C:("func_800BB59C",), 0x800BB604:("func_800BB604",), 0x800BB8EC:("func_800BB8EC",), - 0x800BBA88:("func_800BBA88",), + 0x800BBA88:("Enemy_StartFinishingBlow",), 0x800BBAC0:("func_800BBAC0",), 0x800BBB74:("func_800BBB74",), 0x800BBC20:("func_800BBC20",), @@ -884,7 +884,7 @@ 0x800BE03C:("func_800BE03C",), 0x800BE0B8:("func_800BE0B8",), 0x800BE184:("func_800BE184",), - 0x800BE22C:("func_800BE22C",), + 0x800BE22C:("Actor_ApplyDamage",), 0x800BE258:("func_800BE258",), 0x800BE2B8:("func_800BE2B8",), 0x800BE33C:("func_800BE33C",), @@ -1613,7 +1613,7 @@ 0x800F0390:("func_800F0390",), 0x800F03C0:("func_800F03C0",), 0x800F048C:("func_800F048C",), - 0x800F0568:("func_800F0568",), + 0x800F0568:("Audio_PlaySoundAtPosition",), 0x800F0590:("func_800F0590",), 0x800F05C0:("func_800F05C0",), 0x800F07C0:("func_800F07C0",), @@ -3012,7 +3012,7 @@ 0x80169600:("func_80169600",), 0x80169668:("func_80169668",), 0x801696D4:("Play_GetCamera",), - 0x8016970C:("func_8016970C",), + 0x8016970C:("Play_CameraSetAtEye",), 0x8016981C:("func_8016981C",), 0x80169940:("func_80169940",), 0x80169988:("func_80169988",), @@ -14168,8 +14168,8 @@ 0x80B61914:("func_80B61914",), 0x80B619B4:("func_80B619B4",), 0x80B619FC:("func_80B619FC",), - 0x80B61AC8:("func_80B61AC8",), - 0x80B61AF8:("func_80B61AF8",), + 0x80B61AC8:("EnBigPo_InitWellBigPo",), + 0x80B61AF8:("EnBigPo_WellWaitForProximity",), 0x80B61B38:("func_80B61B38",), 0x80B61B70:("func_80B61B70",), 0x80B61C04:("func_80B61C04",), @@ -14180,40 +14180,40 @@ 0x80B61F04:("func_80B61F04",), 0x80B62034:("func_80B62034",), 0x80B62084:("func_80B62084",), - 0x80B62154:("func_80B62154",), - 0x80B621CC:("func_80B621CC",), - 0x80B622E4:("func_80B622E4",), - 0x80B623BC:("func_80B623BC",), - 0x80B624F4:("func_80B624F4",), - 0x80B6259C:("func_80B6259C",), - 0x80B6275C:("func_80B6275C",), - 0x80B627B4:("func_80B627B4",), - 0x80B62814:("func_80B62814",), - 0x80B62830:("func_80B62830",), - 0x80B62900:("func_80B62900",), - 0x80B62920:("func_80B62920",), - 0x80B629E4:("func_80B629E4",), - 0x80B62A68:("func_80B62A68",), - 0x80B62AD4:("func_80B62AD4",), - 0x80B62B10:("func_80B62B10",), - 0x80B62E38:("func_80B62E38",), - 0x80B62F10:("func_80B62F10",), - 0x80B62FCC:("func_80B62FCC",), - 0x80B631F8:("func_80B631F8",), - 0x80B63264:("func_80B63264",), - 0x80B632BC:("func_80B632BC",), - 0x80B6330C:("func_80B6330C",), - 0x80B633E8:("func_80B633E8",), - 0x80B63410:("func_80B63410",), + 0x80B62154:("EnBigPo_SetupWarpOut",), + 0x80B621CC:("EnBigPo_WarpingOut",), + 0x80B622E4:("EnBigPo_SetupWarpIn",), + 0x80B623BC:("EnBigPo_WarpingIn",), + 0x80B624F4:("EnBigPo_SetupIdleFlying",), + 0x80B6259C:("EnBigPo_IdleFlying",), + 0x80B6275C:("EnBigPo_SetupSpinUp",), + 0x80B627B4:("EnBigPo_SpinningUp",), + 0x80B62814:("EnBigPo_SetupSpinAttack",), + 0x80B62830:("EnBigPo_SpinAttack",), + 0x80B62900:("EnBigPo_SetupSpinDown",), + 0x80B62920:("EnBigPo_SpinningDown",), + 0x80B629E4:("EnBigPo_HitStun",), + 0x80B62A68:("EnBigPo_CheckHealth",), + 0x80B62AD4:("EnBigPo_SetupDeath",), + 0x80B62B10:("EnBigPo_BurnAwayDeath",), + 0x80B62E38:("EnBigPo_SetupLanternDrop",), + 0x80B62F10:("EnBigPo_LanternFalling",), + 0x80B62FCC:("EnBigPo_AdjustPoAlpha",), + 0x80B631F8:("EnBigPo_SpawnScoopSoul",), + 0x80B63264:("EnBigPo_ScoopSoulAppearing",), + 0x80B632BC:("EnBigPo_SetupScoopSoulIdle",), + 0x80B6330C:("EnBigPo_ScoopSoulIdle",), + 0x80B633E8:("EnBigPo_ScoopSoulStartLeaving",), + 0x80B63410:("EnBigPo_ScoopSoulFadingAway",), 0x80B63450:("func_80B63450",), - 0x80B63474:("func_80B63474",), - 0x80B636D0:("func_80B636D0",), - 0x80B636E4:("func_80B636E4",), + 0x80B63474:("EnBigPo_SelectRandomFireLocations",), + 0x80B636D0:("EnBigPo_ChangeToFireCounting",), + 0x80B636E4:("EnBigPo_FireCounting",), 0x80B63758:("func_80B63758",), - 0x80B6382C:("func_80B6382C",), - 0x80B6383C:("func_80B6383C",), - 0x80B63854:("func_80B63854",), - 0x80B63888:("func_80B63888",), + 0x80B6382C:("EnBigpo_DoNothing",), + 0x80B6383C:("EnBigPo_InitHiddenFire",), + 0x80B63854:("EnBigPo_WaitingForDampe",), + 0x80B63888:("EnBigpo_Die",), 0x80B638AC:("func_80B638AC",), 0x80B638D4:("func_80B638D4",), 0x80B63964:("func_80B63964",), @@ -14224,11 +14224,11 @@ 0x80B63D0C:("func_80B63D0C",), 0x80B63D88:("func_80B63D88",), 0x80B63ED4:("EnBigpo_Update",), - 0x80B64190:("func_80B64190",), - 0x80B641E8:("func_80B641E8",), - 0x80B64240:("func_80B64240",), + 0x80B64190:("EnBigPo_UpdateFire",), + 0x80B641E8:("EnBigPo_OverrideLimbDraw2",), + 0x80B64240:("EnBigPo_PostLimbDraw2",), 0x80B64470:("func_80B64470",), - 0x80B6467C:("func_80B6467C",), + 0x80B6467C:("EnBigPo_DrawScoopSoul",), 0x80B64880:("func_80B64880",), 0x80B64B08:("func_80B64B08",), 0x80B64DFC:("func_80B64DFC",),