summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTharo <17233964+Thar0@users.noreply.github.com>2020-12-05 00:34:27 +0000
committerGitHub <noreply@github.com>2020-12-04 19:34:27 -0500
commitf85a2d10ee92861c91243dab8366ad4e81fa5979 (patch)
treed71d5a5e80f3834a87f7ca99a76737b8b9ad6701 /src
parente983d2b72b2ed4885d8f4b3c354469af06cb4665 (diff)
Poe Actor Decomps (#463)
* Poe actors progress * Some more progress, En_Poh almost matching * Further progress * Fix merge * Decompile data * Actor struct cleanups * More functions OK * Progress * Last function decompiled, some nonmatchings left * Few more OK, skelanime_init definition changes * Progress * Style improvements, OPEN/CLOSE_DISPS, few more OK * Few more style improvements, function prototype additions/changes, another function OK * Remove unused asm, begin documentation * Use generated reloc * Cleanup, format * Remove a few no longer needed comments * PR suggestions * DISP macros * Missed some FrameUpdateMatrix != 0 replacements * EnPoField_InteractWithSoul -> EnPoField_SoulInteract, eyeImageIdx -> eyeTextureIdx * Fix merge, reformat * Review Suggestions Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * Further review suggestions * Ran formatter * Less DECR usage Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/code/z_skelanime.c4
-rw-r--r--src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c4
-rw-r--r--src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c239
-rw-r--r--src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h17
-rw-r--r--src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c1003
-rw-r--r--src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h34
-rw-r--r--src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c388
-rw-r--r--src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h18
-rw-r--r--src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c1454
-rw-r--r--src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h22
-rw-r--r--src/overlays/actors/ovl_En_Poh/z_en_poh.c1133
-rw-r--r--src/overlays/actors/ovl_En_Poh/z_en_poh.h50
-rw-r--r--src/overlays/actors/ovl_En_Tk/z_en_tk.c8
-rw-r--r--src/overlays/actors/ovl_En_Tk/z_en_tk.h2
-rw-r--r--src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c4
15 files changed, 4093 insertions, 287 deletions
diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c
index 61ab1fdf6..e57b770dd 100644
--- a/src/code/z_skelanime.c
+++ b/src/code/z_skelanime.c
@@ -1300,8 +1300,8 @@ s32 SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeade
}
}
-void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg,
- AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) {
+s32 SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg,
+ AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) {
FlexSkeletonHeader* skeletonHeader = SEGMENTED_TO_VIRTUAL(skeletonHeaderSeg);
skelAnime->limbCount = skeletonHeader->sh.limbCount + 1;
diff --git a/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c b/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c
index cb44f5194..7599e1764 100644
--- a/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c
+++ b/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c
@@ -50,7 +50,7 @@ static InitChainEntry sInitChain[] = {
extern UNK_TYPE D_060108B8;
extern Gfx D_0600FE40[];
-extern UNK_TYPE D_0400CD80;
+extern Gfx D_0400CD80[];
extern Gfx D_040184B0[];
void BgHakaTubo_Init(Actor* thisx, GlobalContext* globalCtx) {
@@ -105,7 +105,7 @@ void BgHakaTubo_Idle(BgHakaTubo* this, GlobalContext* globalCtx) {
pos.y = this->dyna.actor.posRot.pos.y + 80.0f;
EffectSsBomb2_SpawnLayered(globalCtx, &pos, &sZeroVector, &sZeroVector, 100, 45);
Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.posRot.pos, 50, NA_SE_EV_BOX_BREAK);
- EffectSsHahen_SpawnBurst(globalCtx, &pos, 20.0f, 0, 350, 100, 50, OBJECT_HAKA_OBJECTS, 40, &D_0400CD80);
+ EffectSsHahen_SpawnBurst(globalCtx, &pos, 20.0f, 0, 350, 100, 50, OBJECT_HAKA_OBJECTS, 40, D_0400CD80);
this->dropTimer = 5;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.0f);
diff --git a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
index 9fafb9a3f..e5b9213df 100644
--- a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
+++ b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
@@ -15,7 +15,11 @@ void EnPoDesert_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPoDesert_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPoDesert_Draw(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnPoDesert_SetNextPathPoint(EnPoDesert* this, GlobalContext* globalCtx);
+void EnPoDesert_WaitForPlayer(EnPoDesert* this, GlobalContext* globalCtx);
+void EnPoDesert_MoveToNextPoint(EnPoDesert* this, GlobalContext* globalCtx);
+void EnPoDesert_Disappear(EnPoDesert* this, GlobalContext* globalCtx);
+
const ActorInit En_Po_Desert_InitVars = {
ACTOR_EN_PO_DESERT,
ACTORTYPE_BG,
@@ -27,29 +31,234 @@ const ActorInit En_Po_Desert_InitVars = {
(ActorFunc)EnPoDesert_Update,
(ActorFunc)EnPoDesert_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Destroy.s")
+static ColliderCylinderInit sColliderInit = {
+ { COLTYPE_UNK3, 0x00, 0x00, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
+ { 25, 50, 20, { 0, 0, 0 } },
+};
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_S8(naviEnemyId, 0x5C, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
+ ICHAIN_F32(unk_4C, 3200, ICHAIN_STOP),
+};
+
+extern SkeletonHeader D_06006A30;
+extern AnimationHeader D_06000924;
+extern AnimationHeader D_06001360;
+
+extern Gfx D_06004BA0[];
+extern Gfx D_06004CC0[];
+
+void EnPoDesert_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnPoDesert* this = THIS;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &D_06006A30, &D_06000924, this->limbDrawTable,
+ this->transitionDrawTable, 10);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sColliderInit);
+ this->lightColor.r = 255;
+ this->lightColor.g = 255;
+ this->lightColor.b = 210;
+ this->lightColor.a = 255;
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
+ this->actor.initPosRot.pos.z, 255, 255, 255, 200);
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 37.0f);
+ this->currentPathPoint = 1;
+ this->actor.params = (this->actor.params >> 8) & 0xFF;
+ this->targetY = this->actor.posRot.pos.y;
+ EnPoDesert_SetNextPathPoint(this, globalCtx);
+}
+
+void EnPoDesert_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoDesert* this = THIS;
+
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
+
+void EnPoDesert_SetNextPathPoint(EnPoDesert* this, GlobalContext* globalCtx) {
+ Path* path = &globalCtx->setupPathList[this->actor.params];
+ Vec3s* pathPoint;
+
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06001360, -6.0f);
+ pathPoint = &((Vec3s*)SEGMENTED_TO_VIRTUAL(path->points))[this->currentPathPoint];
+ this->actor.initPosRot.pos.x = pathPoint->x;
+ this->actor.initPosRot.pos.y = pathPoint->y;
+ this->actor.initPosRot.pos.z = pathPoint->z;
+ this->initDistToNextPoint = func_8002DBB0(&this->actor, &this->actor.initPosRot.pos);
+ this->initDistToNextPoint = CLAMP_MIN(this->initDistToNextPoint, 1.0f);
+ this->currentPathPoint++;
+ this->yDiff = this->actor.initPosRot.pos.y - this->actor.posRot.pos.y;
+ this->actor.speedXZ = 0.0f;
+ if (path->count == this->currentPathPoint) {
+ this->currentPathPoint = 0;
+ }
+ this->actionFunc = EnPoDesert_WaitForPlayer;
+}
+
+void EnPoDesert_SetupMoveToNextPoint(EnPoDesert* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000924, -5.0f);
+ this->actionFunc = EnPoDesert_MoveToNextPoint;
+}
+
+void EnPoDesert_SetupDisappear(EnPoDesert* this) {
+ SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06001360, -6.0f);
+ this->actionTimer = 16;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR);
+ this->actionFunc = EnPoDesert_Disappear;
+}
+
+void EnPoDesert_UpdateSpeedModifier(EnPoDesert* this) {
+ if (this->speedModifier == 0) {
+ this->speedModifier = 32;
+ }
+ if (this->speedModifier != 0) {
+ this->speedModifier--;
+ }
+ this->actor.posRot.pos.y = Math_Sins(this->speedModifier * 0x800) * 13.0f + this->targetY;
+}
+
+void EnPoDesert_WaitForPlayer(EnPoDesert* this, GlobalContext* globalCtx) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ if (this->actor.xzDistFromLink < 200.0f && (this->currentPathPoint != 2 || globalCtx->actorCtx.unk_03)) {
+ if (this->currentPathPoint == 2) {
+ if (Gameplay_InCsMode(globalCtx)) {
+ this->actor.shape.rot.y += 0x800;
+ return;
+ }
+ func_8010B680(globalCtx, 0x600B, NULL);
+ }
+ EnPoDesert_SetupMoveToNextPoint(this);
+ } else {
+ this->actor.shape.rot.y += 0x800;
+ }
+}
+
+void EnPoDesert_MoveToNextPoint(EnPoDesert* this, GlobalContext* globalCtx) {
+ f32 temp_f20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2E64.s")
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ temp_f20 = sinf(this->actionTimer * (M_PI / 20.0f)) * 5.0f;
+ this->actor.posRot.pos.x += temp_f20 * Math_Coss(this->actor.shape.rot.y);
+ this->actor.posRot.pos.z += temp_f20 * Math_Sins(this->actor.shape.rot.y);
+ if (this->actionTimer == 0) {
+ this->actionTimer = 40;
+ }
+ temp_f20 = func_8002DBB0(&this->actor, &this->actor.initPosRot.pos);
+ this->actor.posRot.rot.y = func_8002DAC0(&this->actor, &this->actor.initPosRot.pos);
+ Math_SmoothScaleMaxS(&this->actor.shape.rot.y, this->actor.posRot.rot.y + 0x8000, 5, 0x400);
+ this->actor.speedXZ = sinf(this->speedModifier * (M_PI / 32.0f)) * 2.5f + 5.5f;
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ this->targetY = this->actor.initPosRot.pos.y - ((temp_f20 * this->yDiff) / this->initDistToNextPoint);
+ if (temp_f20 < 40.0f) {
+ if (this->currentPathPoint != 0) {
+ EnPoDesert_SetNextPathPoint(this, globalCtx);
+ } else {
+ EnPoDesert_SetupDisappear(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2FBC.s")
+void EnPoDesert_Disappear(EnPoDesert* this, GlobalContext* globalCtx) {
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ this->actor.shape.rot.y += 0x2000;
+ this->lightColor.a = this->actionTimer * 15.9375f;
+ this->actor.shape.unk_14 = this->lightColor.a;
+ if (this->actionTimer == 0) {
+ Actor_Kill(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2FFC.s")
+void EnPoDesert_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoDesert* this = THIS;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD305C.s")
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ this->actionFunc(this, globalCtx);
+ Actor_MoveForward(&this->actor);
+ EnPoDesert_UpdateSpeedModifier(this);
+ func_8002E4B4(globalCtx, &this->actor, 0.0f, 27.0f, 60.0f, 4);
+ Actor_SetHeight(&this->actor, 42.0f);
+ Collider_CylinderUpdate(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ if (globalCtx->actorCtx.unk_03) {
+ this->actor.flags |= 0x81;
+ this->actor.shape.shadowDrawFunc = ActorShadow_DrawFunc_Circle;
+ } else {
+ this->actor.shape.shadowDrawFunc = NULL;
+ this->actor.flags &= ~0x81;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD30D0.s")
+s32 EnPoDesert_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ void* thisx, Gfx** gfxP) {
+ EnPoDesert* this = THIS;
+ f32 mtxScale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3194.s")
+ if (this->actionFunc == EnPoDesert_Disappear && limbIndex == 7) {
+ mtxScale = this->actionTimer * 0.0625f;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ }
+ if ((this->actor.flags & 0x80) != 0x80) {
+ *dList = NULL;
+ }
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3328.s")
+void EnPoDesert_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx,
+ Gfx** gfxP) {
+ static Vec3f baseLightPos = { 0.0f, 1400.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Update.s")
+ EnPoDesert* this = THIS;
+ f32 rand;
+ Color_RGBA8 color;
+ Vec3f lightPos;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3504.s")
+ if (limbIndex == 7) {
+ Matrix_MultVec3f(&baseLightPos, &lightPos);
+ rand = Math_Rand_ZeroOne();
+ color.r = (s16)(rand * 30.0f) + 225;
+ color.g = (s16)(rand * 100.0f) + 155;
+ color.b = (s16)(rand * 160.0f) + 95;
+ if ((this->actor.flags & 0x80) == 0x80) {
+ gDPPipeSync((*gfxP)++);
+ gDPSetEnvColor((*gfxP)++, color.r, color.g, color.b, 255);
+ gSPMatrix((*gfxP)++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_desert.c", 523),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList((*gfxP)++, D_06004BA0);
+ gSPDisplayList((*gfxP)++, D_06004CC0);
+ gDPPipeSync((*gfxP)++);
+ gDPSetEnvColor((*gfxP)++, this->lightColor.r, this->lightColor.g, this->lightColor.b, this->lightColor.a);
+ }
+ Lights_PointNoGlowSetInfo(&this->lightInfo, lightPos.x, lightPos.y, lightPos.z, color.r, color.g, color.b, 200);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3594.s")
+void EnPoDesert_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoDesert* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Draw.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_desert.c", 559);
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x0A, Gfx_EnvColor(globalCtx->state.gfxCtx, 255, 85, 0, 255));
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
+ this->lightColor.a));
+ if (this->actionFunc == EnPoDesert_Disappear) {
+ gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280);
+ } else {
+ gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280 + 2);
+ }
+ POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoDesert_OverrideLimbDraw, EnPoDesert_PostLimbDraw, &this->actor, POLY_XLU_DISP);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_desert.c", 597);
+}
diff --git a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
index 260ff4eac..f338aaa4a 100644
--- a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
+++ b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
@@ -6,9 +6,24 @@
struct EnPoDesert;
+typedef void (*EnPoDesertActionFunc)(struct EnPoDesert*, GlobalContext*);
+
typedef struct EnPoDesert {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x138];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ EnPoDesertActionFunc actionFunc;
+ /* 0x0194 */ s16 actionTimer;
+ /* 0x0196 */ s16 speedModifier;
+ /* 0x0198 */ s32 currentPathPoint;
+ /* 0x019C */ f32 initDistToNextPoint;
+ /* 0x01A0 */ f32 yDiff;
+ /* 0x01A4 */ f32 targetY;
+ /* 0x01A8 */ Vec3s limbDrawTable[10];
+ /* 0x01E4 */ Vec3s transitionDrawTable[10];
+ /* 0x0220 */ Color_RGBA8 lightColor;
+ /* 0x0224 */ LightNode* lightNode;
+ /* 0x0228 */ LightInfo lightInfo;
+ /* 0x0238 */ ColliderCylinder collider;
} EnPoDesert; // size = 0x0284
extern const ActorInit En_Po_Desert_InitVars;
diff --git a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
index d464ebc2c..1793ad5ff 100644
--- a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
+++ b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
@@ -1,3 +1,9 @@
+/*
+ * File: z_en_po_field.c
+ * Overlay: ovl_En_Po_Field
+ * Description: Field Poe
+ */
+
#include "z_en_po_field.h"
#define FLAGS 0x00001035
@@ -9,7 +15,24 @@ void EnPoField_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPoField_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPoField_Draw(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnPoField_UpdateDead(Actor* thisx, GlobalContext* globalCtx);
+void EnPoField_DrawSoul(Actor* thisx, GlobalContext* globalCtx);
+
+void EnPoField_SetupWaitForSpawn(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_WaitForSpawn(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_Appear(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_CirclePlayer(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_Damage(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_Flee(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_Death(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_Disappear(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_SoulIdle(EnPoField* this, GlobalContext* globalCtx);
+void func_80AD587C(EnPoField* this, GlobalContext* globalCtx);
+void func_80AD58D4(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_SoulDisappear(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_SoulInteract(EnPoField* this, GlobalContext* globalCtx);
+void EnPoField_SpawnFlame(EnPoField* this);
+
const ActorInit En_Po_Field_InitVars = {
ACTOR_EN_PO_FIELD,
ACTORTYPE_ENEMY,
@@ -21,85 +44,921 @@ const ActorInit En_Po_Field_InitVars = {
(ActorFunc)EnPoField_Update,
(ActorFunc)EnPoField_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Init.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Destroy.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD3D68.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD3E2C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD3F4C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD3FF0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4084.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4140.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4190.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4208.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD42B0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4384.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD443C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD444C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4470.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4554.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4664.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD48CC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4A68.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4CA4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4E48.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4ED8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD52F0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD53F0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD54D4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD587C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD58D4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5AD8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5B18.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5C74.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5D0C.s")
+static ColliderCylinderInit D_80AD7080 = {
+ { COLTYPE_UNK3, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
+ { 25, 50, 20, { 0, 0, 0 } },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5D60.s")
+static ColliderCylinderInit D_80AD70AC = {
+ { COLTYPE_UNK10, 0x11, 0x00, 0x00, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0xFFCFFFFF, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, 0x19, 0x00, 0x00 },
+ { 10, 30, 0, { 0, 0, 0 } },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5E8C.s")
+static CollisionCheckInfoInit D_80AD70D8 = { 0x04, 0x0019, 0x0032, 0x28 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD619C.s")
+static DamageTable sDamageTable = {
+ 0x00, 0x02, 0x01, 0x02, 0x11, 0x02, 0x02, 0x12, 0x01, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x02, 0x08, 0x04, 0x00, 0x00, 0x04, 0x00,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6330.s")
+static s32 sNumSpawned = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Update.s")
+static Vec3f sFieldMiddle = { -1000.0f, 0.0f, 6500.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD65C8.s")
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32(unk_4C, 3200, ICHAIN_STOP),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD66D0.s")
+static Vec3f D_80AD7114 = { 0.0f, 3.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Draw.s")
+static Vec3f D_80AD7120 = { 0.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6BF4.s")
+static EnPoFieldInfo sPoFieldInfo[2] = {
+ { { 255, 170, 255 }, { 100, 0, 150 }, { 255, 85, 0 }, 248, 0x06001B70 },
+ { { 255, 255, 170 }, { 255, 200, 0 }, { 160, 0, 255 }, 241, 0x06001370 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6C4C.s")
+static Vec3f D_80AD714C = { 0.0f, 1400.0f, 0.0f };
+
+static Vec3s sSpawnPositions[10];
+static u8 sSpawnSwitchFlags[10];
+static MtxF sLimb7Mtx;
+
+extern AnimationHeader D_06000924;
+extern SkeletonHeader D_06006A30;
+extern AnimationHeader D_06000F9C;
+extern AnimationHeader D_06000608;
+extern AnimationHeader D_06000454;
+extern AnimationHeader D_06001360;
+extern Gfx D_0404D4E0[];
+extern Gfx D_060059F0[];
+extern Gfx D_06005900[];
+extern Gfx D_06005620[];
+extern Gfx D_060066D0[];
+extern Gfx D_06004BA0[];
+extern Gfx D_06004CC0[];
+extern Gfx D_060023B0[];
+
+void EnPoField_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoField* this = THIS;
+ s32 pad;
+
+ if (sNumSpawned != 10) {
+ sSpawnPositions[sNumSpawned].x = this->actor.posRot.pos.x;
+ sSpawnPositions[sNumSpawned].y = this->actor.posRot.pos.y;
+ sSpawnPositions[sNumSpawned].z = this->actor.posRot.pos.z;
+ sSpawnSwitchFlags[sNumSpawned] = this->actor.params & 0xFF;
+ sNumSpawned++;
+ }
+ if (sNumSpawned >= 2) {
+ this->actor.params = 0xFF;
+ Actor_Kill(&this->actor);
+ return;
+ }
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &D_06006A30, &D_06000924, this->limbDrawTable,
+ this->transitionDrawTable, 10);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &D_80AD7080);
+ Collider_InitCylinder(globalCtx, &this->flameCollider);
+ Collider_SetCylinder(globalCtx, &this->flameCollider, &this->actor, &D_80AD70AC);
+ func_80061ED4(&this->actor.colChkInfo, &sDamageTable, &D_80AD70D8);
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ Lights_PointGlowSetInfo(&this->lightInfo, this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
+ this->actor.initPosRot.pos.z, 255, 255, 255, 0);
+ this->actor.shape.shadowDrawFunc = ActorShadow_DrawFunc_Circle;
+ EnPoField_SetupWaitForSpawn(this, globalCtx);
+}
+
+void EnPoField_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoField* this = THIS;
+
+ if (this->actor.params != 0xFF) {
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ Collider_DestroyCylinder(globalCtx, &this->flameCollider);
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+ }
+}
+
+void EnPoField_SetupWaitForSpawn(EnPoField* this, GlobalContext* globalCtx) {
+ this->actor.update = EnPoField_Update;
+ Actor_ChangeType(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORTYPE_ENEMY);
+ this->actor.shape.rot.x = 0;
+ Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0);
+ this->actionTimer = 200;
+ Actor_SetScale(&this->actor, 0.0f);
+ this->actor.flags &= ~0x00010001;
+ this->collider.base.acFlags &= ~1;
+ this->collider.base.maskA = 0x39;
+ this->actor.colChkInfo.health = D_80AD70D8.health;
+ this->actor.gravity = 0.0f;
+ this->actor.velocity.y = 0.0f;
+ this->actionFunc = EnPoField_WaitForSpawn;
+}
+
+void EnPoField_SetupAppear(EnPoField* this) {
+ SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06000F9C);
+ this->actor.draw = EnPoField_Draw;
+ this->lightColor.r = 255;
+ this->lightColor.g = 255;
+ this->lightColor.b = 210;
+ this->lightColor.a = 0;
+ this->actor.shape.unk_14 = 0;
+ this->actor.shape.unk_08 = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ if (this->actor.params == EN_PO_FIELD_BIG) {
+ this->actor.speedXZ = 12.0f;
+ this->collider.dim.radius = 35;
+ this->collider.dim.height = 100;
+ this->collider.dim.yShift = 10;
+ this->actor.shape.unk_10 = 45.0f;
+ this->scaleModifier = 0.014f;
+ this->actor.naviEnemyId = 0x5A;
+ } else {
+ this->actor.speedXZ = 0.0f;
+ this->collider.dim.radius = D_80AD7080.dim.radius;
+ this->collider.dim.height = D_80AD7080.dim.height;
+ this->collider.dim.yShift = D_80AD7080.dim.yShift;
+ this->actor.shape.unk_10 = 37.0f;
+ this->scaleModifier = 0.01f;
+ this->actor.naviEnemyId = 0x5C;
+ }
+ this->actionFunc = EnPoField_Appear;
+}
+
+void EnPoField_SetupCirclePlayer(EnPoField* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06000924);
+ this->collider.base.acFlags |= 1;
+ this->scaleModifier = this->actor.xzDistFromLink;
+ Math_Vec3f_Copy(&this->actor.initPosRot.pos, &player->actor.posRot.pos);
+ this->actor.posRot.rot.y = this->actor.yawTowardsLink;
+ if (this->actionFunc != EnPoField_Damage) {
+ this->actor.flags |= 1;
+ this->actionTimer = 600;
+ this->unk_194 = 32;
+ }
+ this->actionFunc = EnPoField_CirclePlayer;
+}
+
+void EnPoField_SetupFlee(EnPoField* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000608, -5.0f);
+ this->collider.base.acFlags |= 1;
+ this->actionFunc = EnPoField_Flee;
+ this->actor.speedXZ = 12.0f;
+ if (this->actionFunc != EnPoField_Damage) {
+ this->actor.flags |= 1;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y + 0x8000;
+ this->actionTimer = 2000;
+ this->unk_194 = 32;
+ }
+}
+
+void EnPoField_SetupDamage(EnPoField* this) {
+ SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06000454, -6.0f);
+ if (this->collider.body.acHitItem->toucher.flags & 0x1F824) {
+ this->actor.posRot.rot.y = this->collider.base.ac->posRot.rot.y;
+ } else {
+ this->actor.posRot.rot.y = func_8002DA78(&this->actor, this->collider.base.ac) + 0x8000;
+ }
+ this->collider.base.acFlags &= ~3;
+ this->actor.speedXZ = 5.0f;
+ func_8003426C(&this->actor, 0x4000, 255, 0, 16);
+ this->actionFunc = EnPoField_Damage;
+}
+
+void EnPoField_SetupDeath(EnPoField* this) {
+ this->actionTimer = 0;
+ this->actor.flags &= -2;
+ this->actor.speedXZ = 0.0f;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ this->actor.naviEnemyId = 0xFF;
+ if (this->flameTimer >= 20) {
+ this->flameTimer = 19;
+ }
+ this->actionFunc = EnPoField_Death;
+}
+
+void EnPoField_SetupDisappear(EnPoField* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06001360, -6.0f);
+ this->actionTimer = 16;
+ this->collider.base.acFlags &= ~3;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR);
+ this->actionFunc = EnPoField_Disappear;
+}
+
+void EnPoField_SetupSoulIdle(EnPoField* this, GlobalContext* globalCtx) {
+ this->actor.update = EnPoField_UpdateDead;
+ this->actor.draw = EnPoField_DrawSoul;
+ this->actor.shape.shadowDrawFunc = NULL;
+ Actor_SetScale(&this->actor, 0.01f);
+ this->actor.gravity = -1.0f;
+ this->actor.shape.unk_08 = 1500.0f;
+ this->actor.shape.rot.x = -0x8000;
+ this->actionTimer = 60;
+ this->actor.posRot.pos.y -= 15.0f;
+ Actor_ChangeType(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORTYPE_MISC);
+ this->actionFunc = EnPoField_SoulIdle;
+}
+
+void func_80AD42B0(EnPoField* this) {
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, 0, 0, 0, 0);
+ this->actor.shape.rot.y = 0;
+ this->lightColor.a = 0;
+ this->actor.shape.rot.x = 0;
+ this->actor.shape.unk_08 = 0.0f;
+ this->actor.gravity = 0.0f;
+ this->actor.velocity.y = 0.0f;
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ this->actor.scale.x = 0.0f;
+ this->actor.scale.y = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND);
+ if (this->actor.params == EN_PO_FIELD_BIG) {
+ func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
+ }
+ this->actionFunc = func_80AD587C;
+}
+
+void func_80AD4384(EnPoField* this) {
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ Actor_SetHeight(&this->actor, -10.0f);
+ this->collider.dim.radius = 13;
+ this->collider.dim.height = 30;
+ this->collider.dim.yShift = 0;
+ this->collider.dim.pos.x = this->actor.posRot.pos.x;
+ this->collider.dim.pos.y = this->actor.posRot.pos.y - 20.0f;
+ this->collider.dim.pos.z = this->actor.posRot.pos.z;
+ this->collider.base.maskA = 9;
+ this->actor.textId = 0x5005;
+ this->actionTimer = 400;
+ this->unk_194 = 32;
+ this->actor.flags |= 1;
+ this->actionFunc = func_80AD58D4;
+}
+
+void EnPoField_SetupSoulDisappear(EnPoField* this) {
+ this->actionFunc = EnPoField_SoulDisappear;
+}
+
+void EnPoField_SetupInteractWithSoul(EnPoField* this) {
+ this->actionFunc = EnPoField_SoulInteract;
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y - 15.0f;
+}
+
+void EnPoField_CorrectYPos(EnPoField* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+
+ if (this->unk_194 == 0) {
+ this->unk_194 = 32;
+ }
+ if (this->unk_194 != 0) {
+ this->unk_194 -= 1;
+ }
+ if (this->actor.groundY == -32000.0f) {
+ EnPoField_SetupDisappear(this);
+ return;
+ }
+ Math_SmoothScaleMaxF(
+ &this->actor.initPosRot.pos.y,
+ ((player->actor.posRot.pos.y > this->actor.groundY) ? player->actor.posRot.pos.y : this->actor.groundY) + 13.0f,
+ 0.2f, 5.0f);
+ this->actor.posRot.pos.y = Math_Sins(this->unk_194 * 0x800) * 13.0f + this->actor.initPosRot.pos.y;
+}
+
+f32 EnPoField_SetFleeSpeed(EnPoField* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ f32 speed = ((player->stateFlags1 & 0x800000) && player->rideActor != NULL) ? player->rideActor->speedXZ : 12.0f;
+
+ if (this->actor.xzDistFromLink < 300.0f) {
+ this->actor.speedXZ = speed * 1.5f + 2.0f;
+ } else if (this->actor.xzDistFromLink < 400.0f) {
+ this->actor.speedXZ = speed * 1.25f + 2.0f;
+ } else if (this->actor.xzDistFromLink < 500.0f) {
+ this->actor.speedXZ = speed + 2.0f;
+ } else {
+ this->actor.speedXZ = 12.0f;
+ }
+ this->actor.speedXZ = CLAMP_MIN(this->actor.speedXZ, 12.0f);
+}
+
+void EnPoField_WaitForSpawn(EnPoField* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ f32 spawnDist;
+ s32 i;
+ UNK_TYPE sp88;
+
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (this->actionTimer == 0) {
+ for (i = 0; i < sNumSpawned; i++) {
+ if (fabsf(sSpawnPositions[i].x - player->actor.posRot.pos.x) < 150.0f &&
+ fabsf(sSpawnPositions[i].z - player->actor.posRot.pos.z) < 150.0f) {
+ if (Flags_GetSwitch(globalCtx, sSpawnSwitchFlags[i])) {
+ if (player->stateFlags1 & 0x800000) { // Player riding Epona
+ return;
+ } else {
+ this->actor.params = EN_PO_FIELD_SMALL;
+ spawnDist = 300.0f;
+ }
+ } else if (player->stateFlags1 & 0x800000 || Math_Rand_ZeroOne() < 0.4f) {
+ this->actor.params = EN_PO_FIELD_BIG;
+ this->spawnFlagIndex = i;
+ spawnDist = 480.0f;
+ } else {
+ this->actor.params = EN_PO_FIELD_SMALL;
+ spawnDist = 300.0f;
+ }
+ this->actor.posRot.pos.x =
+ Math_Sins(player->actor.shape.rot.y) * spawnDist + player->actor.posRot.pos.x;
+ this->actor.posRot.pos.z =
+ Math_Coss(player->actor.shape.rot.y) * spawnDist + player->actor.posRot.pos.z;
+ this->actor.posRot.pos.y = player->actor.posRot.pos.y + 1000.0f;
+ this->actor.posRot.pos.y = func_8003C9A4(&globalCtx->colCtx, &this->actor.floorPoly, &sp88,
+ &this->actor, &this->actor.posRot.pos);
+ if (this->actor.posRot.pos.y != -32000.0f) {
+ this->actor.shape.rot.y = func_8002DA78(&this->actor, &player->actor);
+ EnPoField_SetupAppear(this);
+ } else {
+ return;
+ }
+ }
+ }
+ }
+}
+
+void EnPoField_Appear(EnPoField* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->lightColor.a = 255;
+ Actor_SetScale(&this->actor, this->scaleModifier);
+ if (this->actor.params == EN_PO_FIELD_BIG) {
+ EnPoField_SetupFlee(this);
+ } else {
+ EnPoField_SetupCirclePlayer(this, globalCtx);
+ }
+ } else if (this->skelAnime.animCurrentFrame > 10.0f) {
+ this->lightColor.a = ((this->skelAnime.animCurrentFrame - 10.0f) * 0.05f) * 255.0f;
+ } else {
+ this->actor.scale.x += this->scaleModifier * 0.1f;
+ this->actor.scale.y = this->actor.scale.x;
+ this->actor.scale.z = this->actor.scale.x;
+ }
+ this->actor.shape.unk_14 = this->lightColor.a;
+ this->actor.shape.rot.y = this->actor.yawTowardsLink;
+ if (this->actor.params == EN_PO_FIELD_BIG) {
+ this->actor.posRot.rot.y = this->actor.yawTowardsLink + 0x8000;
+ EnPoField_SetFleeSpeed(this, globalCtx);
+ }
+}
+
+void EnPoField_CirclePlayer(EnPoField* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ s32 temp_v1 = 16 - this->unk_194;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (ABS(temp_v1) < 16) {
+ this->actor.posRot.rot.y += 512.0f * fabsf(Math_Sins(this->unk_194 * 0x800));
+ }
+ Math_SmoothScaleMaxF(&this->scaleModifier, 180.0f, 0.5f, 10.0f);
+ Math_SmoothScaleMaxF(&this->actor.initPosRot.pos.x, player->actor.posRot.pos.x, 0.2f, 6.0f);
+ Math_SmoothScaleMaxF(&this->actor.initPosRot.pos.z, player->actor.posRot.pos.z, 0.2f, 6.0f);
+ Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->actor.posRot.rot.y, 1, 0x800, 0x200);
+ if (this->actor.initPosRot.pos.x - player->actor.posRot.pos.x > 100.0f) {
+ this->actor.initPosRot.pos.x = player->actor.posRot.pos.x + 100.0f;
+ } else if (this->actor.initPosRot.pos.x - player->actor.posRot.pos.x < -100.0f) {
+ this->actor.initPosRot.pos.x = player->actor.posRot.pos.x + -100.0f;
+ }
+ if (this->actor.initPosRot.pos.z - player->actor.posRot.pos.z > 100.0f) {
+ this->actor.initPosRot.pos.z = player->actor.posRot.pos.z + 100.0f;
+ } else if (this->actor.initPosRot.pos.z - player->actor.posRot.pos.z < -100.0f) {
+ this->actor.initPosRot.pos.z = player->actor.posRot.pos.z + -100.0f;
+ }
+ this->actor.posRot.pos.x =
+ this->actor.initPosRot.pos.x - (Math_Sins(this->actor.posRot.rot.y) * this->scaleModifier);
+ this->actor.posRot.pos.z =
+ this->actor.initPosRot.pos.z - (Math_Coss(this->actor.posRot.rot.y) * this->scaleModifier);
+ if (this->actionTimer == 0) {
+ EnPoField_SetupDisappear(this);
+ } else {
+ EnPoField_SpawnFlame(this);
+ }
+ EnPoField_CorrectYPos(this, globalCtx);
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+}
+
+void EnPoField_Flee(EnPoField* this, GlobalContext* globalCtx) {
+ f32 temp_f6;
+ s16 phi_t0;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (func_8002DBB0(&this->actor, &sFieldMiddle) > 3000.0f) {
+ phi_t0 = (s16)(this->actor.yawTowardsLink - func_8002DAC0(&this->actor, &sFieldMiddle) - 0x8000) * 0.2f;
+ } else {
+ phi_t0 = 0;
+ }
+ Math_SmoothScaleMaxS(&this->actor.shape.rot.y, this->actor.yawTowardsLink - phi_t0, 6, 0x400);
+ EnPoField_SetFleeSpeed(this, globalCtx);
+ this->actor.posRot.rot.y = this->actor.shape.rot.y + 0x8000;
+ temp_f6 = Math_Sins(this->actionTimer * 0x800) * 3.0f;
+ this->actor.posRot.pos.x -= temp_f6 * Math_Coss(this->actor.shape.rot.y);
+ this->actor.posRot.pos.z += temp_f6 * Math_Sins(this->actor.shape.rot.y);
+ if (this->actionTimer == 0 || this->actor.xzDistFromLink > 1500.0f) {
+ EnPoField_SetupDisappear(this);
+ } else {
+ EnPoField_CorrectYPos(this, globalCtx);
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG);
+}
+
+void EnPoField_Damage(EnPoField* this, GlobalContext* globalCtx) {
+ Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.5f);
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ if (this->actor.colChkInfo.health == 0) {
+ EnPoField_SetupDeath(this);
+ } else if (this->actor.params == EN_PO_FIELD_BIG) {
+ EnPoField_SetupFlee(this);
+ } else {
+ EnPoField_SetupCirclePlayer(this, globalCtx);
+ }
+ }
+}
+
+void EnPoField_Death(EnPoField* this, GlobalContext* globalCtx) {
+ Vec3f sp6C;
+ f32 sp68;
+ s32 pad;
+ s32 pad1;
+ f32 temp_f0;
+
+ this->actionTimer++;
+ if (this->actionTimer < 8) {
+ if (this->actionTimer < 5) {
+ sp6C.y = Math_Sins(this->actionTimer * 0x1000 - 0x4000) * 23.0f + (this->actor.posRot.pos.y + 40.0f);
+ sp68 = Math_Coss(this->actionTimer * 0x1000 - 0x4000) * 23.0f;
+ sp6C.x = Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * sp68 + this->actor.posRot.pos.x;
+ sp6C.z = Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * sp68 + this->actor.posRot.pos.z;
+ } else {
+ sp6C.y = this->actor.posRot.pos.y + 40.0f + 15.0f * (this->actionTimer - 5);
+ sp6C.x = Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f + this->actor.posRot.pos.x;
+ sp6C.z = Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f + this->actor.posRot.pos.z;
+ }
+ EffectSsDeadDb_Spawn(globalCtx, &sp6C, &D_80AD7114, &D_80AD7120, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, 1);
+ sp6C.x = (this->actor.posRot.pos.x + this->actor.posRot.pos.x) - sp6C.x;
+ sp6C.z = (this->actor.posRot.pos.z + this->actor.posRot.pos.z) - sp6C.z;
+ EffectSsDeadDb_Spawn(globalCtx, &sp6C, &D_80AD7114, &D_80AD7120, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, 1);
+ sp6C.x = this->actor.posRot.pos.x;
+ sp6C.z = this->actor.posRot.pos.z;
+ EffectSsDeadDb_Spawn(globalCtx, &sp6C, &D_80AD7114, &D_80AD7120, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, 1);
+ if (this->actionTimer == 1) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_EXTINCT);
+ }
+ } else if (this->actionTimer == 28) {
+ EnPoField_SetupSoulIdle(this, globalCtx);
+ } else if (this->actionTimer >= 19) {
+ temp_f0 = (28 - this->actionTimer) * 0.001f;
+ this->actor.posRot.pos.y += 5.0f;
+ this->actor.scale.z = temp_f0;
+ this->actor.scale.y = temp_f0;
+ this->actor.scale.x = temp_f0;
+ }
+ if (this->actionTimer == 18) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD2);
+ }
+}
+
+void EnPoField_Disappear(EnPoField* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ this->actor.shape.rot.y += 0x1000;
+ this->lightColor.a = this->actionTimer * 15.9375f;
+ this->actor.shape.unk_14 = this->lightColor.a;
+ if (this->actionTimer == 0) {
+ EnPoField_SetupWaitForSpawn(this, globalCtx);
+ }
+}
+
+void EnPoField_SoulIdle(EnPoField* this, GlobalContext* globalCtx) {
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (this->actor.bgCheckFlags & 1) {
+ EffectSsHahen_SpawnBurst(globalCtx, &this->actor.posRot.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO_FIELD, 10,
+ D_06004BA0);
+ func_80AD42B0(this);
+ } else if (this->actionTimer == 0) {
+ EnPoField_SetupWaitForSpawn(this, globalCtx);
+ }
+ Actor_MoveForward(&this->actor);
+ func_8002E4B4(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 4);
+}
+
+void EnPoField_SoulUpdateProperties(EnPoField* this, s32 arg1) {
+ EnPoFieldInfo* info = &sPoFieldInfo[this->actor.params];
+ f32 multiplier;
+
+ this->lightColor.a = CLAMP(this->lightColor.a + arg1, 0, 255);
+ if (arg1 < 0) {
+ multiplier = this->lightColor.a * 0.003921569f;
+ this->actor.scale.z = 0.0056000003f * multiplier + 0.00140000007f;
+ this->actor.scale.x = 0.0056000003f * multiplier + 0.00140000007f;
+ this->actor.scale.y = 0.007f - 0.007f * multiplier + 0.007f;
+ } else {
+ multiplier = 1.0f;
+ this->actor.scale.z = this->lightColor.a * 2.7450982e-05f;
+ this->actor.scale.y = this->lightColor.a * 2.7450982e-05f;
+ this->actor.scale.x = this->lightColor.a * 2.7450982e-05f;
+ this->actor.posRot.pos.y = this->actor.initPosRot.pos.y + (0.05882353f * this->lightColor.a);
+ }
+ this->lightColor.r = info->lightColor.r * multiplier;
+ this->lightColor.g = info->lightColor.g * multiplier;
+ this->lightColor.b = info->lightColor.b * multiplier;
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, info->lightColor.r, info->lightColor.g, info->lightColor.b,
+ this->lightColor.a * 0.78431373f);
+}
+
+void func_80AD587C(EnPoField* this, GlobalContext* globalCtx) {
+ this->actor.initPosRot.pos.y += 2.0f;
+ EnPoField_SoulUpdateProperties(this, 20);
+ if (this->lightColor.a == 255) {
+ func_80AD4384(this);
+ }
+}
+
+void func_80AD58D4(EnPoField* this, GlobalContext* globalCtx) {
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (func_8002F194(&this->actor, globalCtx) != 0) {
+ EnPoField_SetupInteractWithSoul(this);
+ return;
+ }
+ if (this->actionTimer == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actor.flags &= ~0x10000;
+ EnPoField_SetupSoulDisappear(this);
+ return;
+ }
+ if (this->collider.base.maskA & 2) {
+ this->actor.flags |= 0x10000;
+ func_8002F2F4(&this->actor, globalCtx);
+ } else {
+ this->actor.flags &= ~0x10000;
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ this->actor.posRot.pos.y = Math_Sins(this->unk_194 * 0x800) * 5.0f + this->actor.initPosRot.pos.y;
+ if (this->unk_194 != 0) {
+ this->unk_194 -= 1;
+ }
+ if (this->unk_194 == 0) {
+ this->unk_194 = 32;
+ }
+ this->collider.dim.pos.y = this->actor.posRot.pos.y - 20.0f;
+ Actor_SetHeight(&this->actor, -10.0f);
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, this->lightInfo.params.point.color[0],
+ this->lightInfo.params.point.color[1], this->lightInfo.params.point.color[2],
+ this->lightColor.a * 0.78431374f);
+}
+
+void EnPoField_SoulDisappear(EnPoField* this, GlobalContext* globalCtx) {
+ EnPoField_SoulUpdateProperties(this, -13);
+ if (this->lightColor.a == 0) {
+ EnPoField_SetupWaitForSpawn(this, globalCtx);
+ }
+}
+
+void EnPoField_SoulInteract(EnPoField* this, GlobalContext* globalCtx) {
+ if (this->actor.textId != 0x5005) {
+ EnPoField_SoulUpdateProperties(this, -13);
+ } else {
+ func_8002F974(&this->actor, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ }
+ if (func_8010BDBC(&globalCtx->msgCtx) == 4) {
+ if (func_80106BC8(globalCtx) != 0) {
+ func_800F8A44(&this->actor.projectedPos, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ if (Inventory_HasEmptyBottle()) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_BIG_GET);
+ if (this->actor.params == 0) {
+ Item_Give(globalCtx, ITEM_POE);
+ this->actor.textId = 0x5008;
+ } else {
+ this->actor.textId = 0x508F;
+ Item_Give(globalCtx, ITEM_BIG_POE);
+ Flags_SetSwitch(globalCtx, sSpawnSwitchFlags[this->spawnFlagIndex]);
+ }
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actor.textId = 0x5006;
+ }
+ } else {
+ this->actor.textId = 0x5007;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ }
+ func_8010B720(globalCtx, this->actor.textId);
+ return;
+ }
+ } else if (func_8002F334(&this->actor, globalCtx) != 0) {
+ EnPoField_SetupSoulDisappear(this);
+ }
+}
+
+void EnPoField_TestForDamage(EnPoField* this, GlobalContext* globalCtx) {
+ if (this->collider.base.acFlags & 2) {
+ this->collider.base.acFlags &= ~2;
+ if (this->actor.colChkInfo.damageEffect != 0 || this->actor.colChkInfo.damage != 0) {
+ if (Actor_ApplyDamage(&this->actor) == 0) {
+ func_80032C7C(globalCtx, &this->actor);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD);
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE);
+ }
+ EnPoField_SetupDamage(this);
+ }
+ }
+}
+
+void EnPoField_SpawnFlame(EnPoField* this) {
+ if (this->flameTimer == 0) {
+ this->flamePosition.x = this->lightInfo.params.point.x;
+ this->flamePosition.y = this->lightInfo.params.point.y;
+ this->flamePosition.z = this->lightInfo.params.point.z;
+ this->flameTimer = 70;
+ this->flameRotation = this->actor.shape.rot.y;
+ }
+}
+
+void EnPoField_UpdateFlame(EnPoField* this, GlobalContext* globalCtx) {
+ if (this->flameTimer != 0) {
+ if (this->flameTimer != 0) {
+ this->flameTimer--;
+ }
+ if (this->flameCollider.base.atFlags & 2) {
+ this->flameCollider.base.atFlags &= ~2;
+ this->flameTimer = 19;
+ }
+ if (this->flameTimer < 20) {
+ Math_ApproxF(&this->flameScale, 0.0f, 0.00015f);
+ return;
+ }
+ if (Math_ApproxF(&this->flameScale, 0.003f, 0.0006f) != 0) {
+ this->flamePosition.x += 2.5f * Math_Sins(this->flameRotation);
+ this->flamePosition.z += 2.5f * Math_Coss(this->flameRotation);
+ }
+ this->flameCollider.dim.pos.x = this->flamePosition.x;
+ this->flameCollider.dim.pos.y = this->flamePosition.y;
+ this->flameCollider.dim.pos.z = this->flamePosition.z;
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->flameCollider.base);
+ }
+}
+
+void EnPoField_DrawFlame(EnPoField* this, GlobalContext* globalCtx) {
+ f32 sp4C;
+ s32 pad;
+
+ if (this->flameTimer != 0) {
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 1669);
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
+ (globalCtx->gameplayFrames * -20) % 512, 32, 128));
+ sp4C = this->flameScale * 85000.0f;
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, sp4C);
+ Matrix_Translate(this->flamePosition.x, this->flamePosition.y, this->flamePosition.z, MTXMODE_NEW);
+ Matrix_RotateY((s16)(func_8005A9F4(ACTIVE_CAM) + 0x8000) * 0.0000958738f, MTXMODE_APPLY);
+ if (this->flameTimer >= 20) {
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
+ Matrix_Scale(this->flameScale, this->flameScale, this->flameScale, MTXMODE_APPLY);
+ } else {
+ gDPSetEnvColor(POLY_XLU_DISP++, sp4C, 0, 0, 0);
+ Matrix_Scale((this->flameScale * 0.7f) + 0.00090000004f, (0.003f - this->flameScale) + 0.003f, 0.003f,
+ MTXMODE_APPLY);
+ }
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_field.c", 1709),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, D_0404D4E0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 1712);
+ }
+}
+
+void func_80AD619C(EnPoField* this) {
+ s16 temp_var;
+
+ if (this->actionFunc == EnPoField_Flee) {
+ this->lightColor.r = CLAMP_MAX((s16)(this->lightColor.r + 5), 80);
+ this->lightColor.g = CLAMP_MAX((s16)(this->lightColor.g + 5), 255);
+ temp_var = this->lightColor.b + 5;
+ this->lightColor.b = CLAMP_MAX(temp_var, 225);
+ } else if (this->actionFunc == EnPoField_Damage) {
+ if (this->actor.dmgEffectTimer & 2) {
+ this->lightColor.r = 0;
+ this->lightColor.g = 0;
+ this->lightColor.b = 0;
+ } else {
+ this->lightColor.r = 80;
+ this->lightColor.g = 255;
+ this->lightColor.b = 225;
+ }
+ } else {
+ this->lightColor.r = CLAMP_MAX((s16)(this->lightColor.r + 5), 255);
+ this->lightColor.g = CLAMP_MAX((s16)(this->lightColor.g + 5), 255);
+ if (this->lightColor.b > 210) {
+ temp_var = this->lightColor.b - 5;
+ this->lightColor.b = CLAMP_MIN(temp_var, 210);
+ } else {
+ temp_var = this->lightColor.b + 5;
+ this->lightColor.b = CLAMP_MAX(temp_var, 210);
+ }
+ }
+}
+
+void func_80AD6330(EnPoField* this) {
+ f32 rand;
+
+ if (this->actionFunc == EnPoField_Appear && this->skelAnime.animCurrentFrame < 12.0f) {
+ this->soulColor.r = this->soulColor.g = this->soulColor.b =
+ (s16)(this->skelAnime.animCurrentFrame * 16.66f) + 55;
+ this->soulColor.a = this->skelAnime.animCurrentFrame * 16.666666f;
+ } else {
+ rand = Math_Rand_ZeroOne();
+ this->soulColor.r = (s16)(rand * 30.0f) + 225;
+ this->soulColor.g = (s16)(rand * 100.0f) + 155;
+ this->soulColor.b = (s16)(rand * 160.0f) + 95;
+ this->soulColor.a = 200;
+ }
+}
+
+void EnPoField_Update(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnPoField* this = THIS;
+
+ EnPoField_TestForDamage(this, globalCtx);
+ this->actionFunc(this, globalCtx);
+ EnPoField_UpdateFlame(this, globalCtx);
+ if (this->actionFunc == EnPoField_Flee || this->actionFunc == EnPoField_Damage ||
+ this->actionFunc == EnPoField_Appear) {
+ Actor_MoveForward(&this->actor);
+ }
+ if (this->actionFunc != EnPoField_WaitForSpawn) {
+ Actor_SetHeight(&this->actor, 42.0f);
+ func_8002E4B4(globalCtx, &this->actor, 0.0f, 27.0f, 60.0f, 4);
+ func_80AD619C(this);
+ func_80AD6330(this);
+ Collider_CylinderUpdate(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ if (this->collider.base.acFlags & 1) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ }
+}
+
+s32 EnPoField_OverrideLimbDraw2(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ void* thisx, Gfx** gfxP) {
+ EnPoField* this = THIS;
+
+ if (this->lightColor.a == 0 || limbIndex == 7 || (this->actionFunc == EnPoField_Death && this->actionTimer >= 2)) {
+ *dList = NULL;
+ } else if (this->actor.params == EN_PO_FIELD_BIG) {
+ if (limbIndex == 1) {
+ *dList = D_06005900;
+ } else if (limbIndex == 8) {
+ *dList = D_06005620;
+ } else if (limbIndex == 9) {
+ *dList = D_060059F0;
+ }
+ }
+ if (this->actionFunc == EnPoField_Disappear && limbIndex == 7) {
+ Matrix_Scale(this->actionTimer * 0.0625f, this->actionTimer * 0.0625f, this->actionTimer * 0.0625f, 1);
+ }
+ return 0;
+}
+
+void EnPoField_PostLimDraw2(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfxP) {
+ EnPoField* this = THIS;
+
+ if (this->actionFunc == EnPoField_Death && this->actionTimer >= 2 && limbIndex == 8) {
+ gSPMatrix((*gfxP)++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_field.c", 1916),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList((*gfxP)++, D_060066D0);
+ }
+ if (limbIndex == 7) {
+ Vec3f vec;
+ Matrix_MultVec3f(&D_80AD714C, &vec);
+ if (this->actionFunc == EnPoField_Death && this->actionTimer >= 19 && this->actor.scale.x != 0.0f) {
+ f32 mtxScale = 0.01f / this->actor.scale.x;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ }
+ Matrix_Get(&sLimb7Mtx);
+ if (this->actionFunc == EnPoField_Death && this->actionTimer == 27) {
+ this->actor.posRot.pos.x = sLimb7Mtx.wx;
+ this->actor.posRot.pos.y = sLimb7Mtx.wy;
+ this->actor.posRot.pos.z = sLimb7Mtx.wz;
+ }
+ Lights_PointGlowSetInfo(&this->lightInfo, vec.x, vec.y, vec.z, this->soulColor.r, this->soulColor.g,
+ this->soulColor.b, this->soulColor.a * 0.7843137383460999f);
+ }
+}
+
+void EnPoField_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoField* this = THIS;
+ EnPoFieldInfo* info = &sPoFieldInfo[this->actor.params];
+
+ if (this->actionFunc != EnPoField_WaitForSpawn) {
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 1976);
+ func_80093D18(globalCtx->state.gfxCtx);
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x0A,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, info->envColor.r, info->envColor.g, info->envColor.b, 255));
+ if (this->lightColor.a == 255 || this->lightColor.a == 0) {
+ gSPSegment(POLY_OPA_DISP++, 0x08,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
+ this->lightColor.a));
+ gSPSegment(POLY_OPA_DISP++, 0x0C, D_80116280 + 2);
+ POLY_OPA_DISP =
+ SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoField_OverrideLimbDraw2, EnPoField_PostLimDraw2, &this->actor, POLY_OPA_DISP);
+ } else {
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
+ this->lightColor.a));
+ gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280);
+ POLY_XLU_DISP =
+ SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoField_OverrideLimbDraw2, EnPoField_PostLimDraw2, &this->actor, POLY_XLU_DISP);
+ }
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->soulColor.r, this->soulColor.g, this->soulColor.b, 255);
+ Matrix_Put(&sLimb7Mtx);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2033),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004BA0);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004CC0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2039);
+ }
+ EnPoField_DrawFlame(this, globalCtx);
+}
+
+void EnPoField_UpdateDead(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoField* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+ if (this->actionFunc == EnPoField_SoulIdle) {
+ func_80AD6330(this);
+ }
+ EnPoField_UpdateFlame(this, globalCtx);
+}
+
+void EnPoField_DrawSoul(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoField* this = THIS;
+ s32 pad;
+ EnPoFieldInfo* info = &sPoFieldInfo[this->actor.params];
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2077);
+ if (this->actionFunc == EnPoField_SoulIdle) {
+ func_80093D18(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x0A,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, info->envColor.r, info->envColor.g, info->envColor.b, 255));
+ Lights_PointGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, this->soulColor.r, this->soulColor.g, this->soulColor.b, 200);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->soulColor.r, this->soulColor.g, this->soulColor.b, 255);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2104),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004BA0);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004CC0);
+ } else {
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0,
+ (globalCtx->gameplayFrames * info->unk_9) & 0x1FF, 0x20, 0x80));
+ gSPSegment(POLY_XLU_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(info->unk_C));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, info->primColor.r, info->primColor.g, info->primColor.b,
+ this->lightColor.a);
+ gDPSetEnvColor(POLY_XLU_DISP++, this->lightColor.r, this->lightColor.g, this->lightColor.b, 255);
+ Matrix_RotateY((s16)(func_8005A9F4(ACTIVE_CAM) + 0x8000) * 9.58738e-05f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2143),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, D_060023B0);
+ }
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_field.c", 2149);
+ EnPoField_DrawFlame(this, globalCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
index 752c0b56a..ead31b949 100644
--- a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
+++ b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
@@ -6,9 +6,41 @@
struct EnPoField;
+typedef void (*EnPoFieldActionFunc)(struct EnPoField*, GlobalContext*);
+
+typedef enum {
+ EN_PO_FIELD_SMALL,
+ EN_PO_FIELD_BIG
+} EnPoFieldSize;
+
+typedef struct {
+ /* 0x0000 */ Color_RGB8 primColor;
+ /* 0x0003 */ Color_RGB8 lightColor;
+ /* 0x0006 */ Color_RGB8 envColor;
+ /* 0x0009 */ s8 unk_9;
+ /* 0x000C */ UNK_PTR unk_C;
+} EnPoFieldInfo; // size = 0x10
+
typedef struct EnPoField {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x190];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ EnPoFieldActionFunc actionFunc;
+ /* 0x0194 */ u8 unk_194;
+ /* 0x0195 */ u8 spawnFlagIndex;
+ /* 0x0196 */ s16 actionTimer;
+ /* 0x0198 */ s16 flameRotation;
+ /* 0x019A */ s16 flameTimer;
+ /* 0x019C */ Vec3s limbDrawTable[10];
+ /* 0x01D8 */ Vec3s transitionDrawTable[10];
+ /* 0x0214 */ Color_RGBA8 lightColor;
+ /* 0x0214 */ Color_RGBA8 soulColor;
+ /* 0x021C */ f32 scaleModifier;
+ /* 0x0220 */ f32 flameScale;
+ /* 0x0224 */ Vec3f flamePosition;
+ /* 0x0230 */ LightNode* lightNode;
+ /* 0x0234 */ LightInfo lightInfo;
+ /* 0x0244 */ ColliderCylinder collider;
+ /* 0x0290 */ ColliderCylinder flameCollider;
} EnPoField; // size = 0x02DC
extern const ActorInit En_Po_Field_InitVars;
diff --git a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
index abd6b8252..8413d4c08 100644
--- a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
+++ b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
@@ -1,3 +1,9 @@
+/*
+ * File: z_en_po_relay.c
+ * Overlay: ovl_En_Po_Relay
+ * Description: Dampé's Ghost
+ */
+
#include "z_en_po_relay.h"
#define FLAGS 0x00011019
@@ -9,7 +15,24 @@ void EnPoRelay_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPoRelay_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPoRelay_Draw(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnPoRelay_Idle(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_Race(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_EndRace(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_Talk(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_Talk2(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_DisappearAndReward(EnPoRelay* this, GlobalContext* globalCtx);
+void EnPoRelay_SetupIdle(EnPoRelay* this);
+
+Vec3s D_80AD8C30[] = {
+ { 0xFFC4, 0xFDEE, 0xF47A }, { 0x0186, 0xFE0C, 0xF47A }, { 0x0186, 0xFE0C, 0xF0F6 }, { 0x00D2, 0xFDEE, 0xF0F6 },
+ { 0x00D2, 0xFD9E, 0xEEDA }, { 0x023A, 0xFDC6, 0xEEDA }, { 0x023A, 0xFDC6, 0xED18 }, { 0x00D2, 0xFDC6, 0xED18 },
+ { 0x00D2, 0xFDC6, 0xEBCE }, { 0x00D2, 0xFDC6, 0xEAA2 }, { 0x023A, 0xFDC6, 0xEAA2 }, { 0x023A, 0xFDC6, 0xEBB0 },
+ { 0x04EC, 0xFD9E, 0xEBB0 }, { 0x0672, 0xFD62, 0xED18 }, { 0x0672, 0xFD30, 0xEE80 }, { 0x07DA, 0xFD26, 0xEE80 },
+ { 0x07DA, 0xFD26, 0xEF70 }, { 0x07DA, 0xFD26, 0xF204 }, { 0x0672, 0xFD44, 0xF204 }, { 0x0672, 0xFD6C, 0xF3C6 },
+ { 0x088E, 0xFD6C, 0xF3C6 }, { 0x088E, 0xFDB2, 0xF5E2 }, { 0x099C, 0xFDD0, 0xF5E2 }, { 0x0B54, 0xFE66, 0xF772 },
+ { 0x0B4E, 0xFE66, 0xF87E }, { 0x0B4A, 0xFE66, 0xF97A }, { 0x0B4A, 0xFE98, 0xF9FC }, { 0x0BAE, 0xFE98, 0xF9FC },
+};
+
const ActorInit En_Po_Relay_InitVars = {
ACTOR_EN_PO_RELAY,
ACTORTYPE_NPC,
@@ -21,35 +44,364 @@ const ActorInit En_Po_Relay_InitVars = {
(ActorFunc)EnPoRelay_Update,
(ActorFunc)EnPoRelay_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Destroy.s")
+static ColliderCylinderInit sCylinderInit = {
+ { COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
+ { 30, 52, 0, { 0, 0, 0 } },
+};
+
+static s32 D_80AD8D24 = 0;
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_S8(naviEnemyId, 0x4F, ICHAIN_CONTINUE),
+ ICHAIN_F32(unk_4C, 1500, ICHAIN_STOP),
+};
+
+static Vec3f D_80AD8D30 = { 0.0f, 1.5f, 0.0f };
+
+static Vec3f D_80AD8D3C = { 0.0f, 0.0f, 0.0f };
+
+static Vec3f D_80AD8D48 = { 0.0f, 1200.0f, 0.0f };
+
+static UNK_PTR sEyesSegments[] = {
+ 0x06003B40,
+ 0x06004340,
+ 0x06004B40,
+};
+
+extern FlexSkeletonHeader D_0600BE40;
+extern AnimationHeader D_06003768;
+extern Gfx D_0600B838[];
+extern Gfx D_0600BBA0[];
+
+void EnPoRelay_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoRelay* this = THIS;
+ s32 temp;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 42.0f);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600BE40, &D_06003768, this->limbDrawTable,
+ this->transitionDrawTable, 18);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
+ this->actor.initPosRot.pos.z, 255, 255, 255, 200);
+ this->lightColor.a = 255;
+ temp = 1;
+ if (D_80AD8D24 != 0) {
+ Actor_Kill(&this->actor);
+ } else {
+ D_80AD8D24 = temp;
+ Actor_SetTextWithPrefix(globalCtx, &this->actor, 65);
+ this->textId = this->actor.textId;
+ EnPoRelay_SetupIdle(this);
+ }
+ this->actor.params &= 0x3F;
+}
+
+void EnPoRelay_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoRelay* this = THIS;
+
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
+
+void EnPoRelay_SetupIdle(EnPoRelay* this) {
+ this->unk_195 = 32;
+ this->pathIndex = 0;
+ this->actor.room = -1;
+ this->actor.shape.rot.y = 0;
+ this->actor.posRot.rot.y = -0x8000;
+ this->actor.colChkInfo.mass = 0xFE;
+ this->actionFunc = EnPoRelay_Idle;
+}
+
+void EnPoRelay_Vec3sToVec3f(Vec3f* dest, Vec3s* src) {
+ dest->x = src->x;
+ dest->y = src->y;
+ dest->z = src->z;
+}
+
+void EnPoRelay_SetupRace(EnPoRelay* this) {
+ Vec3f vec;
+
+ EnPoRelay_Vec3sToVec3f(&vec, &D_80AD8C30[this->pathIndex]);
+ this->actionTimer = ((s16)(this->actor.shape.rot.y - this->actor.posRot.rot.y - 0x8000) >> 0xB) % 32U;
+ func_80088B34(0);
+ this->hookshotSlotFull = INV_CONTENT(ITEM_HOOKSHOT) != ITEM_NONE;
+ this->unk_19A = func_8002DAC0(&this->actor, &vec);
+ this->actor.flags |= 0x8000000;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actionFunc = EnPoRelay_Race;
+}
+
+void EnPoRelay_SetupEndRace(EnPoRelay* this) {
+ this->actor.posRot.rot.y = this->actor.initPosRot.rot.y + 0xC000;
+ this->actor.flags &= ~0x08000000;
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = EnPoRelay_EndRace;
+}
+
+void EnPoRelay_CorrectY(EnPoRelay* this) {
+ Math_ApproxF(&this->actor.initPosRot.pos.y, D_80AD8C30[(this->pathIndex >= 28) ? 27 : this->pathIndex].y + 45.0f,
+ 2.0f);
+ this->actor.posRot.pos.y = Math_Sins(this->unk_195 * 0x800) * 8.0f + this->actor.initPosRot.pos.y;
+}
+
+void EnPoRelay_Idle(EnPoRelay* this, GlobalContext* globalCtx) {
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, this->actor.yawTowardsLink, 0x100);
+ if (func_8002F194(&this->actor, globalCtx) != 0) {
+ this->actor.flags &= ~0x10000;
+ this->actionFunc = EnPoRelay_Talk;
+ } else if (this->actor.xzDistFromLink < 250.0f) {
+ this->actor.flags |= 0x10000;
+ this->actor.textId = this->textId;
+ func_8002F2CC(&this->actor, globalCtx, 250.0f);
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD790C.s")
+void EnPoRelay_Talk(EnPoRelay* this, GlobalContext* globalCtx) {
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, this->actor.yawTowardsLink, 0x100);
+ if (func_8002F334(&this->actor, globalCtx) != 0) {
+ Actor_SetTextWithPrefix(globalCtx, &this->actor, 0x2F);
+ this->textId = this->actor.textId;
+ EnPoRelay_SetupRace(this);
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7944.s")
+#ifdef NON_MATCHING
+// Single stack difference
+void EnPoRelay_Race(EnPoRelay* this, GlobalContext* globalCtx) { // saved, sp64
+ Player* player = PLAYER; // sp5C
+ Vec3f vec; // sp50
+ f32 rand;
+ f32 multiplier; // sp48
+ f32 speed;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7984.s")
+ if (this->actionTimer != 0) {
+ this->actionTimer--;
+ }
+ if (this->actionTimer == 0 && Math_Rand_ZeroOne() < 0.03f) {
+ this->actionTimer = 32;
+ if (this->pathIndex < 23) {
+ rand = Math_Rand_ZeroOne() * 3.0f;
+ if (rand < 1.0f) {
+ multiplier = 1.0f;
+ } else if (rand < 2.0f) {
+ multiplier = -1.0f;
+ } else {
+ multiplier = 0.0f;
+ }
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HONOTRAP,
+ Math_Coss(this->unk_19A) * (30.0f * multiplier) + this->actor.posRot.pos.x,
+ this->actor.posRot.pos.y,
+ Math_Sins(this->unk_19A) * (30.0f * multiplier) + this->actor.posRot.pos.z, 0,
+ (this->unk_19A + 0x8000) - (0x2000 * multiplier), 0, 2);
+ }
+ }
+ Math_SmoothScaleMaxMinS(&this->actor.posRot.rot.y, this->unk_19A, 2, 0x1000, 0x100);
+ this->actor.shape.rot.y = this->actor.posRot.rot.y + (this->actionTimer * 0x800) + 0x8000;
+ if (this->pathIndex < 23) {
+ // If the player travels along a different path to Dampé that converges later
+ if ((Math3D_PointInSquare2D(660.0f, 840.0f, -4480.0f, -3760.0f, player->actor.posRot.pos.x,
+ player->actor.posRot.pos.z) != 0) ||
+ (Math3D_PointInSquare2D(1560.0f, 1740.0f, -4030.0f, -3670.0f, player->actor.posRot.pos.x,
+ player->actor.posRot.pos.z) != 0) ||
+ (Math3D_PointInSquare2D(1580.0f, 2090.0f, -3030.0f, -2500.0f, player->actor.posRot.pos.x,
+ player->actor.posRot.pos.z) != 0)) {
+ speed = (this->hookshotSlotFull) ? player->actor.speedXZ * 1.4f : player->actor.speedXZ * 1.2f;
+ } else if (this->actor.xzDistFromLink < 150.0f) {
+ speed = (this->hookshotSlotFull) ? player->actor.speedXZ * 1.2f : player->actor.speedXZ;
+ } else if (this->actor.xzDistFromLink < 300.0f) {
+ speed = (this->hookshotSlotFull) ? player->actor.speedXZ : player->actor.speedXZ * 0.8f;
+ } else if (this->hookshotSlotFull) {
+ speed = 4.5f;
+ } else {
+ speed = 3.5f;
+ }
+ multiplier = 250.0f - this->actor.xzDistFromLink;
+ multiplier = CLAMP_MIN(multiplier, 0.0f);
+ speed += multiplier * 0.02f + 1.0f;
+ Math_SmoothScaleMaxF(&this->actor.speedXZ, speed, 0.5f, 1.5f);
+ } else {
+ Math_SmoothScaleMaxF(&this->actor.speedXZ, 3.5f, 0.5f, 1.5f);
+ }
+ EnPoRelay_Vec3sToVec3f(&vec, &D_80AD8C30[this->pathIndex]);
+ if (func_8002DBB0(&this->actor, &vec) < 40.0f) {
+ this->pathIndex++;
+ EnPoRelay_Vec3sToVec3f(&vec, &D_80AD8C30[this->pathIndex]);
+ if (this->pathIndex == 28) {
+ EnPoRelay_SetupEndRace(this);
+ } else if (this->pathIndex == 9) {
+ Flags_SetSwitch(globalCtx, 0x35);
+ } else if (this->pathIndex == 17) {
+ Flags_SetSwitch(globalCtx, 0x36);
+ } else if (this->pathIndex == 25) {
+ Flags_SetSwitch(globalCtx, 0x37);
+ }
+ }
+ this->unk_19A = func_8002DAC0(&this->actor, &vec);
+ func_8002F974(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG);
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Race.s")
+#endif
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7A4C.s")
+void EnPoRelay_EndRace(EnPoRelay* this, GlobalContext* globalCtx) {
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, -0x4000, 0x800);
+ if (func_8002F194(&this->actor, globalCtx) != 0) {
+ this->actionFunc = EnPoRelay_Talk2;
+ } else if (globalCtx->roomCtx.curRoom.num == 5) {
+ Actor_Kill(&this->actor);
+ gSaveContext.timer1State = 0;
+ } else if (func_8002E12C(&this->actor, 150.0f, 0x3000) != 0) {
+ this->actor.textId = this->textId;
+ func_8002F2CC(&this->actor, globalCtx, 250.0f);
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7A88.s")
+void EnPoRelay_Talk2(EnPoRelay* this, GlobalContext* globalCtx) {
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, this->actor.yawTowardsLink, 0x100);
+ if (func_8010BDBC(&globalCtx->msgCtx) == 5) {
+ if (func_80106BC8(globalCtx) != 0) {
+ if (this->hookshotSlotFull != 0) {
+ Actor_SetTextWithPrefix(globalCtx, &this->actor, 0x2E);
+ } else {
+ Actor_SetTextWithPrefix(globalCtx, &this->actor, 0x2D);
+ }
+ this->textId = this->actor.textId;
+ func_8010B720(globalCtx, this->actor.textId);
+ }
+ } else if (func_8002F334(&this->actor, globalCtx) != 0) {
+ gSaveContext.timer1State = 0;
+ this->actionTimer = 0;
+ this->actionFunc = EnPoRelay_DisappearAndReward;
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7B34.s")
+void EnPoRelay_DisappearAndReward(EnPoRelay* this, GlobalContext* globalCtx) {
+ Vec3f vec;
+ f32 multiplier;
+ s32 pad;
+ Vec3f sp60;
+ s32 pad1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7BF0.s")
+ this->actionTimer++;
+ if (this->actionTimer < 8) {
+ if (this->actionTimer < 5) {
+ vec.y = Math_Sins((this->actionTimer * 0x1000) - 0x4000) * 23.0f + (this->actor.posRot.pos.y + 40.0f);
+ multiplier = Math_Coss((this->actionTimer * 0x1000) - 0x4000) * 23.0f;
+ vec.x = (Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * multiplier) + this->actor.posRot.pos.x;
+ vec.z = (Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * multiplier) + this->actor.posRot.pos.z;
+ } else {
+ vec.y = this->actor.posRot.pos.y + 40.0f + 15.0f * (this->actionTimer - 5);
+ vec.x = (Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f) + this->actor.posRot.pos.x;
+ vec.z = (Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f) + this->actor.posRot.pos.z;
+ }
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AD8D30, &D_80AD8D3C, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, true);
+ vec.x = (this->actor.posRot.pos.x + this->actor.posRot.pos.x) - vec.x;
+ vec.z = (this->actor.posRot.pos.z + this->actor.posRot.pos.z) - vec.z;
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AD8D30, &D_80AD8D3C, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, true);
+ vec.x = this->actor.posRot.pos.x;
+ vec.z = this->actor.posRot.pos.z;
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AD8D30, &D_80AD8D3C, this->actionTimer * 10 + 80, 0, 255, 255, 255,
+ 255, 0, 0, 255, 1, 9, true);
+ if (this->actionTimer == 1) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_EXTINCT);
+ }
+ }
+ if (Math_ApproxF(&this->actor.scale.x, 0.0f, 0.001f) != 0) {
+ if (this->hookshotSlotFull != 0) {
+ sp60.x = this->actor.posRot.pos.x;
+ sp60.y = this->actor.groundY;
+ sp60.z = this->actor.posRot.pos.z;
+ if (gSaveContext.timer1Value < gSaveContext.dampeRaceTime) {
+ gSaveContext.dampeRaceTime = gSaveContext.timer1Value;
+ }
+ if (Flags_GetCollectible(globalCtx, this->actor.params) == 0 && gSaveContext.timer1Value <= 60) {
+ Item_DropCollectible2(globalCtx, &sp60, (this->actor.params << 8) + (0x4000 | ITEM00_HEART_PIECE));
+ } else {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, sp60.x, sp60.y, sp60.z, 0, 0, 0, 2);
+ }
+ } else {
+ Flags_SetTempClear(globalCtx, 4);
+ gSaveContext.dampeRaceTime = gSaveContext.timer1Value;
+ }
+ Actor_Kill(&this->actor);
+ }
+ this->actor.scale.y = this->actor.scale.x;
+ this->actor.scale.z = this->actor.scale.x;
+ this->actor.posRot.pos.y += 10.0f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7C64.s")
+void EnPoRelay_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoRelay* this = THIS;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD8174.s")
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ this->actionFunc(this, globalCtx);
+ Actor_MoveForward(&this->actor);
+ EnPoRelay_CorrectY(this);
+ func_8002E4B4(globalCtx, &this->actor, 0.0f, 27.0f, 60.0f, 4);
+ Collider_CylinderUpdate(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ Actor_SetHeight(&this->actor, 50.0f);
+ if (this->unk_195 != 0) {
+ this->unk_195 -= 1;
+ }
+ if (this->unk_195 == 0) {
+ this->unk_195 = 32;
+ }
+ this->eyeTextureIdx++;
+ if (this->eyeTextureIdx == 3) {
+ this->eyeTextureIdx = 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD8234.s")
+void EnPoRelay_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnPoRelay* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD830C.s")
+ if (limbIndex == 14) {
+ f32 rand;
+ Vec3f vec;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Update.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 885);
+ rand = Math_Rand_ZeroOne();
+ this->lightColor.r = (s16)(rand * 30.0f) + 225;
+ this->lightColor.g = (s16)(rand * 100.0f) + 155;
+ this->lightColor.b = (s16)(rand * 160.0f) + 95;
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->lightColor.r, this->lightColor.g, this->lightColor.b, 128);
+ gSPDisplayList(POLY_OPA_DISP++, D_0600B838);
+ if (1) {}
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 901);
+ Matrix_MultVec3f(&D_80AD8D48, &vec);
+ Lights_PointNoGlowSetInfo(&this->lightInfo, vec.x, vec.y, vec.z, this->lightColor.r, this->lightColor.g,
+ this->lightColor.b, 200);
+ } else if (limbIndex == 8) {
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 916);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 918),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, D_0600BBA0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 922);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD88D0.s")
+void EnPoRelay_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoRelay* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Draw.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 940);
+ func_80093D18(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyesSegments[this->eyeTextureIdx]));
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount,
+ NULL, EnPoRelay_PostLimbDraw, &this->actor);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_relay.c", 954);
+}
diff --git a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h
index b4fd76f1b..414173a62 100644
--- a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h
+++ b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h
@@ -6,9 +6,25 @@
struct EnPoRelay;
+typedef void (*EnPoRelayActionFunc)(struct EnPoRelay*, GlobalContext*);
+
typedef struct EnPoRelay {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x190];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ EnPoRelayActionFunc actionFunc;
+ /* 0x0194 */ u8 hookshotSlotFull;
+ /* 0x0195 */ u8 unk_195;
+ /* 0x0196 */ s16 actionTimer;
+ /* 0x0198 */ s16 pathIndex;
+ /* 0x019A */ s16 unk_19A;
+ /* 0x019C */ u16 textId;
+ /* 0x019E */ u16 eyeTextureIdx;
+ /* 0x01A0 */ Vec3s limbDrawTable[18];
+ /* 0x020C */ Vec3s transitionDrawTable[18];
+ /* 0x0278 */ Color_RGBA8 lightColor;
+ /* 0x027C */ LightNode* lightNode;
+ /* 0x0280 */ LightInfo lightInfo;
+ /* 0x0290 */ ColliderCylinder collider;
} EnPoRelay; // size = 0x02DC
extern const ActorInit En_Po_Relay_InitVars;
diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
index 9470b3b08..c0fc9d8e2 100644
--- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
+++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
@@ -1,3 +1,9 @@
+/*
+ * File: z_en_po_sisters.c
+ * Overlay: ovl_En_Po_Sisters
+ * Description: Forest Temple Four Poe Sisters
+ */
+
#include "z_en_po_sisters.h"
#define FLAGS 0x00005215
@@ -9,7 +15,52 @@ void EnPoSisters_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPoSisters_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx);
-/*
+void func_80ADA094(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA4A8(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA530(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA6A0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA7F0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA8C0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADA9E8(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADAAA4(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADAC70(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADAD54(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADAE6C(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADAFC0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB17C(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB2B8(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB338(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB9F0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB4B0(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB51C(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADB770(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBB6C(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBBF4(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBC88(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBD38(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBD8C(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBEE8(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80ADBF58(EnPoSisters* this, GlobalContext* globalCtx);
+
+void func_80AD9AA8(EnPoSisters* this, GlobalContext* globalCtx);
+void func_80AD9C24(EnPoSisters* this, GlobalContext* globalCtx);
+
+void func_80AD9D44(EnPoSisters* this);
+
+static Color_RGBA8 D_80ADD6F0[4] = {
+ { 255, 170, 255, 255 },
+ { 255, 200, 0, 255 },
+ { 0, 170, 255, 255 },
+ { 170, 255, 0, 255 },
+};
+
+static Color_RGBA8 D_80ADD700[4] = {
+ { 100, 0, 255, 255 },
+ { 255, 0, 0, 255 },
+ { 0, 0, 255, 255 },
+ { 0, 150, 0, 255 },
+};
+
const ActorInit En_Po_Sisters_InitVars = {
ACTOR_EN_PO_SISTERS,
ACTORTYPE_ENEMY,
@@ -21,127 +72,1310 @@ const ActorInit En_Po_Sisters_InitVars = {
(ActorFunc)EnPoSisters_Update,
(ActorFunc)EnPoSisters_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/EnPoSisters_Init.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/EnPoSisters_Destroy.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9240.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9368.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD93C4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD943C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD944C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD94E0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9568.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD95D8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD96A4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9718.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD97C8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD98F4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD99D4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9A54.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9AA8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9C24.s")
+static ColliderCylinderInit sCylinderInit = {
+ { COLTYPE_UNK3, 0x11, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0xFFCFFFFF, 0x00, 0x08 }, { 0x4FC7FFEA, 0x00, 0x00 }, 0x01, 0x05, 0x01 },
+ { 18, 60, 15, { 0, 0, 0 } },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9D44.s")
+static CollisionCheckInfoInit sColChkInfoInit = { 0x0A, 0x0019, 0x003C, 0x28 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9DF0.s")
+static DamageTable sDamageTable = {
+ 0xF0, 0x02, 0x01, 0x02, 0x00, 0x02, 0x02, 0x02, 0xE1, 0xE2, 0xE4, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0xE4, 0xE2, 0xE2, 0xE8, 0xE4, 0x00, 0x00, 0x04, 0x00,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9E60.s")
+static s32 D_80ADD784 = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9F1C.s")
+static InitChainEntry sInitChain[] = {
+ ICHAIN_VEC3F_DIV1000(scale, 7, ICHAIN_CONTINUE),
+ ICHAIN_F32(unk_4C, 6000, ICHAIN_STOP),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80AD9F90.s")
+static Vec3f sZeroVector = { 0.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA028.s")
+static s16 D_80ADD79C[4] = { 0xB000, 0xD000, 0x5000, 0x3000 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA094.s")
+static Vec3s D_80ADD7A4[4] = {
+ { -22, 337, -1704 },
+ { -431, 879, -3410 },
+ { 549, 879, -3410 },
+ { 1717, 515, -1340 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA10C.s")
+static Vec3f D_80ADD7BC = { 120.0f, 250.0f, -1420.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA1B8.s")
+static Gfx* D_80ADD7C8[4] = { 0x06001DE0, 0x06002F88, 0x06003628, 0x06003DC8 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA25C.s")
+static Gfx* D_80ADD7D8[4] = { 0x06001CB0, 0x06002EB8, 0x06003880, 0x06004020 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA2BC.s")
+static Color_RGBA8 D_80ADD7E8[4] = {
+ { 80, 0, 100, 0 },
+ { 80, 15, 0, 0 },
+ { 0, 70, 50, 0 },
+ { 70, 70, 0, 0 },
+};
+static Vec3f D_80ADD7F8 = { 1000.0f, -1700.0f, 0.0f };
+
+extern SkeletonHeader D_060065C8;
+extern AnimationHeader D_060014CC;
+extern AnimationHeader D_06000D40;
+extern AnimationHeader D_06000114;
+extern AnimationHeader D_060008C0;
+extern AnimationHeader D_06000A54;
+extern AnimationHeader D_0600119C;
+extern AnimationHeader D_06000680;
+
+extern Gfx D_060027B0[];
+extern Gfx D_060046E0[];
+
+extern Gfx D_0404D4E0[];
+
+void EnPoSisters_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoSisters* this = THIS;
+ s32 pad;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 50.0f);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &D_060065C8, &D_060014CC, this->limbDrawTable,
+ this->transitionDrawTable, 12);
+ this->unk_22E.r = 255;
+ this->unk_22E.g = 255;
+ this->unk_22E.b = 210;
+ this->unk_22E.a = 255;
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ Lights_PointGlowSetInfo(&this->lightInfo, this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
+ this->actor.initPosRot.pos.z, 0, 0, 0, 0);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ func_80061ED4(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+ this->unk_194 = (thisx->params >> 8) & 3;
+ this->actor.naviEnemyId = this->unk_194 + 0x50;
+ if (1) {}
+ this->unk_195 = (thisx->params >> 0xA) & 3;
+ this->unk_196 = 32;
+ this->unk_197 = 20;
+ this->unk_198 = 1;
+ this->unk_199 = 32;
+ this->unk_294 = 110.0f;
+ this->actor.flags &= ~1;
+ if (this->actor.params & 0x1000) {
+ func_80ADA094(this, globalCtx);
+ } else if (this->unk_194 == 0) {
+ if (this->unk_195 == 0) {
+ this->collider.base.maskA = 9;
+ func_80AD9AA8(this, globalCtx);
+ } else {
+ this->actor.flags &= -0x4201;
+ this->collider.body.flags = 4;
+ this->collider.body.bumper.flags |= 1;
+ this->collider.base.maskA = 0;
+ func_80AD9C24(this, NULL);
+ }
+ } else {
+ func_80AD9D44(this);
+ }
+ this->actor.params &= 0x3F;
+}
+
+void EnPoSisters_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoSisters* this = THIS;
+
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ if (this->unk_194 == 0 && this->unk_195 == 0) {
+ func_800F5B58();
+ }
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
+
+void func_80AD9240(EnPoSisters* this, s32 arg1, Vec3f* arg2) {
+ f32 temp_f20 = SQ(arg1) * 0.1f;
+ Vec3f* vec;
+ s32 i;
+
+ for (i = 0; i < this->unk_198; i++) {
+ vec = &this->unk_234[i];
+ vec->x = arg2->x + Math_Sins((s16)(this->actor.shape.rot.y + (this->unk_19A * 0x800) + i * 0x2000)) * temp_f20;
+ vec->z = arg2->z + Math_Coss((s16)(this->actor.shape.rot.y + (this->unk_19A * 0x800) + i * 0x2000)) * temp_f20;
+ vec->y = arg2->y + arg1;
+ }
+}
+
+void func_80AD9368(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_060014CC, -3.0f);
+ this->unk_19A = Math_Rand_S16Offset(2, 3);
+ this->actionFunc = func_80ADA4A8;
+ this->actor.speedXZ = 0.0f;
+}
+
+void func_80AD93C4(EnPoSisters* this) {
+ if (this->actionFunc != func_80ADA6A0) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000D40, -3.0f);
+ }
+ this->unk_19A = Math_Rand_S16Offset(0xF, 3);
+ this->unk_199 |= 7;
+ this->actionFunc = func_80ADA530;
+}
+
+void func_80AD943C(EnPoSisters* this) {
+ this->actionFunc = func_80ADA6A0;
+}
+
+void func_80AD944C(EnPoSisters* this) {
+ if (this->unk_22E.a != 0) {
+ this->collider.base.type = COLTYPE_METAL_SHIELD;
+ this->collider.base.acFlags |= 4;
+ }
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000114, -5.0f);
+ this->actor.speedXZ = 0.0f;
+ this->unk_19A = SkelAnime_GetFrameCount(&D_06000114) * 3 + 3;
+ this->unk_199 &= ~2;
+ this->actionFunc = func_80ADA7F0;
+}
+
+void func_80AD94E0(EnPoSisters* this) {
+ this->actor.speedXZ = 5.0f;
+ if (this->unk_194 == 0) {
+ this->collider.base.type = COLTYPE_METAL_SHIELD;
+ this->collider.base.acFlags |= 4;
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000114, -5.0f);
+ }
+ this->unk_19A = 5;
+ this->actor.posRot.rot.y = this->actor.yawTowardsLink;
+ this->unk_199 |= 8;
+ this->actionFunc = func_80ADA8C0;
+}
+
+void func_80AD9568(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000D40, -3.0f);
+ this->actor.posRot.rot.y = this->actor.yawTowardsLink + 0x8000;
+ if (this->unk_194 != 0) {
+ this->collider.base.type = COLTYPE_UNK3;
+ this->collider.base.acFlags &= ~4;
+ }
+ this->actionFunc = func_80ADA9E8;
+}
+
+void func_80AD95D8(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_060008C0, -3.0f);
+ if (this->collider.base.ac != NULL) {
+ this->actor.posRot.rot.y = (this->collider.body.acHitItem->toucher.flags & 0x1F824)
+ ? this->collider.base.ac->posRot.rot.y
+ : func_8002DA78(&this->actor, this->collider.base.ac) + 0x8000;
+ }
+ if (this->unk_194 != 0) {
+ this->actor.speedXZ = 10.0f;
+ }
+ this->unk_199 &= ~0xB;
+ func_8003426C(&this->actor, 0x4000, 0xFF, 0, 0x10);
+ this->actionFunc = func_80ADAAA4;
+}
+
+void func_80AD96A4(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000A54, -3.0f);
+ this->actor.posRot.rot.y = this->actor.shape.rot.y + 0x8000;
+ this->unk_19A = 5;
+ this->unk_199 |= 0xB;
+ this->actor.speedXZ = 5.0f;
+ this->actionFunc = func_80ADAC70;
+}
+
+void func_80AD9718(EnPoSisters* this) {
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_0600119C, 1.5f, 0.0f, SkelAnime_GetFrameCount(&D_0600119C), 2, -3.0f);
+ this->actor.speedXZ = 0.0f;
+ this->unk_19C = 100;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ this->unk_199 &= ~5;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ this->actionFunc = func_80ADAD54;
+}
+
+void func_80AD97C8(EnPoSisters* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ f32 sp20;
+
+ if (this->unk_195 == 0 || this->actionFunc != func_80ADAAA4) {
+ if ((player->swordState == 0 || player->swordAnimation >= 24) &&
+ player->actor.posRot.pos.y - player->actor.groundY < 1.0f) {
+ Math_ApproxF(&this->unk_294, 110.0f, 3.0f);
+ } else {
+ Math_ApproxF(&this->unk_294, 170.0f, 10.0f);
+ }
+ sp20 = this->unk_294;
+ } else if (this->unk_195 != 0) {
+ sp20 = this->actor.parent->xzDistFromLink;
+ }
+ this->actor.posRot.pos.x = (Math_Sins(this->actor.shape.rot.y + 0x8000) * sp20) + player->actor.posRot.pos.x;
+ this->actor.posRot.pos.z = (Math_Coss(this->actor.shape.rot.y + 0x8000) * sp20) + player->actor.posRot.pos.z;
+}
+
+void func_80AD98F4(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_0600119C, 1.5f, 0.0f, SkelAnime_GetFrameCount(&D_0600119C), 2, -3.0f);
+ if (this->unk_194 == 0) {
+ this->unk_294 = 110.0f;
+ func_80AD97C8(this, globalCtx);
+ this->unk_22E.a = 0;
+ this->actor.draw = EnPoSisters_Draw;
+ } else {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ }
+ this->unk_19A = 15;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ this->unk_199 &= ~1;
+ this->actionFunc = func_80ADAE6C;
+}
+
+void func_80AD99D4(EnPoSisters* this, GlobalContext* globalCtx) {
+ this->unk_19A = 0;
+ this->actor.speedXZ = 0.0f;
+ this->actor.posRot.pos.y += 42.0f;
+ this->actor.shape.unk_08 = -6000.0f;
+ this->actor.flags &= -2;
+ this->unk_199 = 0;
+ this->actionFunc = func_80ADAFC0;
+ func_800800F8(globalCtx, 0xC76, 0x3E7, &this->actor, 0);
+}
+
+void func_80AD9A54(EnPoSisters* this, GlobalContext* globalCtx) {
+ this->unk_19A = 0;
+ this->actor.posRot.pos.y = this->unk_234[0].y;
+ Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.posRot.pos, 0x80);
+ this->actionFunc = func_80ADB17C;
+}
+
+// Meg spawning fakes
+void func_80AD9AA8(EnPoSisters* this, GlobalContext* globalCtx) {
+ Actor* actor1 = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.posRot.pos.x,
+ this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, 0, 0, 0x400);
+ Actor* actor2 = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.posRot.pos.x,
+ this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, 0, 0, 0x800);
+ Actor* actor3 = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.posRot.pos.x,
+ this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, 0, 0, 0xC00);
+ s32 pad;
+ s32 pad1;
+
+ if (actor1 == NULL || actor2 == NULL || actor3 == NULL) {
+ if (actor1 != NULL) {
+ Actor_Kill(actor1);
+ }
+ if (actor2 != NULL) {
+ Actor_Kill(actor2);
+ }
+ if (actor3 != NULL) {
+ Actor_Kill(actor3);
+ }
+ Actor_Kill(&this->actor);
+ } else {
+ actor3->parent = &this->actor;
+ actor2->parent = &this->actor;
+ actor1->parent = &this->actor;
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06000680);
+ this->unk_198 = 0;
+ this->unk_199 = 160;
+ this->actionFunc = func_80ADB2B8;
+ }
+}
+
+void func_80AD9C24(EnPoSisters* this, GlobalContext* globalCtx) {
+ Vec3f vec;
+
+ this->actor.draw = NULL;
+ this->actor.flags &= -2;
+ this->unk_19C = 100;
+ this->unk_199 = 32;
+ this->collider.base.type = COLTYPE_UNK3;
+ this->collider.base.acFlags &= ~4;
+ if (globalCtx != NULL) {
+ vec.x = this->actor.posRot.pos.x;
+ vec.y = this->actor.posRot.pos.y + 45.0f;
+ vec.z = this->actor.posRot.pos.z;
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &sZeroVector, &sZeroVector, 150, 0, 255, 255, 255, 155, 150, 150, 150, 1,
+ 9, 0);
+ }
+ Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0);
+ this->actionFunc = func_80ADB338;
+}
+
+void func_80AD9D44(EnPoSisters* this) {
+ if (this->unk_194 == 3) {
+ SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_0600119C);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ } else {
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_0600119C, 0.5f, 0.0f, SkelAnime_GetFrameCount(&D_0600119C), 3, 0.0f);
+ }
+ this->unk_22E.a = 0;
+ this->unk_199 = 32;
+ this->actionFunc = func_80ADB9F0;
+}
+
+void func_80AD9DF0(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_0600119C, -5.0f);
+ this->unk_198 = 1;
+ this->unk_199 &= ~0x80;
+ this->actionFunc = func_80ADB4B0;
+ func_800800F8(globalCtx, 0xC6C, 0x9C, &this->actor, 0);
+}
+
+void func_80AD9E60(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000D40, -3.0f);
+ this->unk_19A = SkelAnime_GetFrameCount(&D_06000D40) * 7 + 7;
+ if (this->actor.parent != NULL) {
+ this->actor.posRot.pos = this->actor.parent->posRot.pos;
+ this->actor.shape.rot.y = this->actor.parent->shape.rot.y;
+ } else {
+ this->actor.shape.rot.y = this->actor.yawTowardsLink;
+ this->unk_19A++;
+ }
+ if (this->unk_195 == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ }
+ this->actionFunc = func_80ADB51C;
+}
+
+void func_80AD9F1C(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000D40, -3.0f);
+ this->unk_22E.a = 255;
+ this->unk_19A = 300;
+ this->unk_19C = 3;
+ this->unk_199 |= 9;
+ this->actor.flags |= 1;
+ this->actionFunc = func_80ADB770;
+}
+
+void func_80AD9F90(EnPoSisters* this) {
+ if (this->unk_194 == 1) {
+ this->actor.initPosRot.pos.x = -632.0f;
+ this->actor.initPosRot.pos.z = -3440.0f;
+ } else {
+ this->actor.initPosRot.pos.x = 752.0f;
+ this->actor.initPosRot.pos.z = -3440.0f;
+ }
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06000D40);
+ this->unk_199 |= 0xA;
+ this->actionFunc = func_80ADBB6C;
+ this->actor.speedXZ = 5.0f;
+}
+
+void func_80ADA028(EnPoSisters* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_060014CC, -3.0f);
+ this->unk_22E.a = 255;
+ this->unk_199 |= 0x15;
+ this->actor.flags |= 1;
+ this->actionFunc = func_80ADBBF4;
+ this->actor.speedXZ = 0.0f;
+}
+
+void func_80ADA094(EnPoSisters* this, GlobalContext* globalCtx) {
+ D_80ADD784 = 0;
+ this->unk_22E.a = 0;
+ this->unk_199 = 128;
+ this->unk_19A = 50;
+ this->unk_234[0] = this->actor.initPosRot.pos;
+ Actor_ChangeType(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORTYPE_PROP);
+ this->actionFunc = func_80ADBC88;
+}
+
+void func_80ADA10C(EnPoSisters* this) {
+ s32 i;
+
+ this->unk_198 = ARRAY_COUNT(this->unk_234);
+ for (i = 0; i < ARRAY_COUNT(this->unk_234); i++) {
+ this->unk_234[i] = this->unk_234[0];
+ }
+ this->actionFunc = func_80ADBD38;
+}
+
+void func_80ADA1B8(EnPoSisters* this) {
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_0600119C, 0.833f, 0.0f, SkelAnime_GetFrameCount(&D_0600119C), 3, 0.0f);
+ if (this->unk_194 == 0 || this->unk_194 == 1) {
+ this->unk_19A = 40;
+ } else {
+ this->unk_19A = 76;
+ }
+ this->unk_198 = 0;
+ D_80ADD784 = 0;
+ this->actionFunc = func_80ADBD8C;
+}
+
+void func_80ADA25C(EnPoSisters* this) {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_060014CC);
+ this->unk_198 = 8;
+ this->unk_19A = 32;
+ func_80AD9240(this, this->unk_19A, &this->actor.initPosRot.pos);
+ this->actionFunc = func_80ADBEE8;
+}
+
+void func_80ADA2BC(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000D40, -3.0f);
+ this->unk_198 = 0;
+ this->unk_199 = 40;
+ this->unk_19A = 90;
+ this->unk_196 = 32;
+ this->actor.posRot.rot.y = D_80ADD79C[this->unk_194];
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ if (this->unk_194 == 0) {
+ Flags_SetSwitch(globalCtx, 0x1B);
+ }
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_FLAME_IGNITION);
+ this->actionFunc = func_80ADBF58;
+}
+
+#ifdef NON_MATCHING
+// Single register swap
+void func_80ADA35C(EnPoSisters* this, GlobalContext* globalCtx) {
+ f32 targetY;
+ Player* player = PLAYER;
+
+ if (this->actionFunc == func_80ADBF58) {
+ targetY = this->actor.initPosRot.pos.y;
+ } else if (this->unk_194 == 0 || this->unk_194 == 3) {
+ targetY = player->actor.posRot.pos.y + 5.0f;
+ } else {
+ targetY = 832.0f;
+ }
+ Math_SmoothScaleMaxF(&this->actor.posRot.pos.y, targetY, 0.5f, 3.0f);
+ if (this->unk_196 == 0) {
+ this->unk_196 = 32;
+ }
+ if (this->unk_196 != 0U) { // U improves codegen from missing move + regalloc to just regalloc
+ this->unk_196 -= 1U;
+ }
+ this->actor.posRot.pos.y += (2.0f + 0.5f * Math_Rand_ZeroOne()) * Math_Sins(this->unk_196 * 0x800);
+ if (this->unk_22E.a == 255 && this->actionFunc != func_80ADA8C0 && this->actionFunc != func_80ADA7F0) {
+ if (this->actionFunc == func_80ADAC70) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG);
+ } else {
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ }
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA35C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA4A8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA530.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA6A0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA7F0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA8C0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADA9E8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADAAA4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADAC70.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADAD54.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADAE6C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADAFC0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB17C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB2B8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB338.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB4B0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB51C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB770.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADB9F0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBB6C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBBF4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBC88.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBD38.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBD8C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBEE8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADBF58.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADC034.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADC10C.s")
-
+#endif
+
+void func_80ADA4A8(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->unk_19A == 0 || this->actor.xzDistFromLink < 200.0f) {
+ func_80AD93C4(this);
+ }
+}
+
+void func_80ADA530(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ Math_ApproxF(&this->actor.speedXZ, 1.0f, 0.2f);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->actor.xzDistFromLink < 200.0f && fabsf(this->actor.yDistFromLink + 5.0f) < 30.0f) {
+ func_80AD943C(this);
+ } else if (this->unk_19A == 0 && Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.2f) != 0) {
+ func_80AD9368(this);
+ }
+ if (this->actor.bgCheckFlags & 8) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, func_8002DAC0(&this->actor, &this->actor.initPosRot.pos),
+ 0x71C);
+ } else if (func_8002DBB0(&this->actor, &this->actor.initPosRot.pos) > 300.0f) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, func_8002DAC0(&this->actor, &this->actor.initPosRot.pos),
+ 0x71C);
+ }
+}
+
+void func_80ADA6A0(EnPoSisters* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ s16 temp_v0;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ temp_v0 = this->actor.yawTowardsLink - player->actor.shape.rot.y;
+ Math_ApproxF(&this->actor.speedXZ, 2.0f, 0.2f);
+ if (temp_v0 > 0x3000) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink + 0x3000, 0x71C);
+ } else if (temp_v0 < -0x3000) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink - 0x3000, 0x71C);
+ } else {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink, 0x71C);
+ }
+ if (this->actor.xzDistFromLink < 160.0f && fabsf(this->actor.yDistFromLink + 5.0f) < 30.0f) {
+ func_80AD944C(this);
+ } else if (this->actor.xzDistFromLink > 240.0f) {
+ func_80AD93C4(this);
+ }
+}
+
+void func_80ADA7F0(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ this->actor.shape.rot.y += 384.0f * ((this->skelAnime.animFrameCount + 1.0f) * 3.0f - this->unk_19A);
+ if (this->unk_19A == 18 || this->unk_19A == 7) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL);
+ }
+ if (this->unk_19A == 0) {
+ func_80AD94E0(this);
+ }
+}
+
+void func_80ADA8C0(EnPoSisters* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ this->actor.shape.rot.y += (384.0f * this->skelAnime.animFrameCount) * 3.0f;
+ if (this->unk_19A == 0 && ABS((s16)(this->actor.shape.rot.y - this->actor.posRot.rot.y)) < 0x1000) {
+ if (this->unk_194 != 0) {
+ this->collider.base.type = COLTYPE_UNK3;
+ this->collider.base.acFlags &= ~4;
+ func_80AD93C4(this);
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ func_80AD9C24(this, globalCtx);
+ }
+ }
+ if (func_800A56C8(&this->skelAnime, 1.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL);
+ }
+}
+
+void func_80ADA9E8(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ this->actor.shape.rot.y -= (this->actor.speedXZ * 10.0f) * 128.0f;
+ if (Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.1f) != 0) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ if (this->unk_194 != 0) {
+ func_80AD93C4(this);
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ func_80AD9C24(this, globalCtx);
+ }
+ }
+}
+
+void func_80ADAAA4(EnPoSisters* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime) && !(this->actor.flags & 0x8000)) {
+ if (this->actor.colChkInfo.health != 0) {
+ if (this->unk_194 != 0) {
+ func_80AD96A4(this);
+ } else if (this->unk_195 != 0) {
+ func_80AD9C24(this, NULL);
+ } else {
+ func_80AD9C24(this, globalCtx);
+ }
+ } else {
+ func_80AD99D4(this, globalCtx);
+ }
+ }
+ if (this->unk_195 != 0) {
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, this->actor.parent->shape.rot.y,
+ (this->unk_195 == 2) ? 0x800 : 0x400);
+ this->unk_22E.a = ((this->skelAnime.animFrameCount - this->skelAnime.animCurrentFrame) * 255.0f) /
+ this->skelAnime.animFrameCount;
+ this->actor.posRot.pos.y = this->actor.parent->posRot.pos.y;
+ func_80AD97C8(this, globalCtx);
+ } else if (this->unk_194 != 0) {
+ Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.5f);
+ }
+}
+
+void func_80ADAC70(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink + 0x8000, 1820);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->actor.bgCheckFlags & 8) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ this->unk_199 |= 2;
+ func_80AD9718(this);
+ } else if (this->unk_19A == 0 && 240.0f < this->actor.xzDistFromLink) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ func_80AD93C4(this);
+ }
+}
+
+void func_80ADAD54(EnPoSisters* this, GlobalContext* globalCtx) {
+ s32 animFrameCount;
+
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->unk_22E.a = 0;
+ this->collider.body.bumper.flags = 0x60001;
+ func_80AD93C4(this);
+ } else {
+ animFrameCount = this->skelAnime.animFrameCount;
+ this->unk_22E.a = ((animFrameCount - this->skelAnime.animCurrentFrame) * 255.0f) / animFrameCount;
+ }
+}
+
+void func_80ADAE6C(EnPoSisters* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->unk_22E.a = 255;
+ if (this->unk_194 != 0) {
+ this->unk_199 |= 1;
+ this->collider.body.bumper.flags = 0x4FC7FFEA;
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->unk_19A == 0) {
+ this->unk_197 = 20;
+ func_80AD93C4(this);
+ }
+ } else {
+ func_80AD9F1C(this);
+ }
+ } else {
+ this->unk_22E.a = (this->skelAnime.animCurrentFrame * 255.0f) / this->skelAnime.animFrameCount;
+ if (this->unk_194 == 0) {
+ func_80AD97C8(this, globalCtx);
+ }
+ }
+}
+
+void func_80ADAFC0(EnPoSisters* this, GlobalContext* globalCtx) {
+ s32 i;
+
+ this->unk_19A++;
+ this->unk_198 = CLAMP_MAX(this->unk_198 + 1, 8);
+ for (i = this->unk_198 - 1; i > 0; i--) {
+ this->unk_234[i] = this->unk_234[i - 1];
+ }
+ this->unk_234[0].x =
+ (Math_Sins((this->actor.shape.rot.y + this->unk_19A * 0x3000) - 0x4000) * (3000.0f * this->actor.scale.x)) +
+ this->actor.posRot.pos.x;
+ this->unk_234[0].z =
+ (Math_Coss((this->actor.shape.rot.y + this->unk_19A * 0x3000) - 0x4000) * (3000.0f * this->actor.scale.x)) +
+ this->actor.posRot.pos.z;
+ if (this->unk_19A < 8) {
+ this->unk_234[0].y = this->unk_234[1].y - 9.0f;
+ } else {
+ this->unk_234[0].y = this->unk_234[1].y + 2.0f;
+ if (this->unk_19A >= 16) {
+ if (Math_ApproxF(&this->actor.scale.x, 0.0f, 0.001f) != 0) {
+ func_80AD9A54(this, globalCtx);
+ }
+ this->actor.scale.z = this->actor.scale.x;
+ this->actor.scale.y = this->actor.scale.x;
+ }
+ }
+ if (this->unk_19A == 16) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD2);
+ }
+}
+
+void func_80ADB17C(EnPoSisters* this, GlobalContext* globalCtx) {
+ Vec3s* vec;
+
+ this->unk_19A++;
+ if (this->unk_19A == 64) {
+ Flags_SetSwitch(globalCtx, this->actor.params);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 30, NA_SE_EV_FLAME_IGNITION);
+ if (this->unk_194 == 0) {
+ Flags_UnsetSwitch(globalCtx, 0x1B);
+ }
+ globalCtx->envCtx.unk_BF = 0xFF;
+ func_80078884(NA_SE_SY_CORRECT_CHIME);
+ Actor_Kill(&this->actor);
+ } else if (this->unk_19A < 32) {
+ func_80AD9240(this, this->unk_19A, &this->actor.posRot.pos);
+ } else {
+ func_80AD9240(this, 64 - this->unk_19A, &this->actor.posRot.pos);
+ }
+ if (this->unk_19A == 32) {
+ vec = &D_80ADD7A4[this->unk_194];
+ this->actor.posRot.pos.x = vec->x;
+ this->actor.posRot.pos.y = vec->y;
+ this->actor.posRot.pos.z = vec->z;
+ }
+}
+
+void func_80ADB2B8(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->actor.xzDistFromLink < 130.0f) {
+ func_80AD9DF0(this, globalCtx);
+ }
+ if (func_800A56C8(&this->skelAnime, 0.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_CRY);
+ }
+ this->actor.shape.rot.y = this->actor.yawTowardsLink;
+}
+
+void func_80ADB338(EnPoSisters* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
+ EnPoSisters* realMeg = (EnPoSisters*)this->actor.parent;
+
+ if (this->unk_195 == 0) {
+ if (func_8002DBB0(&player->actor, &this->actor.initPosRot.pos) < 600.0f) {
+ if (this->unk_19C != 0) {
+ this->unk_19C--;
+ }
+ } else {
+ this->unk_19C = 100;
+ }
+ if (this->unk_19C == 0) {
+ this->actor.shape.rot.y = (s32)(4.0f * Math_Rand_ZeroOne()) * 0x4000 + this->actor.yawTowardsLink;
+ this->actor.posRot.pos.y = player->actor.posRot.pos.y + 5.0f;
+ func_80AD98F4(this, globalCtx);
+ }
+ } else {
+ if (realMeg->actionFunc == func_80ADB51C) {
+ this->actor.draw = EnPoSisters_Draw;
+ func_80AD9E60(this);
+ } else if (realMeg->actionFunc == func_80ADAE6C) {
+ this->actor.shape.rot.y = this->actor.parent->shape.rot.y + this->unk_195 * 0x4000;
+ this->actor.posRot.pos.y = player->actor.posRot.pos.y + 5.0f;
+ func_80AD98F4(this, globalCtx);
+ } else if (realMeg->actionFunc == func_80ADAFC0) {
+ Actor_Kill(&this->actor);
+ }
+ }
+}
+
+void func_80ADB4B0(EnPoSisters* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ func_80AD9E60(this);
+ }
+ func_80AD97C8(this, globalCtx);
+ this->actor.posRot.pos.y += 1.0f;
+ Actor_SetHeight(&this->actor, 40.0f);
+}
+
+void func_80ADB51C(EnPoSisters* this, GlobalContext* globalCtx) {
+ f32 temp_f2;
+ s16 phi_v0;
+ s16 phi_a2;
+ u8 temp;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ temp_f2 = this->skelAnime.animFrameCount * 0.5f;
+ this->unk_22E.a = (fabsf(temp_f2 - this->skelAnime.animCurrentFrame) * 255.0f) / temp_f2;
+ if (this->unk_19A != 0) {
+ this->unk_19A -= 1;
+ }
+ if (this->unk_19A == 0) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y += 0x4000 * (s32)(Math_Rand_ZeroOne() * 4.0f);
+ if (this->unk_195 == 0) {
+ func_800F5ACC(0x38);
+ }
+ func_80AD9F1C(this);
+ } else {
+ this->actor.posRot.pos.y += 0.1f;
+ temp = this->unk_195;
+ if (temp != 0) {
+ if (this->unk_19A > 90) {
+ phi_v0 = 1;
+ phi_a2 = 64;
+ } else if (this->unk_19A > 70) {
+ phi_v0 = 0;
+ phi_a2 = 64;
+ } else if (this->unk_19A > 55) {
+ phi_v0 = 1;
+ phi_a2 = 96;
+ } else if (this->unk_19A > 40) {
+ phi_v0 = 0;
+ phi_a2 = 96;
+ } else {
+ phi_v0 = 1;
+ phi_a2 = 256;
+ }
+ if (this->unk_195 == 2) {
+ phi_a2 *= 2;
+ }
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y,
+ this->actor.parent->shape.rot.y + (this->unk_195 * 0x4000) * phi_v0, phi_a2);
+ } else if (this->unk_19A == 70 || this->unk_19A == 40) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ }
+ }
+ func_80AD97C8(this, globalCtx);
+ Actor_SetHeight(&this->actor, 40.0f);
+}
+
+void func_80ADB770(EnPoSisters* this, GlobalContext* globalCtx) {
+ s32 temp_v0;
+ s32 phi_a0;
+
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->unk_19C > 0) {
+ if (this->unk_19A >= 16) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->unk_195 == 0) {
+ if (ABS((s16)(16 - this->unk_196)) < 14) {
+ this->actor.shape.rot.y +=
+ (0x580 - (this->unk_19C * 0x180)) * fabsf(Math_Sins(this->unk_196 * 0x800));
+ }
+ if (this->unk_19A >= 284 || this->unk_19A < 31) {
+ this->unk_199 |= 0x40;
+ } else {
+ this->unk_199 &= ~0x40;
+ }
+ } else {
+ this->actor.shape.rot.y = (s16)(this->actor.parent->shape.rot.y + (this->unk_195 * 0x4000));
+ }
+ }
+ }
+ if (this->unk_195 == 0) {
+ if (this->unk_19A >= 284 || (this->unk_19A < 31 && this->unk_19A >= 16)) {
+ this->unk_199 |= 0x40;
+ } else {
+ this->unk_199 &= ~0x40;
+ }
+ }
+ if (func_8002DBB0(&PLAYER->actor, &this->actor.initPosRot.pos) > 600.0f) {
+ this->unk_199 &= ~0x40;
+ func_80AD9C24(this, globalCtx);
+ } else if (this->unk_19A == 0) {
+ if (this->unk_195 == 0) {
+ func_80AD94E0(this);
+ } else {
+ func_80AD9C24(this, globalCtx);
+ }
+ } else if (this->unk_195 != 0) {
+ EnPoSisters* realMeg = (EnPoSisters*)this->actor.parent;
+ if (realMeg->actionFunc == func_80ADAAA4) {
+ func_80AD95D8(this);
+ }
+ } else if (this->unk_19C == 0) {
+ this->unk_19C = -15;
+ } else if (this->unk_19C < 0) {
+ this->unk_19C++;
+ if (this->unk_19C == 0) {
+ func_80AD94E0(this);
+ }
+ }
+ func_80AD97C8(this, globalCtx);
+}
+
+void func_80ADB9F0(EnPoSisters* this, GlobalContext* globalCtx) {
+ f32 div;
+
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->unk_22E.a = 255;
+ if (this->unk_194 == 3) {
+ this->actor.flags |= 1;
+ this->actor.initPosRot.pos.x = 1992.0f;
+ this->actor.initPosRot.pos.z = -1440.0f;
+ this->unk_199 |= 0x18;
+ func_80AD93C4(this);
+ } else {
+ func_80AD9F90(this);
+ }
+ } else {
+ div = this->skelAnime.animCurrentFrame / this->skelAnime.animFrameCount;
+ this->unk_22E.a = 255.0f * div;
+ }
+ if (this->unk_194 != 3 && func_800A56C8(&this->skelAnime, 1.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ }
+ Actor_SetHeight(&this->actor, 40.0f);
+}
+
+void func_80ADBB6C(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (func_8002DBB0(&this->actor, &this->actor.initPosRot.pos) < 10.0f) {
+ func_80ADA028(this);
+ } else {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, func_8002DAC0(&this->actor, &this->actor.initPosRot.pos),
+ 1820);
+ }
+}
+
+void func_80ADBBF4(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink, 1820);
+ if (this->actor.xzDistFromLink < 240.0f && fabsf(this->actor.yDistFromLink + 5.0f) < 30.0f) {
+ func_80AD93C4(this);
+ }
+}
+
+void func_80ADBC88(EnPoSisters* this, GlobalContext* globalCtx) {
+ if (D_80ADD784 != 0 || !Player_InCsMode(globalCtx)) {
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ if (this->unk_19A == 30) {
+ if (this->unk_194 == 0) {
+ func_800800F8(globalCtx, 0xC44, 0x3E7, NULL, 0);
+ }
+ D_80ADD784 = 1;
+ }
+ if (this->unk_19A == 0) {
+ func_80ADA10C(this);
+ }
+ }
+ func_8002F974(&this->actor, NA_SE_EV_TORCH - SFX_FLAG);
+}
+
+void func_80ADBD38(EnPoSisters* this, GlobalContext* globalCtx) {
+ this->unk_19A++;
+ func_80AD9240(this, this->unk_19A, &this->actor.initPosRot.pos);
+ if (this->unk_19A == 32) {
+ func_80ADA1B8(this);
+ }
+}
+
+void func_80ADBD8C(EnPoSisters* this, GlobalContext* globalCtx) {
+ this->unk_19A--;
+ if (this->unk_19A == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ this->unk_199 &= ~0x80;
+ }
+ if (this->unk_19A <= 0) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->unk_22E.a = 255;
+ D_80ADD784 |= (1 << this->unk_194);
+ } else {
+ this->unk_22E.a = (this->skelAnime.animCurrentFrame * 255.0f) / this->skelAnime.animFrameCount;
+ }
+ }
+ if (D_80ADD784 == 15) {
+ func_80ADA25C(this);
+ }
+}
+
+void func_80ADBEE8(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
+ func_80AD9240(this, this->unk_19A, &this->actor.initPosRot.pos);
+ if (this->unk_19A == 0) {
+ func_80ADA2BC(this, globalCtx);
+ }
+}
+
+void func_80ADBF58(EnPoSisters* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ this->unk_19A--;
+ Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, this->actor.posRot.rot.y, 0x500);
+ if (this->unk_19A == 0 && this->unk_194 == 0) {
+ globalCtx->envCtx.unk_BF = 4;
+ }
+ if (this->unk_19A < 0) {
+ Math_ApproxF(&this->actor.speedXZ, 5.0f, 0.2f);
+ }
+ if (this->unk_19A == -70 && this->unk_194 == 1) {
+ Audio_PlaySoundAtPosition(globalCtx, &D_80ADD7BC, 40, NA_SE_EN_PO_LAUGH);
+ }
+ if (this->unk_19A < -120) {
+ Actor_Kill(&this->actor);
+ }
+}
+
+void func_80ADC034(EnPoSisters* this, GlobalContext* globalCtx) {
+ if (this->actor.unk_10C != 0 && this->unk_22E.a == 255) {
+ if (this->unk_197 != 0) {
+ this->unk_197--;
+ }
+ } else {
+ this->unk_197 = 20;
+ }
+ if (this->unk_22E.a == 0) {
+ if (this->unk_19C != 0) {
+ this->unk_19C--;
+ }
+ }
+ if (this->actionFunc != func_80ADA7F0 && this->actionFunc != func_80ADA8C0 && this->actionFunc != func_80ADAAA4) {
+ if (this->unk_197 == 0) {
+ func_80AD9718(this);
+ } else if (this->unk_19C == 0 && this->unk_22E.a == 0) {
+ func_80AD98F4(this, globalCtx);
+ }
+ }
+}
+
+void func_80ADC10C(EnPoSisters* this, GlobalContext* globalCtx) {
+ Vec3f sp24;
+
+ if (this->collider.base.acFlags & 2) {
+ this->collider.base.acFlags &= ~2;
+ func_80035650(&this->actor, &this->collider.body, 1);
+ if (this->unk_195 != 0) {
+ ((EnPoSisters*)this->actor.parent)->unk_19C--;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH2);
+ func_80AD9C24(this, globalCtx);
+ if (Math_Rand_ZeroOne() < 0.2f) {
+ sp24.x = this->actor.posRot.pos.x;
+ sp24.y = this->actor.posRot.pos.y;
+ sp24.z = this->actor.posRot.pos.z;
+ Item_DropCollectible(globalCtx, &sp24, ITEM00_ARROWS_SMALL);
+ }
+ } else if (this->collider.base.type == 9 ||
+ (this->actor.colChkInfo.damageEffect == 0 && this->actor.colChkInfo.damage == 0)) {
+ if (this->unk_194 == 0) {
+ this->actor.freezeTimer = 0;
+ }
+ } else if (this->actor.colChkInfo.damageEffect == 0xF) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ this->unk_199 |= 2;
+ func_80AD98F4(this, globalCtx);
+ } else if (this->unk_194 == 0 && this->actor.colChkInfo.damageEffect == 0xE &&
+ this->actionFunc == func_80ADB770) {
+ if (this->unk_19C == 0) {
+ this->unk_19C = -45;
+ }
+ } else {
+ if (Actor_ApplyDamage(&this->actor) != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE);
+ } else {
+ func_80032C7C(globalCtx, &this->actor);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_SISTER_DEAD);
+ }
+ func_80AD95D8(this);
+ }
+ }
+}
+
+#ifdef NON_MATCHING
+// Stack only
+void EnPoSisters_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoSisters* this = THIS;
+ s32 pad;
+
+ if (this->collider.base.atFlags & 2) {
+ this->collider.base.atFlags &= ~2;
+ func_80AD9568(this);
+ }
+ func_80ADC10C(this, globalCtx);
+ if (this->unk_199 & 4) {
+ func_80ADC034(this, globalCtx);
+ }
+ this->actionFunc(this, globalCtx);
+ if (this->unk_199 & 0x1F) {
+ if (this->unk_199 & 8) {
+ func_80ADA35C(this, globalCtx);
+ }
+ Actor_MoveForward(&this->actor);
+ if (this->unk_199 & 0x10) {
+ func_8002E4B4(globalCtx, &this->actor, 20.0f, 20.0f, 0.0f, 5);
+ } else {
+ Vec3f vec;
+ UNK_TYPE sp34;
+ vec.x = this->actor.posRot.pos.x;
+ vec.y = this->actor.posRot.pos.y + 10.0f;
+ vec.z = this->actor.posRot.pos.z;
+ this->actor.groundY = func_8003C9A4(&globalCtx->colCtx, &this->actor.floorPoly, &sp34, &this->actor, &vec);
+ }
+ Collider_CylinderUpdate(&this->actor, &this->collider);
+ if (this->actionFunc == func_80ADA8C0 || this->actionFunc == func_80ADA7F0) {
+ this->unk_198++;
+ this->unk_198 = CLAMP_MAX(this->unk_198, 8);
+ } else if (this->actionFunc != func_80ADAFC0) {
+ this->unk_198 = CLAMP_MIN((s16)(this->unk_198 - 1), 1);
+ }
+ if (this->actionFunc == func_80ADA8C0) {
+ this->actor.flags |= 0x01000000;
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ if (this->unk_199 & 1) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ if (this->actionFunc != func_80ADB338) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ Actor_SetHeight(&this->actor, 40.0f);
+ if (this->actionFunc == func_80ADAC70) {
+ this->actor.shape.rot.y = this->actor.posRot.rot.y + 0x8000;
+ } else if (this->unk_199 & 2) {
+ this->actor.shape.rot.y = this->actor.posRot.rot.y;
+ }
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/EnPoSisters_Update.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADC55C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADC77C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/func_80ADC970.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Sisters/EnPoSisters_Draw.s")
+#endif
+
+void func_80ADC55C(EnPoSisters* this) {
+ s16 temp_var;
+
+ if (this->skelAnime.animation == &D_06000114) {
+ this->unk_22E.r = CLAMP_MAX((s16)(this->unk_22E.r + 5), 255);
+ this->unk_22E.g = CLAMP_MIN((s16)(this->unk_22E.g - 5), 50);
+ temp_var = this->unk_22E.b - 5;
+ this->unk_22E.b = CLAMP_MIN(temp_var, 0);
+ } else if (this->skelAnime.animation == &D_06000A54) {
+ this->unk_22E.r = CLAMP_MAX((s16)(this->unk_22E.r + 5), 80);
+ this->unk_22E.g = CLAMP_MAX((s16)(this->unk_22E.g + 5), 255);
+ temp_var = this->unk_22E.b + 5;
+ this->unk_22E.b = CLAMP_MAX(temp_var, 225);
+ } else if (this->skelAnime.animation == &D_060008C0) {
+ if (this->actor.dmgEffectTimer & 2) {
+ this->unk_22E.r = 0;
+ this->unk_22E.g = 0;
+ this->unk_22E.b = 0;
+ } else {
+ this->unk_22E.r = 80;
+ this->unk_22E.g = 255;
+ this->unk_22E.b = 225;
+ }
+ } else {
+ this->unk_22E.r = CLAMP_MAX((s16)(this->unk_22E.r + 5), 255);
+ this->unk_22E.g = CLAMP_MAX((s16)(this->unk_22E.g + 5), 255);
+ if (this->unk_22E.b > 210) {
+ temp_var = this->unk_22E.b - 5;
+ this->unk_22E.b = CLAMP_MIN(temp_var, 210);
+ } else {
+ temp_var = this->unk_22E.b + 5;
+ this->unk_22E.b = CLAMP_MAX(temp_var, 210);
+ }
+ }
+}
+
+s32 EnPoSisters_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ void* thisx, Gfx** gfxP) {
+ EnPoSisters* this = THIS;
+ Color_RGBA8* color;
+
+ if (limbIndex == 1 && (this->unk_199 & 0x40)) {
+ if (this->unk_19A >= 284) {
+ rot->x += (this->unk_19A * 0x1000) + 0xFFEE4000;
+ } else {
+ rot->x += (this->unk_19A * 0x1000) + 0xFFFF1000;
+ }
+ }
+ if (this->unk_22E.a == 0 || limbIndex == 8 || (this->actionFunc == func_80ADAFC0 && this->unk_19A >= 8)) {
+ *dList = NULL;
+ } else if (limbIndex == 9) {
+ *dList = D_80ADD7C8[this->unk_194];
+ } else if (limbIndex == 10) {
+ *dList = D_80ADD7D8[this->unk_194];
+ gDPPipeSync((*gfxP)++);
+ gDPSetEnvColor((*gfxP)++, this->unk_22E.r, this->unk_22E.g, this->unk_22E.b, this->unk_22E.a);
+ } else if (limbIndex == 11) {
+ color = &D_80ADD7E8[this->unk_194];
+ gDPPipeSync((*gfxP)++);
+ gDPSetEnvColor((*gfxP)++, color->r, color->g, color->b, this->unk_22E.a);
+ }
+ return 0;
+}
+
+void EnPoSisters_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx,
+ Gfx** gfxP) {
+ EnPoSisters* this = THIS;
+ s32 i;
+ s32 pad;
+
+ if (this->actionFunc == func_80ADAFC0 && this->unk_19A >= 8 && limbIndex == 9) {
+ gSPMatrix((*gfxP)++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_sisters.c", 2876),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList((*gfxP)++, D_060046E0);
+ }
+ if (limbIndex == 8 && this->actionFunc != func_80ADB2B8) {
+ if (this->unk_199 & 0x20) {
+ for (i = this->unk_198 - 1; i > 0; i--) {
+ this->unk_234[i] = this->unk_234[i - 1];
+ }
+ Matrix_MultVec3f(&D_80ADD7F8, &this->unk_234[0]);
+ } else if (this->actionFunc == func_80ADBD8C) {
+ Matrix_MultVec3f(&D_80ADD7F8, &this->actor.initPosRot.pos);
+ }
+ if (this->unk_198 > 0) {
+ Color_RGBA8* color = &D_80ADD6F0[this->unk_194];
+ f32 temp_f2 = Math_Rand_ZeroOne() * 0.3f + 0.7f;
+
+ if (this->actionFunc == func_80ADB17C || this->actionFunc == func_80ADBD38 ||
+ this->actionFunc == func_80ADBEE8) {
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->unk_234[0].x, this->unk_234[0].y + 15.0f,
+ this->unk_234[0].z, color->r * temp_f2, color->g * temp_f2,
+ color->b * temp_f2, 200);
+ } else {
+ Lights_PointGlowSetInfo(&this->lightInfo, this->unk_234[0].x, this->unk_234[0].y + 15.0f,
+ this->unk_234[0].z, color->r * temp_f2, color->g * temp_f2, color->b * temp_f2,
+ 200);
+ }
+ } else {
+ Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0);
+ }
+ if (!(this->unk_199 & 0x80)) {
+ Matrix_Get(&this->unk_2F8);
+ }
+ }
+}
+
+void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoSisters* this = THIS;
+ u8 phi_s5;
+ f32 phi_f20;
+ s32 i;
+ u8 spE7;
+ Color_RGBA8* temp_s1 = &D_80ADD700[this->unk_194];
+ Color_RGBA8* temp_s7 = &D_80ADD6F0[this->unk_194];
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_po_sisters.c", 2989);
+ func_80ADC55C(this);
+ func_80093D18(globalCtx->state.gfxCtx);
+ func_80093D84(globalCtx->state.gfxCtx);
+ if (this->unk_22E.a == 255 || this->unk_22E.a == 0) {
+ gDPSetEnvColor(POLY_OPA_DISP++, this->unk_22E.r, this->unk_22E.g, this->unk_22E.b, this->unk_22E.a);
+ gSPSegment(POLY_OPA_DISP++, 0x09, D_80116280 + 2);
+ POLY_OPA_DISP =
+ SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_OPA_DISP);
+ } else {
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->unk_22E.a);
+ gSPSegment(POLY_XLU_DISP++, 0x09, D_80116280);
+ POLY_XLU_DISP =
+ SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_XLU_DISP);
+ }
+ if (!(this->unk_199 & 0x80)) {
+ Matrix_Put(&this->unk_2F8);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_sisters.c", 3034),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, D_060027B0);
+ }
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0,
+ (globalCtx->gameplayFrames * -20) % 512, 0x20, 0x80));
+ gDPSetEnvColor(POLY_XLU_DISP++, temp_s1->r, temp_s1->g, temp_s1->b, temp_s1->a);
+ if (this->actionFunc == func_80ADB17C) {
+ if (this->unk_19A < 32) {
+ phi_s5 = ((32 - this->unk_19A) * 255) / 32;
+ phi_f20 = 0.0056000003f;
+ } else {
+ phi_s5 = (this->unk_19A * 255 - 8160) / 32;
+ phi_f20 = 0.0027f;
+ }
+ } else if (this->actionFunc == func_80ADBD38) {
+ phi_s5 = ((32 - this->unk_19A) * 255) / 32;
+ phi_f20 = 0.0027f;
+ } else if (this->actionFunc == func_80ADBEE8) {
+ phi_s5 = ((32 - this->unk_19A) * 255) / 32;
+ phi_f20 = 0.0035f;
+ } else if (this->actionFunc == func_80ADBC88) {
+ //! @bug uninitialised spE7
+ phi_s5 = spE7;
+ phi_f20 = 0.0027f;
+ } else {
+ phi_s5 = spE7;
+ phi_f20 = this->actor.scale.x * 0.5f;
+ }
+ for (i = 0; i < this->unk_198; i++) {
+ if (this->actionFunc != func_80ADB17C && this->actionFunc != func_80ADBD38 &&
+ this->actionFunc != func_80ADBEE8) {
+ phi_s5 = -i * 31 + 248;
+ }
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, temp_s7->r, temp_s7->g, temp_s7->b, phi_s5);
+ Matrix_Translate(this->unk_234[i].x, this->unk_234[i].y, this->unk_234[i].z, MTXMODE_NEW);
+ Matrix_RotateRPY(0, (s16)(func_8005A9F4(ACTIVE_CAM) + 0x8000), 0, MTXMODE_APPLY);
+ if (this->actionFunc == func_80ADAFC0) {
+ phi_f20 = (this->unk_19A - i) * 0.025f + 0.5f;
+ phi_f20 = CLAMP(phi_f20, 0.5f, 0.8f) * 0.007f;
+ }
+ Matrix_Scale(phi_f20, phi_f20, phi_f20, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_po_sisters.c", 3132),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, D_0404D4E0);
+ }
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_po_sisters.c", 3139);
+}
diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h
index ca00287df..3ce5d6e9d 100644
--- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h
+++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h
@@ -6,9 +6,29 @@
struct EnPoSisters;
+typedef void (*EnPoSistersActionFunc)(struct EnPoSisters*, GlobalContext*);
+
typedef struct EnPoSisters {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x1EC];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ EnPoSistersActionFunc actionFunc;
+ /* 0x0194 */ u8 unk_194;
+ /* 0x0195 */ u8 unk_195;
+ /* 0x0196 */ u8 unk_196;
+ /* 0x0197 */ u8 unk_197;
+ /* 0x0198 */ u8 unk_198;
+ /* 0x0199 */ u8 unk_199;
+ /* 0x019A */ s16 unk_19A;
+ /* 0x019A */ s16 unk_19C;
+ /* 0x019E */ Vec3s limbDrawTable[12];
+ /* 0x01E6 */ Vec3s transitionDrawTable[12];
+ /* 0x022E */ Color_RGBA8 unk_22E;
+ /* 0x0234 */ Vec3f unk_234[8];
+ /* 0x0294 */ f32 unk_294;
+ /* 0x0298 */ LightNode* lightNode;
+ /* 0x029C */ LightInfo lightInfo;
+ /* 0x02AC */ ColliderCylinder collider;
+ /* 0x02F8 */ MtxF unk_2F8;
} EnPoSisters; // size = 0x0338
extern const ActorInit En_Po_Sisters_InitVars;
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
index 5703de7eb..100ad8259 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
@@ -1,3 +1,9 @@
+/*
+ * File: z_en_poh.c
+ * Overlay: ovl_En_Poh
+ * Description: Graveyard Poe
+ */
+
#include "z_en_poh.h"
#define FLAGS 0x00001015
@@ -8,7 +14,34 @@ void EnPoh_Init(Actor* thisx, GlobalContext* globalCtx);
void EnPoh_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnPoh_UpdateLiving(Actor* thisx, GlobalContext* globalCtx);
+void EnPoh_UpdateDead(Actor* thisx, GlobalContext* globalCtx);
+void EnPoh_DrawRegular(Actor* thisx, GlobalContext* globalCtx);
+void EnPoh_DrawComposer(Actor* thisx, GlobalContext* globalCtx);
+void EnPoh_DrawSoul(Actor* thisx, GlobalContext* globalCtx);
+
+void func_80ADEAC4(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_Idle(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADEC9C(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_Attack(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADEECC(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADF894(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_ComposerAppear(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADEF38(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADF15C(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADF574(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADF5E0(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_Disappear(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_Appear(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_Death(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADFE28(EnPoh* this, GlobalContext* globalCtx);
+void func_80ADFE80(EnPoh* this, GlobalContext* globalCtx);
+void func_80AE009C(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_TalkRegular(EnPoh* this, GlobalContext* globalCtx);
+void EnPoh_TalkComposer(EnPoh* this, GlobalContext* globalCtx);
+
+static s16 D_80AE1A50 = 0;
+
const ActorInit En_Poh_InitVars = {
ACTOR_EN_POH,
ACTORTYPE_ENEMY,
@@ -20,111 +53,1099 @@ const ActorInit En_Poh_InitVars = {
(ActorFunc)EnPoh_Update,
NULL,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/EnPoh_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/EnPoh_Destroy.s")
+static ColliderCylinderInit sCylinderInit = {
+ { COLTYPE_UNK3, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
+ { 20, 40, 20, { 0, 0, 0 } },
+};
+
+static ColliderJntSphItemInit D_80AE1AA0[] = {
+ {
+ { 0x00, { 0xFFCFFFFF, 0x00, 0x08 }, { 0x00000000, 0x00, 0x00 }, 0x01, 0x00, 0x01 },
+ { 18, { { 0, 1400, 0 }, 10 }, 100 },
+ },
+};
+
+static ColliderJntSphInit sJntSphInit = { { COLTYPE_UNK3, 0x11, 0x09, 0x39, 0x10, COLSHAPE_JNTSPH }, 1, D_80AE1AA0 };
+
+static CollisionCheckInfoInit sColChkInfoInit = { 0x04, 0x0019, 0x0032, 0x28 };
+
+static DamageTable sDamageTable = {
+ 0x00, 0x02, 0x01, 0x02, 0x11, 0x02, 0x02, 0x12, 0x01, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x02, 0x08, 0x04, 0x00, 0x00, 0x04, 0x00,
+};
+
+static EnPohInfo sPoeInfo[2] = {
+ {
+ { 255, 170, 255 },
+ { 100, 0, 150 },
+ 18,
+ 5,
+ 248,
+ 0x060015B0,
+ 0x06000A60,
+ 0x060004EC,
+ 0x060006E0,
+ 0x06002D28,
+ 0x06002608,
+ 0x06003850,
+ },
+ {
+ { 255, 255, 170 },
+ { 0, 150, 0 },
+ 9,
+ 1,
+ 244,
+ 0x06001440,
+ 0x060009DC,
+ 0x06000570,
+ 0x06000708,
+ 0x060045A0,
+ 0x06005220,
+ 0x06001C90,
+ },
+};
+
+static Color_RGBA8 D_80AE1B4C = { 75, 20, 25, 255 };
+static Color_RGBA8 D_80AE1B50 = { 80, 110, 90, 255 };
+static Color_RGBA8 D_80AE1B54 = { 90, 85, 50, 255 };
+static Color_RGBA8 D_80AE1B58 = { 100, 90, 100, 255 };
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32(unk_4C, 3200, ICHAIN_STOP),
+};
+
+static Vec3f D_80AE1B60 = { 0.0f, 3.0f, 0.0f };
+static Vec3f D_80AE1B6C = { 0.0f, 0.0f, 0.0f };
+
+extern FlexSkeletonHeader D_06006F90;
+extern AnimationHeader D_060009DC;
+extern SkeletonHeader D_060050D0;
+extern AnimationHeader D_06000A60;
+
+extern AnimationHeader D_060001A8;
+extern AnimationHeader D_0600020C;
+extern AnimationHeader D_060004EC;
+extern AnimationHeader D_06000570;
+extern AnimationHeader D_06000FE4;
+extern AnimationHeader D_060011C4;
+
+extern Gfx D_06004638[];
+
+extern Gfx D_06004498[];
+extern Gfx D_06004530[];
+
+void EnPoh_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnItem00* collectible;
+ EnPoh* this = THIS;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 30.0f);
+ Collider_InitJntSph(globalCtx, &this->colliderSph);
+ Collider_SetJntSph(globalCtx, &this->colliderSph, &this->actor, &sJntSphInit, &this->colliderSphItem);
+ this->colliderSph.list[0].dim.worldSphere.radius = 0;
+ this->colliderSph.list[0].dim.worldSphere.center.x = this->actor.posRot.pos.x;
+ this->colliderSph.list[0].dim.worldSphere.center.y = this->actor.posRot.pos.y;
+ this->colliderSph.list[0].dim.worldSphere.center.z = this->actor.posRot.pos.z;
+ Collider_InitCylinder(globalCtx, &this->colliderCyl);
+ Collider_SetCylinder(globalCtx, &this->colliderCyl, &this->actor, &sCylinderInit);
+ func_80061ED4(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+ this->unk_194 = 0;
+ this->unk_195 = 32;
+ this->visibilityTimer = Math_Rand_S16Offset(700, 300);
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ Lights_PointGlowSetInfo(&this->lightInfo, this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
+ this->actor.initPosRot.pos.z, 255, 255, 255, 0);
+ if (this->actor.params >= 4) {
+ this->actor.params = EN_POH_NORMAL;
+ }
+ if (this->actor.params == EN_POH_RUPEE) {
+ D_80AE1A50++;
+ if (D_80AE1A50 >= 3) {
+ Actor_Kill(&this->actor);
+ } else {
+ collectible = Item_DropCollectible(globalCtx, &this->actor.posRot.pos, 0x4000 | ITEM00_RUPEE_BLUE);
+ if (collectible != NULL) {
+ collectible->actor.speedXZ = 0.0f;
+ }
+ }
+ } else if (this->actor.params == EN_POH_FLAT) {
+ if (Flags_GetSwitch(globalCtx, 0x28) || Flags_GetSwitch(globalCtx, 0x9)) {
+ Actor_Kill(&this->actor);
+ } else {
+ Flags_SetSwitch(globalCtx, 0x28);
+ }
+ } else if (this->actor.params == EN_POH_SHARP) {
+ if (Flags_GetSwitch(globalCtx, 0x29) || Flags_GetSwitch(globalCtx, 0x9)) {
+ Actor_Kill(&this->actor);
+ } else {
+ Flags_SetSwitch(globalCtx, 0x29);
+ }
+ }
+ if (this->actor.params < EN_POH_SHARP) {
+ this->objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_POH);
+ this->infoIdx = EN_POH_INFO_NORMAL;
+ this->actor.naviEnemyId = 0x44;
+ } else {
+ this->objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_PO_COMPOSER);
+ this->infoIdx = EN_POH_INFO_COMPOSER;
+ this->actor.naviEnemyId = 0x43;
+ }
+ this->info = &sPoeInfo[this->infoIdx];
+ if (this->objectIdx < 0) {
+ Actor_Kill(&this->actor);
+ }
+}
+
+void EnPoh_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
+
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ Collider_DestroyJntSph(globalCtx, &this->colliderSph);
+ Collider_DestroyCylinder(globalCtx, &this->colliderCyl);
+ if (this->actor.params == EN_POH_RUPEE) {
+ D_80AE1A50--;
+ }
+}
+
+void func_80ADE114(EnPoh* this) {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, this->info->unk_C);
+ this->unk_198 = Math_Rand_S16Offset(2, 3);
+ this->actionFunc = func_80ADEAC4;
+ this->actor.speedXZ = 0.0f;
+}
+
+void EnPoh_SetupIdle(EnPoh* this) {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, this->info->unk_10);
+ this->unk_198 = Math_Rand_S16Offset(15, 3);
+ this->actionFunc = EnPoh_Idle;
+}
+
+void func_80ADE1BC(EnPoh* this) {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, this->info->unk_10);
+ this->actionFunc = func_80ADEC9C;
+ this->unk_198 = 0;
+ this->actor.speedXZ = 2.0f;
+}
+
+void EnPoh_SetupAttack(EnPoh* this) {
+ if (this->infoIdx == EN_POH_INFO_NORMAL) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_060001A8, -6.0f);
+ } else {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_0600020C);
+ }
+ this->unk_198 = 12;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actionFunc = EnPoh_Attack;
+}
+
+void func_80ADE28C(EnPoh* this) {
+ if (this->infoIdx == EN_POH_INFO_NORMAL) {
+ SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_060004EC, -6.0f);
+ } else {
+ SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06000570);
+ }
+ if (this->colliderCyl.body.acHitItem->toucher.flags & 0x0001F824) {
+ this->actor.posRot.rot.y = this->colliderCyl.base.ac->posRot.rot.y;
+ } else {
+ this->actor.posRot.rot.y = func_8002DA78(&this->actor, this->colliderCyl.base.ac) + 0x8000;
+ }
+ this->colliderCyl.base.acFlags &= ~1;
+ this->actor.speedXZ = 5.0f;
+ func_8003426C(&this->actor, 0x4000, 0xFF, 0, 0x10);
+ this->actionFunc = func_80ADEECC;
+}
+
+void func_80ADE368(EnPoh* this) {
+ SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, this->info->unk_18, -5.0f);
+ this->actor.speedXZ = 5.0f;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y + 0x8000;
+ this->colliderCyl.base.acFlags |= 1;
+ this->unk_198 = 200;
+ this->actionFunc = func_80ADF894;
+}
+
+void EnPoh_SetupInitialAction(EnPoh* this) {
+ this->lightColor.a = 0;
+ this->actor.flags &= ~1;
+ if (this->infoIdx == EN_POH_INFO_NORMAL) {
+ SkelAnime_ChangeAnimPlaybackStop(&this->skelAnime, &D_060011C4, 0.0f);
+ this->actionFunc = func_80ADEF38;
+ } else {
+ SkelAnime_ChangeAnimPlaybackStop(&this->skelAnime, &D_06000FE4, 1.0f);
+ this->actor.posRot.pos.y = this->actor.initPosRot.pos.y + 20.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ this->actionFunc = EnPoh_ComposerAppear;
+ }
+}
+
+void func_80ADE48C(EnPoh* this) {
+ this->actor.speedXZ = 0.0f;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ this->unk_198 = 0;
+ this->actor.naviEnemyId = 0xFF;
+ this->actor.flags &= ~1;
+ this->actionFunc = func_80ADF15C;
+}
+
+void func_80ADE4C8(EnPoh* this) {
+ SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, this->info->unk_10);
+ this->actionFunc = func_80ADF574;
+ this->actor.speedXZ = -5.0f;
+}
+
+void func_80ADE514(EnPoh* this) {
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, this->info->unk_C);
+ this->unk_19C = this->actor.posRot.rot.y + 0x8000;
+ this->actionFunc = func_80ADF5E0;
+ this->actor.speedXZ = 0.0f;
+}
+
+void EnPoh_SetupDisappear(EnPoh* this) {
+ this->unk_194 = 32;
+ this->actor.speedXZ = 0.0f;
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actionFunc = EnPoh_Disappear;
+}
+
+void EnPoh_SetupAppear(EnPoh* this) {
+ this->unk_194 = 0;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ this->actionFunc = EnPoh_Appear;
+}
+
+void EnPoh_SetupDeath(EnPoh* this, GlobalContext* globalCtx) {
+ this->actor.update = EnPoh_UpdateDead;
+ this->actor.draw = EnPoh_DrawSoul;
+ this->actor.shape.shadowDrawFunc = NULL;
+ Actor_SetScale(&this->actor, 0.01f);
+ this->actor.flags |= 0x10;
+ this->actor.gravity = -1.0f;
+ this->actor.shape.unk_08 = 1500.0f;
+ this->actor.posRot.pos.y -= 15.0f;
+ if (this->infoIdx != EN_POH_INFO_COMPOSER) {
+ this->actor.shape.rot.x = -0x8000;
+ }
+ Actor_ChangeType(globalCtx, &globalCtx->actorCtx, &this->actor, 8);
+ this->unk_198 = 60;
+ this->actionFunc = EnPoh_Death;
+}
+
+void func_80ADE6D4(EnPoh* this) {
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, 0, 0, 0, 0);
+ this->visibilityTimer = 0;
+ this->actor.shape.rot.y = 0;
+ this->lightColor.r = 0;
+ this->lightColor.a = 0;
+ this->actor.shape.unk_08 = 0.0f;
+ this->actor.gravity = 0.0f;
+ this->actor.velocity.y = 0.0f;
+ if (this->actor.params >= EN_POH_SHARP) {
+ this->lightColor.g = 200;
+ this->lightColor.b = 0;
+ } else {
+ this->lightColor.g = 0;
+ this->lightColor.b = 200;
+ }
+ this->actor.scale.x = 0.0f;
+ this->actor.scale.y = 0.0f;
+ this->actor.shape.rot.x = 0;
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND);
+ this->actionFunc = func_80ADFE28;
+}
+
+void EnPoh_Talk(EnPoh* this, GlobalContext* globalCtx) {
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y;
+ Actor_SetHeight(&this->actor, -10.0f);
+ this->colliderCyl.dim.radius = 13;
+ this->colliderCyl.dim.height = 30;
+ this->colliderCyl.dim.yShift = 0;
+ this->colliderCyl.dim.pos.x = this->actor.posRot.pos.x;
+ this->colliderCyl.dim.pos.y = this->actor.posRot.pos.y - 20.0f;
+ this->colliderCyl.dim.pos.z = this->actor.posRot.pos.z;
+ this->colliderCyl.base.maskA = 9;
+ if (this->actor.params == EN_POH_FLAT || this->actor.params == EN_POH_SHARP) {
+ if (CHECK_QUEST_ITEM(QUEST_SONG_SUN)) {
+ this->actor.textId = 0x5000;
+ } else if (!Flags_GetSwitch(globalCtx, 0xA) && !Flags_GetSwitch(globalCtx, 0xB)) {
+ this->actor.textId = 0x500F;
+ } else if ((this->actor.params == EN_POH_FLAT && Flags_GetSwitch(globalCtx, 0xA)) ||
+ (this->actor.params == EN_POH_SHARP && Flags_GetSwitch(globalCtx, 0xB))) {
+ this->actor.textId = 0x5013;
+ } else {
+ this->actor.textId = 0x5012;
+ }
+ } else {
+ this->actor.textId = 0x5005;
+ }
+ this->unk_198 = 200;
+ this->unk_195 = 32;
+ this->actor.flags |= 1;
+ this->actionFunc = func_80ADFE80;
+}
+
+void func_80ADE950(EnPoh* this, s32 arg1) {
+ if (arg1) {
+ func_800F8A44(&this->actor.projectedPos, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ }
+ this->actionFunc = func_80AE009C;
+}
+
+void func_80ADE998(EnPoh* this) {
+ this->actionFunc = EnPoh_TalkRegular;
+ this->actor.initPosRot.pos.y = this->actor.posRot.pos.y - 15.0f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE114.s")
+void func_80ADE9BC(EnPoh* this) {
+ this->actionFunc = EnPoh_TalkComposer;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE16C.s")
+void EnPoh_MoveTowardsPlayerHeight(EnPoh* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE1BC.s")
+ Math_ApproxF(&this->actor.posRot.pos.y, player->actor.posRot.pos.y, 1.0f);
+ this->actor.posRot.pos.y += 2.5f * Math_Sins(this->unk_195 * 0x800);
+ if (this->unk_195 != 0) {
+ this->unk_195 -= 1;
+ }
+ if (this->unk_195 == 0) {
+ this->unk_195 = 32;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE20C.s")
+void func_80ADEA5C(EnPoh* this) {
+ if (func_8002DBB0(&this->actor, &this->actor.initPosRot.pos) > 400.0f) {
+ this->unk_19C = func_8002DAC0(&this->actor, &this->actor.initPosRot.pos);
+ }
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->unk_19C, 0x71C);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE28C.s")
+void func_80ADEAC4(EnPoh* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ if (this->actor.xzDistFromLink < 200.0f) {
+ func_80ADE1BC(this);
+ } else if (this->unk_198 == 0) {
+ EnPoh_SetupIdle(this);
+ }
+ if (this->lightColor.a == 255) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE368.s")
+void EnPoh_Idle(EnPoh* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ Math_ApproxF(&this->actor.speedXZ, 1.0f, 0.2f);
+ if (func_800A56C8(&this->skelAnime, 0.0f) && this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ func_80ADEA5C(this);
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ if (this->actor.xzDistFromLink < 200.0f && this->unk_198 < 19) {
+ func_80ADE1BC(this);
+ } else if (this->unk_198 == 0) {
+ if (Math_Rand_ZeroOne() < 0.1f) {
+ func_80ADE514(this);
+ } else {
+ func_80ADE114(this);
+ }
+ }
+ if (this->lightColor.a == 255) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE3DC.s")
+void func_80ADEC9C(EnPoh* this, GlobalContext* globalCtx) {
+ Player* player;
+ s16 facingDiff;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE48C.s")
+ player = PLAYER;
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ facingDiff = this->actor.yawTowardsLink - player->actor.shape.rot.y;
+ if (facingDiff >= 0x3001) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink + 0x3000, 0x71C);
+ } else if (facingDiff < -0x3000) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink - 0x3000, 0x71C);
+ } else {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink, 0x71C);
+ }
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ if (this->actor.xzDistFromLink > 280.0f) {
+ EnPoh_SetupIdle(this);
+ } else if (this->unk_198 == 0 && this->actor.xzDistFromLink < 140.0f &&
+ func_8002DFC8(&this->actor, 0x2AAA, globalCtx) == 0) {
+ EnPoh_SetupAttack(this);
+ }
+ if (this->lightColor.a == 255) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE4C8.s")
+void EnPoh_Attack(EnPoh* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (func_800A56C8(&this->skelAnime, 0.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_KANTERA);
+ if (this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ }
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ if (this->unk_198 >= 10) {
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink, 0xE38);
+ } else if (this->unk_198 == 9) {
+ this->actor.speedXZ = 5.0f;
+ this->skelAnime.animPlaybackSpeed = 2.0f;
+ } else if (this->unk_198 == 0) {
+ EnPoh_SetupIdle(this);
+ this->unk_198 = 23;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE514.s")
+void func_80ADEECC(EnPoh* this, GlobalContext* globalCtx) {
+ Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.5f);
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ if (this->actor.colChkInfo.health != 0) {
+ func_80ADE368(this);
+ } else {
+ func_80ADE48C(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE56C.s")
+void func_80ADEF38(EnPoh* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->lightColor.a = 255;
+ this->visibilityTimer = Math_Rand_S16Offset(700, 300);
+ this->actor.flags |= 1;
+ EnPoh_SetupIdle(this);
+ } else if (this->skelAnime.animCurrentFrame > 10.0f) {
+ this->lightColor.a = ((this->skelAnime.animCurrentFrame - 10.0f) * 0.05f) * 255.0f;
+ }
+ if (this->skelAnime.animPlaybackSpeed < 0.5f && this->actor.xzDistFromLink < 280.0f) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_APPEAR);
+ this->skelAnime.animPlaybackSpeed = 1.0f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE5C4.s")
+void EnPoh_ComposerAppear(EnPoh* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->lightColor.a = 255;
+ this->visibilityTimer = Math_Rand_S16Offset(700, 300);
+ this->actor.flags |= 1;
+ EnPoh_SetupIdle(this);
+ } else {
+ this->lightColor.a = CLAMP_MAX((s32)(this->skelAnime.animCurrentFrame * 25.5f), 255);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE610.s")
+void func_80ADF15C(EnPoh* this, GlobalContext* globalCtx) {
+ Vec3f vec;
+ f32 multiplier;
+ f32 newScale;
+ s32 pad;
+ s32 pad1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE6D4.s")
+ this->unk_198++;
+ if (this->unk_198 < 8) {
+ if (this->unk_198 < 5) {
+ vec.y = Math_Sins((this->unk_198 * 0x1000) - 0x4000) * 23.0f + (this->actor.posRot.pos.y + 40.0f);
+ multiplier = Math_Coss((this->unk_198 * 0x1000) - 0x4000) * 23.0f;
+ vec.x = Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * multiplier + this->actor.posRot.pos.x;
+ vec.z = Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * multiplier + this->actor.posRot.pos.z;
+ } else {
+ vec.y = (this->actor.posRot.pos.y + 40.0f) + (15.0f * (this->unk_198 - 5));
+ vec.x = Math_Sins(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f + this->actor.posRot.pos.x;
+ vec.z = Math_Coss(func_8005A9F4(ACTIVE_CAM) + 0x4800) * 23.0f + this->actor.posRot.pos.z;
+ }
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AE1B60, &D_80AE1B6C, this->unk_198 * 10 + 80, 0, 255, 255, 255, 255,
+ 0, 0, 255, 1, 9, 1);
+ vec.x = (this->actor.posRot.pos.x + this->actor.posRot.pos.x) - vec.x;
+ vec.z = (this->actor.posRot.pos.z + this->actor.posRot.pos.z) - vec.z;
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AE1B60, &D_80AE1B6C, this->unk_198 * 10 + 80, 0, 255, 255, 255, 255,
+ 0, 0, 255, 1, 9, 1);
+ vec.x = this->actor.posRot.pos.x;
+ vec.z = this->actor.posRot.pos.z;
+ EffectSsDeadDb_Spawn(globalCtx, &vec, &D_80AE1B60, &D_80AE1B6C, this->unk_198 * 10 + 80, 0, 255, 255, 255, 255,
+ 0, 0, 255, 1, 9, 1);
+ if (this->unk_198 == 1) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_EXTINCT);
+ }
+ } else if (this->unk_198 == 28) {
+ EnPoh_SetupDeath(this, globalCtx);
+ } else if (this->unk_198 >= 19) {
+ newScale = (28 - this->unk_198) * 0.001f;
+ this->actor.posRot.pos.y += 5.0f;
+ this->actor.scale.z = newScale;
+ this->actor.scale.y = newScale;
+ this->actor.scale.x = newScale;
+ }
+ if (this->unk_198 == 18) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD2);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE7C0.s")
+void func_80ADF574(EnPoh* this, GlobalContext* globalCtx) {
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ EnPoh_SetupIdle(this);
+ this->unk_198 = 23;
+ } else {
+ Math_ApproxF(&this->actor.speedXZ, 0.0f, 0.5f);
+ this->actor.shape.rot.y += 0x1000;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE950.s")
+void func_80ADF5E0(EnPoh* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->unk_19C, 1820) != 0) {
+ EnPoh_SetupIdle(this);
+ }
+ if (this->actor.xzDistFromLink < 200.0f) {
+ func_80ADE1BC(this);
+ }
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE998.s")
+void EnPoh_Disappear(EnPoh* this, GlobalContext* globalCtx) {
+ if (this->unk_194 != 0) {
+ this->unk_194--;
+ }
+ this->actor.posRot.rot.y += 0x1000;
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ this->lightColor.a = this->unk_194 * 7.96875f;
+ if (this->unk_194 == 0) {
+ this->visibilityTimer = Math_Rand_S16Offset(100, 50);
+ EnPoh_SetupIdle(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE9BC.s")
+void EnPoh_Appear(EnPoh* this, GlobalContext* globalCtx) {
+ this->unk_194++;
+ this->actor.posRot.rot.y -= 0x1000;
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ this->lightColor.a = this->unk_194 * 7.96875f;
+ if (this->unk_194 == 32) {
+ this->visibilityTimer = Math_Rand_S16Offset(700, 300);
+ this->unk_194 = 0;
+ EnPoh_SetupIdle(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADE9CC.s")
+void func_80ADF894(EnPoh* this, GlobalContext* globalCtx) {
+ f32 multiplier;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEA5C.s")
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ multiplier = Math_Sins(this->unk_195 * 0x800) * 3.0f;
+ this->actor.posRot.pos.x -= multiplier * Math_Coss(this->actor.shape.rot.y);
+ this->actor.posRot.pos.z += multiplier * Math_Sins(this->actor.shape.rot.y);
+ Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, this->actor.yawTowardsLink + 0x8000, 0x71C);
+ EnPoh_MoveTowardsPlayerHeight(this, globalCtx);
+ if (this->unk_198 == 0 || this->actor.xzDistFromLink > 250.0f) {
+ this->actor.posRot.rot.y = this->actor.shape.rot.y;
+ EnPoh_SetupIdle(this);
+ }
+ func_8002F974(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEAC4.s")
+void EnPoh_Death(EnPoh* this, GlobalContext* globalCtx) {
+ s32 objId;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEB80.s")
+ if (this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ if (this->actor.bgCheckFlags & 1) {
+ objId = (this->infoIdx == EN_POH_INFO_COMPOSER) ? OBJECT_PO_COMPOSER : OBJECT_POH;
+ EffectSsHahen_SpawnBurst(globalCtx, &this->actor.posRot.pos, 6.0f, 0, 1, 1, 15, objId, 10, this->info->unk_1C);
+ func_80ADE6D4(this);
+ } else if (this->unk_198 == 0) {
+ Actor_Kill(&this->actor);
+ return;
+ }
+ Actor_MoveForward(&this->actor);
+ func_8002E4B4(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 4);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEC9C.s")
+void func_80ADFA90(EnPoh* this, s32 arg1) {
+ f32 multiplier;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEDFC.s")
+ this->lightColor.a = CLAMP(this->lightColor.a + arg1, 0, 255);
+ if (arg1 < 0) {
+ multiplier = this->lightColor.a * 0.003921569f;
+ this->actor.scale.z = 0.0056000002f * multiplier + 0.00140000006f;
+ this->actor.scale.x = 0.0056000002f * multiplier + 0.00140000006f;
+ this->actor.scale.y = (0.007f - 0.007f * multiplier) + 0.007f;
+ } else {
+ multiplier = 1.0f;
+ this->actor.scale.z = this->lightColor.a * 2.7450982e-05f;
+ this->actor.scale.y = this->lightColor.a * 2.7450982e-05f;
+ this->actor.scale.x = this->lightColor.a * 2.7450982e-05f;
+ this->actor.posRot.pos.y = this->actor.initPosRot.pos.y + 0.05882353f * this->lightColor.a;
+ }
+ this->lightColor.r = this->info->lightColor.r * multiplier;
+ this->lightColor.g = this->info->lightColor.g * multiplier;
+ this->lightColor.b = this->info->lightColor.b * multiplier;
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, this->info->lightColor.r, this->info->lightColor.g,
+ this->info->lightColor.b, this->lightColor.a * 0.78431373f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEECC.s")
+void func_80ADFE28(EnPoh* this, GlobalContext* globalCtx) {
+ this->actor.initPosRot.pos.y += 2.0f;
+ func_80ADFA90(this, 20);
+ if (this->lightColor.a == 255) {
+ EnPoh_Talk(this, globalCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADEF38.s")
+void func_80ADFE80(EnPoh* this, GlobalContext* globalCtx) {
+ if (this->unk_198 != 0) {
+ this->unk_198--;
+ }
+ if (func_8002F194(&this->actor, globalCtx) != 0) {
+ if (this->actor.params >= EN_POH_SHARP) {
+ func_80ADE9BC(this);
+ } else {
+ func_80ADE998(this);
+ }
+ return;
+ }
+ if (this->unk_198 == 0) {
+ func_80ADE950(this, 1);
+ this->actor.flags &= ~0x10000;
+ return;
+ }
+ if (this->colliderCyl.base.maskA & 2) {
+ this->actor.flags |= 0x10000;
+ func_8002F2F4(&this->actor, globalCtx);
+ } else {
+ this->actor.flags &= ~0x10000;
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCyl.base);
+ }
+ this->actor.posRot.pos.y = Math_Sins(this->unk_195 * 0x800) * 5.0f + this->actor.initPosRot.pos.y;
+ if (this->unk_195 != 0) {
+ this->unk_195 -= 1;
+ }
+ if (this->unk_195 == 0) {
+ this->unk_195 = 32;
+ }
+ this->colliderCyl.dim.pos.y = this->actor.posRot.pos.y - 20.0f;
+ Actor_SetHeight(&this->actor, -10.0f);
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, this->info->lightColor.r, this->info->lightColor.g,
+ this->info->lightColor.b, this->lightColor.a * 0.78431373f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF0B8.s")
+void func_80AE009C(EnPoh* this, GlobalContext* globalCtx) {
+ func_80ADFA90(this, -13);
+ if (this->lightColor.a == 0) {
+ Actor_Kill(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF15C.s")
+void EnPoh_TalkRegular(EnPoh* this, GlobalContext* globalCtx) {
+ if (this->actor.textId != 0x5005) {
+ func_80ADFA90(this, -13);
+ } else {
+ func_8002F974(&this->actor, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ }
+ if (func_8010BDBC(&globalCtx->msgCtx) == 4) {
+ if (func_80106BC8(globalCtx) != 0) {
+ func_800F8A44(&this->actor.projectedPos, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ if (Inventory_HasEmptyBottle()) {
+ this->actor.textId = 0x5008;
+ Item_Give(globalCtx, ITEM_POE);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_BIG_GET);
+ } else {
+ this->actor.textId = 0x5006;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ }
+ } else {
+ this->actor.textId = 0x5007;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH);
+ }
+ func_8010B720(globalCtx, this->actor.textId);
+ }
+ } else if (func_8002F334(&this->actor, globalCtx) != 0) {
+ func_80ADE950(this, 0);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF574.s")
+void EnPoh_TalkComposer(EnPoh* this, GlobalContext* globalCtx) {
+ func_8002F974(&this->actor, NA_SE_EN_PO_BIG_CRY - SFX_FLAG);
+ if (func_8010BDBC(&globalCtx->msgCtx) == 4) {
+ if (func_80106BC8(globalCtx) != 0) {
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ if (!Flags_GetSwitch(globalCtx, 0xB) && !Flags_GetSwitch(globalCtx, 0xA)) {
+ this->actor.textId = 0x5010;
+ } else {
+ this->actor.textId = 0x5014;
+ }
+ func_8010B720(globalCtx, this->actor.textId);
+ } else {
+ if (this->actor.params == EN_POH_SHARP) {
+ Flags_SetSwitch(globalCtx, 0xB);
+ } else {
+ Flags_SetSwitch(globalCtx, 0xA);
+ }
+ func_80ADE950(this, 1);
+ }
+ }
+ } else if (func_8002F334(&this->actor, globalCtx) != 0) {
+ if (this->actor.textId == 0x5000) {
+ Flags_SetSwitch(globalCtx, 9);
+ }
+ func_80ADE950(this, 1);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF5E0.s")
+void func_80AE032C(EnPoh* this, GlobalContext* globalCtx) {
+ if (this->colliderCyl.base.acFlags & 2) {
+ this->colliderCyl.base.acFlags &= ~2;
+ if (this->actor.colChkInfo.damageEffect != 0 || this->actor.colChkInfo.damage != 0) {
+ if (Actor_ApplyDamage(&this->actor) == 0) {
+ func_80032C7C(globalCtx, &this->actor);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD);
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE);
+ }
+ func_80ADE28C(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF660.s")
+void EnPoh_UpdateVisibility(EnPoh* this) {
+ if (this->actionFunc != EnPoh_Appear && this->actionFunc != EnPoh_Disappear && this->actionFunc != func_80ADEF38 &&
+ this->actionFunc != EnPoh_ComposerAppear) {
+ if (this->visibilityTimer != 0) {
+ this->visibilityTimer--;
+ }
+ if (this->lightColor.a == 255) {
+ if (this->actor.unk_10C != 0) {
+ this->unk_194++;
+ this->unk_194 = CLAMP_MAX(this->unk_194, 20);
+ } else {
+ this->unk_194 = 0;
+ }
+ if ((this->unk_194 == 20 || this->visibilityTimer == 0) &&
+ (this->actionFunc == func_80ADEAC4 || this->actionFunc == EnPoh_Idle ||
+ this->actionFunc == func_80ADEC9C || this->actionFunc == func_80ADF894 ||
+ this->actionFunc == func_80ADF5E0)) {
+ EnPoh_SetupDisappear(this);
+ }
+ } else if (this->lightColor.a == 0 && this->visibilityTimer == 0 &&
+ (this->actionFunc == func_80ADEAC4 || this->actionFunc == EnPoh_Idle ||
+ this->actionFunc == func_80ADEC9C || this->actionFunc == func_80ADF5E0)) {
+ EnPoh_SetupAppear(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF77C.s")
+void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF894.s")
+ if (Object_IsLoaded(&globalCtx->objectCtx, this->objectIdx) != 0) {
+ this->actor.objBankIndex = this->objectIdx;
+ this->actor.update = EnPoh_UpdateLiving;
+ Actor_SetObjectDependency(globalCtx, &this->actor);
+ if (this->infoIdx == EN_POH_INFO_NORMAL) {
+ SkelAnime_Init(globalCtx, &this->skelAnime, &D_060050D0, &D_06000A60, this->limbDrawTable,
+ this->transitionDrawTable, 21);
+ this->actor.draw = EnPoh_DrawRegular;
+ } else {
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06006F90, &D_060009DC, this->limbDrawTable,
+ this->transitionDrawTable, 12);
+ this->actor.draw = EnPoh_DrawComposer;
+ this->colliderSph.list[0].dim.joint = 9;
+ this->colliderSph.list->dim.modelSphere.center.y *= -1;
+ this->actor.shape.rot.y = this->actor.posRot.rot.y = -0x4000;
+ this->colliderCyl.dim.radius = 20;
+ this->colliderCyl.dim.height = 55;
+ this->colliderCyl.dim.yShift = 15;
+ }
+ this->actor.flags &= ~0x10;
+ EnPoh_SetupInitialAction(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADF994.s")
+void func_80AE067C(EnPoh* this) {
+ s16 temp_var;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADFA90.s")
+ if (this->actionFunc == EnPoh_Attack) {
+ this->lightColor.r = CLAMP_MAX((s16)(this->lightColor.r + 5), 255);
+ this->lightColor.g = CLAMP_MIN((s16)(this->lightColor.g - 5), 50);
+ temp_var = this->lightColor.b - 5;
+ this->lightColor.b = CLAMP_MIN(temp_var, 0);
+ } else if (this->actionFunc == func_80ADF894) {
+ this->lightColor.r = CLAMP_MAX((s16)(this->lightColor.r + 5), 80);
+ this->lightColor.g = CLAMP_MAX((s16)(this->lightColor.g + 5), 255);
+ temp_var = this->lightColor.b + 5;
+ this->lightColor.b = CLAMP_MAX(temp_var, 225);
+ } else if (this->actionFunc == func_80ADEECC) {
+ if (this->actor.dmgEffectTimer & 2) {
+ this->lightColor.r = 0;
+ this->lightColor.g = 0;
+ this->lightColor.b = 0;
+ } else {
+ this->lightColor.r = 80;
+ this->lightColor.g = 255;
+ this->lightColor.b = 225;
+ }
+ } else {
+ this->lightColor.r = CLAMP_MAX((s16)(this->lightColor.r + 5), 255);
+ this->lightColor.g = CLAMP_MAX((s16)(this->lightColor.g + 5), 255);
+ if (this->lightColor.b >= 211) {
+ temp_var = this->lightColor.b - 5;
+ this->lightColor.b = CLAMP_MIN(temp_var, 210);
+ } else {
+ temp_var = this->lightColor.b + 5;
+ this->lightColor.b = CLAMP_MAX(temp_var, 210);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADFE28.s")
+void func_80AE089C(EnPoh* this) {
+ f32 rand;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80ADFE80.s")
+ if ((this->actionFunc == func_80ADEF38 || this->actionFunc == EnPoh_ComposerAppear) &&
+ this->skelAnime.animCurrentFrame < 12.0f) {
+ this->envColor.r = this->envColor.g = this->envColor.b = (s16)(this->skelAnime.animCurrentFrame * 16.66f) + 55;
+ this->envColor.a = this->skelAnime.animCurrentFrame * 16.666666f;
+ } else {
+ rand = Math_Rand_ZeroOne();
+ this->envColor.r = (s16)(rand * 30.0f) + 225;
+ this->envColor.g = (s16)(rand * 100.0f) + 155;
+ this->envColor.b = (s16)(rand * 160.0f) + 95;
+ this->envColor.a = 200;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE009C.s")
+void EnPoh_UpdateLiving(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
+ s32 pad;
+ Vec3f vec;
+ UNK_TYPE sp38;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE00DC.s")
+ if (this->colliderSph.base.atFlags & 2) {
+ this->colliderSph.base.atFlags &= ~2;
+ func_80ADE4C8(this);
+ }
+ func_80AE032C(this, globalCtx);
+ EnPoh_UpdateVisibility(this);
+ this->actionFunc(this, globalCtx);
+ Actor_MoveForward(&this->actor);
+ if (this->actionFunc == EnPoh_Attack && this->unk_198 < 10) {
+ this->actor.flags |= 0x1000000;
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSph.base);
+ }
+ Collider_CylinderUpdate(&this->actor, &this->colliderCyl);
+ if ((this->colliderCyl.base.acFlags & 1) && this->lightColor.a == 255) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCyl.base);
+ }
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCyl.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSph.base);
+ Actor_SetHeight(&this->actor, 42.0f);
+ if (this->actionFunc != func_80ADEECC && this->actionFunc != func_80ADF574) {
+ if (this->actionFunc == func_80ADF894) {
+ this->actor.shape.rot.y = this->actor.posRot.rot.y + 0x8000;
+ } else {
+ this->actor.shape.rot.y = this->actor.posRot.rot.y;
+ }
+ }
+ vec.x = this->actor.posRot.pos.x;
+ vec.y = this->actor.posRot.pos.y + 20.0f;
+ vec.z = this->actor.posRot.pos.z;
+ this->actor.groundY = func_8003C9A4(&globalCtx->colCtx, &this->actor.floorPoly, &sp38, &this->actor, &vec);
+ func_80AE089C(this);
+ this->actor.shape.unk_14 = this->lightColor.a;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE0204.s")
+s32 EnPoh_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx,
+ Gfx** gfxP) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE032C.s")
+ if ((this->lightColor.a == 0 || limbIndex == this->info->unk_6) ||
+ (this->actionFunc == func_80ADF15C && this->unk_198 >= 2)) {
+ *dList = NULL;
+ } else if (this->actor.params == EN_POH_FLAT && limbIndex == 0xA) {
+ *dList = D_06004638;
+ }
+ if (limbIndex == 0x13 && this->infoIdx == EN_POH_INFO_NORMAL) {
+ gDPPipeSync((*gfxP)++);
+ gDPSetEnvColor((*gfxP)++, this->lightColor.r, this->lightColor.g, this->lightColor.b, this->lightColor.a);
+ }
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE03C4.s")
+void EnPoh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfxP) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/EnPoh_Update.s")
+ func_800628A4(limbIndex, &this->colliderSph);
+ if (this->actionFunc == func_80ADF15C && this->unk_198 >= 2 && limbIndex == this->info->unk_7) {
+ gSPMatrix((*gfxP)++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_poh.c", 2460),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList((*gfxP)++, this->info->unk_20);
+ }
+ if (limbIndex == this->info->unk_6) {
+ if (this->actionFunc == func_80ADF15C && this->unk_198 >= 19 && 0.0f != this->actor.scale.x) {
+ f32 mtxScale = 0.01f / this->actor.scale.x;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ }
+ Matrix_Get(&this->unk_368);
+ if (this->actionFunc == func_80ADF15C && this->unk_198 == 27) {
+ this->actor.posRot.pos.x = this->unk_368.wx;
+ this->actor.posRot.pos.y = this->unk_368.wy;
+ this->actor.posRot.pos.z = this->unk_368.wz;
+ }
+ Lights_PointGlowSetInfo(&this->lightInfo, this->colliderSph.list[0].dim.worldSphere.center.x,
+ this->colliderSph.list[0].dim.worldSphere.center.y,
+ this->colliderSph.list[0].dim.worldSphere.center.z, this->envColor.r, this->envColor.g,
+ this->envColor.b, this->envColor.a * 0.78431374f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE067C.s")
+void EnPoh_DrawRegular(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE089C.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2629);
+ func_80AE067C(this);
+ func_80093D18(globalCtx->state.gfxCtx);
+ func_80093D84(globalCtx->state.gfxCtx);
+ if (this->lightColor.a == 255 || this->lightColor.a == 0) {
+ gDPSetEnvColor(POLY_OPA_DISP++, this->lightColor.r, this->lightColor.g, this->lightColor.b, this->lightColor.a);
+ gSPSegment(POLY_OPA_DISP++, 0x08, D_80116280 + 2);
+ POLY_OPA_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw, &this->actor, POLY_OPA_DISP);
+ } else {
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->lightColor.a);
+ gSPSegment(POLY_XLU_DISP++, 0x08, D_80116280);
+ POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw, &this->actor, POLY_XLU_DISP);
+ }
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->envColor.r, this->envColor.g, this->envColor.b, 255);
+ Matrix_Put(&this->unk_368);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_poh.c", 2676),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, this->info->unk_1C);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2681);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE0A1C.s")
+void EnPoh_DrawComposer(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
+ Color_RGBA8* sp90;
+ Color_RGBA8* phi_t0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE0BF8.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2694);
+ func_80AE067C(this);
+ if (this->actor.params == EN_POH_SHARP) {
+ sp90 = &D_80AE1B4C;
+ phi_t0 = &D_80AE1B54;
+ } else {
+ sp90 = &D_80AE1B50;
+ phi_t0 = &D_80AE1B58;
+ }
+ if (this->lightColor.a == 255 || this->lightColor.a == 0) {
+ func_80093D18(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x08,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
+ this->lightColor.a));
+ gSPSegment(POLY_OPA_DISP++, 0x0A,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, sp90->r, sp90->g, sp90->b, this->lightColor.a));
+ gSPSegment(POLY_OPA_DISP++, 0x0B,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, phi_t0->r, phi_t0->g, phi_t0->b, this->lightColor.a));
+ gSPSegment(POLY_OPA_DISP++, 0x0C, D_80116280 + 2);
+ POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ this->skelAnime.dListCount, EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw,
+ &this->actor, POLY_OPA_DISP);
+ } else {
+ func_80093D18(globalCtx->state.gfxCtx);
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
+ this->lightColor.a));
+ gSPSegment(POLY_XLU_DISP++, 0x0A,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, sp90->r, sp90->g, sp90->b, this->lightColor.a));
+ gSPSegment(POLY_XLU_DISP++, 0x0B,
+ Gfx_EnvColor(globalCtx->state.gfxCtx, phi_t0->r, phi_t0->g, phi_t0->b, this->lightColor.a));
+ gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280);
+ POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
+ this->skelAnime.dListCount, EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw,
+ &this->actor, POLY_XLU_DISP);
+ }
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->envColor.r, this->envColor.g, this->envColor.b, 255);
+ Matrix_Put(&this->unk_368);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_poh.c", 2787),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, this->info->unk_1C);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004498);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, sp90->r, sp90->g, sp90->b, 255);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004530);
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2802);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE0CE8.s")
+void EnPoh_UpdateDead(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE0EE4.s")
+ this->actionFunc(this, globalCtx);
+ if (this->actionFunc != EnPoh_Death) {
+ this->visibilityTimer++;
+ }
+ func_80AE089C(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE1148.s")
+void EnPoh_DrawSoul(Actor* thisx, GlobalContext* globalCtx) {
+ EnPoh* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE1600.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2833);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Poh/func_80AE1654.s")
+ if (this->actionFunc == EnPoh_Death) {
+ func_80093D18(globalCtx->state.gfxCtx);
+ gDPSetEnvColor(POLY_OPA_DISP++, this->envColor.r, this->envColor.g, this->envColor.b, 255);
+ Lights_PointGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z, this->envColor.r, this->envColor.g, this->envColor.b, 200);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_poh.c", 2854),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, this->info->unk_1C);
+ if (this->infoIdx == EN_POH_INFO_COMPOSER) {
+ Color_RGBA8* envColor = (this->actor.params == EN_POH_SHARP) ? &D_80AE1B4C : &D_80AE1B50;
+ s32 pad;
+ gSPDisplayList(POLY_OPA_DISP++, D_06004498);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, envColor->r, envColor->g, envColor->b, 255);
+ gSPDisplayList(POLY_OPA_DISP++, D_06004530);
+ }
+ } else {
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0,
+ (this->visibilityTimer * this->info->unk_8) % 512U, 0x20, 0x80));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, this->info->primColor.r, this->info->primColor.g,
+ this->info->primColor.b, this->lightColor.a);
+ gDPSetEnvColor(POLY_XLU_DISP++, this->lightColor.r, this->lightColor.g, this->lightColor.b, 255);
+ Matrix_RotateY((s16)(func_8005A9F4(ACTIVE_CAM) + 0x8000) * 9.58738e-05f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_poh.c", 2910),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, this->info->soulDisplayList);
+ }
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_poh.c", 2916);
+}
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
index f3b50339f..7ee1ee042 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.h
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
@@ -6,9 +6,57 @@
struct EnPoh;
+typedef void (*EnPohActionFunc)(struct EnPoh*, GlobalContext*);
+
+typedef enum {
+ EN_POH_NORMAL,
+ EN_POH_RUPEE,
+ EN_POH_SHARP,
+ EN_POH_FLAT
+} EnPohType;
+
+typedef enum {
+ EN_POH_INFO_NORMAL,
+ EN_POH_INFO_COMPOSER
+} EnPohInfoType;
+
+typedef struct {
+ /* 0x0000 */ Color_RGB8 primColor;
+ /* 0x0003 */ Color_RGB8 lightColor;
+ /* 0x0006 */ u8 unk_6; // limb index
+ /* 0x0006 */ u8 unk_7; // limb index
+ /* 0x0008 */ s8 unk_8; // rate of some kind
+ /* 0x000C */ AnimationHeader* unk_C;
+ /* 0x0010 */ AnimationHeader* unk_10;
+ /* 0x0014 */ UNK_PTR unk_14;
+ /* 0x0018 */ AnimationHeader* unk_18;
+ /* 0x001C */ Gfx* unk_1C;
+ /* 0x0020 */ Gfx* unk_20;
+ /* 0x0024 */ Gfx* soulDisplayList;
+} EnPohInfo; // size = 0x28
+
typedef struct EnPoh {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x25C];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ EnPohActionFunc actionFunc;
+ /* 0x0194 */ u8 unk_194;
+ /* 0x0195 */ u8 unk_195;
+ /* 0x0196 */ s8 objectIdx;
+ /* 0x0197 */ u8 infoIdx;
+ /* 0x0198 */ s16 unk_198;
+ /* 0x019A */ s16 visibilityTimer;
+ /* 0x019C */ s16 unk_19C;
+ /* 0x019E */ Vec3s limbDrawTable[21];
+ /* 0x021C */ Vec3s transitionDrawTable[21];
+ /* 0x029A */ Color_RGBA8 lightColor;
+ /* 0x029E */ Color_RGBA8 envColor;
+ /* 0x02A4 */ EnPohInfo* info;
+ /* 0x02A8 */ LightNode* lightNode;
+ /* 0x02AC */ LightInfo lightInfo;
+ /* 0x02BC */ ColliderCylinder colliderCyl;
+ /* 0x0308 */ ColliderJntSph colliderSph;
+ /* 0x0328 */ ColliderJntSphItem colliderSphItem;
+ /* 0x0368 */ MtxF unk_368;
} EnPoh; // size = 0x03A8
extern const ActorInit En_Poh_InitVars;
diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/src/overlays/actors/ovl_En_Tk/z_en_tk.c
index 5a73310c6..7fbe600be 100644
--- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c
+++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c
@@ -196,8 +196,8 @@ void EnTk_DigAnim(EnTk* this, GlobalContext* globalCtx) {
void EnTk_UpdateEyes(EnTk* this) {
if (DECR(this->blinkCountdown) == 0) {
- this->eyeImageIdx++;
- if (this->eyeImageIdx > 2) {
+ this->eyeTextureIdx++;
+ if (this->eyeTextureIdx > 2) {
this->blinkCycles--;
if (this->blinkCycles < 0) {
this->blinkCountdown = Math_Rand_S16Offset(30, 30);
@@ -206,7 +206,7 @@ void EnTk_UpdateEyes(EnTk* this) {
this->blinkCycles++;
}
}
- this->eyeImageIdx = 0;
+ this->eyeTextureIdx = 0;
}
}
}
@@ -738,7 +738,7 @@ void EnTk_Draw(Actor* thisx, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyesSegments[this->eyeImageIdx]));
+ gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyesSegments[this->eyeTextureIdx]));
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnim.skeleton, this->skelAnim.limbDrawTbl, this->skelAnim.dListCount,
EnTk_OverrideLimbDraw, EnTk_PostLimbDraw, this);
diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.h b/src/overlays/actors/ovl_En_Tk/z_en_tk.h
index 788705700..c62051b92 100644
--- a/src/overlays/actors/ovl_En_Tk/z_en_tk.h
+++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.h
@@ -39,7 +39,7 @@ typedef struct EnTk {
/* 0x021C */ s16 actionCountdown;
/* 0x021E */ s16 h_21E;
/* 0x0220 */ char unk_220[0x2];
- /* 0x0222 */ s16 eyeImageIdx;
+ /* 0x0222 */ s16 eyeTextureIdx;
/* 0x0224 */ s16 blinkCountdown;
/* 0x0226 */ s16 headRot;
/* 0x0228 */ s16 currentWaypoint;
diff --git a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
index 6f764872b..51efd7d78 100644
--- a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
+++ b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
@@ -44,7 +44,7 @@ static InitChainEntry sInitChain[] = {
static UNK_PTR D_80B43F64[] = { 0x06000AF0, 0x06000000 };
-extern UNK_TYPE D_06000A60;
+extern Gfx D_06000A60[];
extern Gfx D_06000970[];
void EnYukabyun_Init(Actor* thisx, GlobalContext* globalCtx) {
@@ -98,7 +98,7 @@ void func_80B43B6C(EnYukabyun* this, GlobalContext* globalCtx) {
void EnYukabyun_Break(EnYukabyun* this, GlobalContext* globalCtx) {
EffectSsHahen_SpawnBurst(globalCtx, &this->actor.posRot.pos, 8.0f, 0, 1300, 300, 15, OBJECT_YUKABYUN, 10,
- &D_06000A60);
+ D_06000A60);
Actor_Kill(&this->actor);
}