1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-04 06:54:33 +00:00

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>
This commit is contained in:
Tharo 2020-12-05 00:34:27 +00:00 committed by GitHub
parent e983d2b72b
commit f85a2d10ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
212 changed files with 4102 additions and 15655 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2E64.s")
static InitChainEntry sInitChain[] = {
ICHAIN_S8(naviEnemyId, 0x5C, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
ICHAIN_F32(unk_4C, 3200, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2FBC.s")
extern SkeletonHeader D_06006A30;
extern AnimationHeader D_06000924;
extern AnimationHeader D_06001360;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD2FFC.s")
extern Gfx D_06004BA0[];
extern Gfx D_06004CC0[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD305C.s")
void EnPoDesert_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnPoDesert* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD30D0.s")
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);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3194.s")
void EnPoDesert_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnPoDesert* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3328.s")
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
Collider_DestroyCylinder(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Update.s")
void EnPoDesert_SetNextPathPoint(EnPoDesert* this, GlobalContext* globalCtx) {
Path* path = &globalCtx->setupPathList[this->actor.params];
Vec3s* pathPoint;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3504.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/func_80AD3594.s")
void EnPoDesert_SetupMoveToNextPoint(EnPoDesert* this) {
SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000924, -5.0f);
this->actionFunc = EnPoDesert_MoveToNextPoint;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Desert/EnPoDesert_Draw.s")
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;
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);
}
}
}
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);
}
}
void EnPoDesert_Update(Actor* thisx, GlobalContext* globalCtx) {
EnPoDesert* this = THIS;
s32 pad;
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;
}
}
s32 EnPoDesert_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
void* thisx, Gfx** gfxP) {
EnPoDesert* this = THIS;
f32 mtxScale;
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;
}
void EnPoDesert_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx,
Gfx** gfxP) {
static Vec3f baseLightPos = { 0.0f, 1400.0f, 0.0f };
EnPoDesert* this = THIS;
f32 rand;
Color_RGBA8 color;
Vec3f lightPos;
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);
}
}
void EnPoDesert_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnPoDesert* this = THIS;
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);
}

View file

@ -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;

View file

@ -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")
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_80AD3D68.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_80AD3E2C.s")
static CollisionCheckInfoInit D_80AD70D8 = { 0x04, 0x0019, 0x0032, 0x28 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD3F4C.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_80AD3FF0.s")
static s32 sNumSpawned = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4084.s")
static Vec3f sFieldMiddle = { -1000.0f, 0.0f, 6500.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4140.s")
static InitChainEntry sInitChain[] = {
ICHAIN_F32(unk_4C, 3200, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4190.s")
static Vec3f D_80AD7114 = { 0.0f, 3.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4208.s")
static Vec3f D_80AD7120 = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD42B0.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_80AD4384.s")
static Vec3f D_80AD714C = { 0.0f, 1400.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD443C.s")
static Vec3s sSpawnPositions[10];
static u8 sSpawnSwitchFlags[10];
static MtxF sLimb7Mtx;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD444C.s")
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[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4470.s")
void EnPoField_Init(Actor* thisx, GlobalContext* globalCtx) {
EnPoField* this = THIS;
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4554.s")
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);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4664.s")
void EnPoField_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnPoField* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD48CC.s")
if (this->actor.params != 0xFF) {
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
Collider_DestroyCylinder(globalCtx, &this->flameCollider);
Collider_DestroyCylinder(globalCtx, &this->collider);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4A68.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4CA4.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4E48.s")
void EnPoField_SetupCirclePlayer(EnPoField* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD4ED8.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD52F0.s")
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;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD53F0.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD54D4.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD587C.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD58D4.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5AD8.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5B18.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5C74.s")
void EnPoField_SetupSoulDisappear(EnPoField* this) {
this->actionFunc = EnPoField_SoulDisappear;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5D0C.s")
void EnPoField_SetupInteractWithSoul(EnPoField* this) {
this->actionFunc = EnPoField_SoulInteract;
this->actor.initPosRot.pos.y = this->actor.posRot.pos.y - 15.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5D60.s")
void EnPoField_CorrectYPos(EnPoField* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD5E8C.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD619C.s")
f32 EnPoField_SetFleeSpeed(EnPoField* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
f32 speed = ((player->stateFlags1 & 0x800000) && player->rideActor != NULL) ? player->rideActor->speedXZ : 12.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6330.s")
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);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Update.s")
void EnPoField_WaitForSpawn(EnPoField* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
f32 spawnDist;
s32 i;
UNK_TYPE sp88;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD65C8.s")
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;
}
}
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD66D0.s")
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);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/EnPoField_Draw.s")
void EnPoField_CirclePlayer(EnPoField* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s32 temp_v1 = 16 - this->unk_194;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6BF4.s")
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);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Field/func_80AD6C4C.s")
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);
}

View file

@ -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;

View file

@ -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 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD790C.s")
static s32 D_80AD8D24 = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7944.s")
static InitChainEntry sInitChain[] = {
ICHAIN_S8(naviEnemyId, 0x4F, ICHAIN_CONTINUE),
ICHAIN_F32(unk_4C, 1500, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7984.s")
static Vec3f D_80AD8D30 = { 0.0f, 1.5f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7A4C.s")
static Vec3f D_80AD8D3C = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7A88.s")
static Vec3f D_80AD8D48 = { 0.0f, 1200.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7B34.s")
static UNK_PTR sEyesSegments[] = {
0x06003B40,
0x06004340,
0x06004B40,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7BF0.s")
extern FlexSkeletonHeader D_0600BE40;
extern AnimationHeader D_06003768;
extern Gfx D_0600B838[];
extern Gfx D_0600BBA0[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD7C64.s")
void EnPoRelay_Init(Actor* thisx, GlobalContext* globalCtx) {
EnPoRelay* this = THIS;
s32 temp;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD8174.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD8234.s")
void EnPoRelay_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnPoRelay* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD830C.s")
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
Collider_DestroyCylinder(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Update.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/func_80AD88D0.s")
void EnPoRelay_Vec3sToVec3f(Vec3f* dest, Vec3s* src) {
dest->x = src->x;
dest->y = src->y;
dest->z = src->z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Po_Relay/EnPoRelay_Draw.s")
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);
}
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);
}
#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;
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
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);
}
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);
}
void EnPoRelay_DisappearAndReward(EnPoRelay* this, GlobalContext* globalCtx) {
Vec3f vec;
f32 multiplier;
s32 pad;
Vec3f sp60;
s32 pad1;
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;
}
void EnPoRelay_Update(Actor* thisx, GlobalContext* globalCtx) {
EnPoRelay* this = THIS;
s32 pad;
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;
}
}
void EnPoRelay_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
EnPoRelay* this = THIS;
if (limbIndex == 14) {
f32 rand;
Vec3f vec;
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);
}
}
void EnPoRelay_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnPoRelay* this = THIS;
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);
}

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);
}