diff --git a/Makefile b/Makefile
index 5c4cdd549..7d08aadce 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,8 @@ NON_MATCHING ?= 0
ORIG_COMPILER ?= 0
# Keep .mdebug section in build
KEEP_MDEBUG ?= 0
+# Disassembles all asm from the ROM instead of skipping files which are entirely in C
+FULL_DISASM ?= 0
ifeq ($(NON_MATCHING),1)
CFLAGS := -DNON_MATCHING
@@ -17,6 +19,10 @@ ifeq ($(NON_MATCHING),1)
COMPARE := 0
endif
+ifneq ($(FULL_DISASM), 0)
+ DISASM_FLAGS += --full
+endif
+
PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
MAKE = make
@@ -246,7 +252,7 @@ setup:
## Assembly generation
disasm:
$(RM) -rf asm data
- python3 tools/disasm/disasm.py -j $(N_THREADS)
+ python3 tools/disasm/disasm.py -j $(N_THREADS) $(DISASM_FLAGS)
diff-init: uncompressed
$(RM) -rf expected/
diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index f3ed5c898..d8ab73a83 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -766,59 +766,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -939,36 +942,39 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_cs.xml b/assets/xml/objects/object_cs.xml
index 7fff51fd8..65cff1d46 100644
--- a/assets/xml/objects/object_cs.xml
+++ b/assets/xml/objects/object_cs.xml
@@ -49,7 +49,7 @@
-
+
diff --git a/assets/xml/objects/object_fish.xml b/assets/xml/objects/object_fish.xml
index 3d02127c6..c0cbd54c7 100644
--- a/assets/xml/objects/object_fish.xml
+++ b/assets/xml/objects/object_fish.xml
@@ -1,6 +1,6 @@
-
+
@@ -35,29 +35,29 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
@@ -73,12 +73,12 @@
-
-
-
+
+
+
-
-
+
+
@@ -86,21 +86,23 @@
-
+
+
+
-
-
+
+
-
-
+
+
-
+
@@ -129,29 +131,32 @@
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
diff --git a/assets/xml/objects/object_giant.xml b/assets/xml/objects/object_giant.xml
index 9e1815528..edaeee039 100644
--- a/assets/xml/objects/object_giant.xml
+++ b/assets/xml/objects/object_giant.xml
@@ -1,63 +1,90 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_kibako.xml b/assets/xml/objects/object_kibako.xml
index 138894b0f..43276080a 100644
--- a/assets/xml/objects/object_kibako.xml
+++ b/assets/xml/objects/object_kibako.xml
@@ -1,8 +1,9 @@
+
-
-
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_kibako2.xml b/assets/xml/objects/object_kibako2.xml
index 098a5318d..4b6ce5ac7 100644
--- a/assets/xml/objects/object_kibako2.xml
+++ b/assets/xml/objects/object_kibako2.xml
@@ -1,13 +1,14 @@
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_oF1d_map.xml b/assets/xml/objects/object_oF1d_map.xml
index 78d5fbc9c..9557dc73e 100644
--- a/assets/xml/objects/object_oF1d_map.xml
+++ b/assets/xml/objects/object_oF1d_map.xml
@@ -7,9 +7,9 @@
-
+
-
+
diff --git a/assets/xml/objects/object_ssh.xml b/assets/xml/objects/object_ssh.xml
index e4072d79e..a95597ae4 100644
--- a/assets/xml/objects/object_ssh.xml
+++ b/assets/xml/objects/object_ssh.xml
@@ -11,9 +11,11 @@
-
+
-
+
+
+
diff --git a/assets/xml/objects/object_stream.xml b/assets/xml/objects/object_stream.xml
index ac7312079..2e49af916 100644
--- a/assets/xml/objects/object_stream.xml
+++ b/assets/xml/objects/object_stream.xml
@@ -1,6 +1,7 @@
+
-
-
+
+
diff --git a/assets/xml/objects/object_wiz.xml b/assets/xml/objects/object_wiz.xml
index 6a27c2ba9..7f41954cf 100644
--- a/assets/xml/objects/object_wiz.xml
+++ b/assets/xml/objects/object_wiz.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/assets/xml/overlays/ovl_En_Bomjima.xml b/assets/xml/overlays/ovl_En_Bomjima.xml
new file mode 100644
index 000000000..5aada4887
--- /dev/null
+++ b/assets/xml/overlays/ovl_En_Bomjima.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/assets/xml/overlays/ovl_En_Mm2.xml b/assets/xml/overlays/ovl_En_Mm2.xml
new file mode 100644
index 000000000..5d0be627f
--- /dev/null
+++ b/assets/xml/overlays/ovl_En_Mm2.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/functions.h b/include/functions.h
index 2fef88b66..52732428a 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -305,8 +305,8 @@ void osViBlack(u8 active);
s32 __osSiRawReadIo(u32 devAddr, u32* data);
OSId osGetThreadId(OSThread* t);
void osSpTaskYield(void);
-s32 __osPfsGetNextPage(OSPfs* param_1, __OSInode* param_2, u8 param_3, u8 param_4);
-s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, s32 offset, s32 size_in_bytes, u8* data_buffer);
+s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page);
+s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data);
s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel);
// void __osPfsRequestOneChannel(void);
// void __osPfsGetOneChannelData(void);
@@ -493,8 +493,8 @@ void* __osMemcpy(void* dst, void* src, size_t size);
// void EnItem00_DrawHeartContainer(EnItem00* this, GlobalContext* globalCtx);
// void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx);
// s16 func_800A7650(s16 dropId);
-EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params);
-Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params);
+Actor* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params);
+Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, s32 params);
void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3f* spawnPos, s16 params);
s32 func_800A8150(s32 index);
s32 func_800A817C(s32 index);
@@ -591,9 +591,10 @@ void EffectSsKiraKira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f
void EffectSsBomb2_SpawnLayered(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep);
// void EffectSsBlast_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, Color_RGBA8* param_5, Color_RGBA8* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10);
-// void EffectSsBlast_SpawnWhiteCustomScale(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7);
+void EffectSsBlast_SpawnWhiteCustomScale(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
+ s16 scaleStep, s16 life);
// void EffectSsBlast_SpawnShockwave(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE2 param_7);
-// void EffectSsBlast_SpawnWhiteShockwave(void);
+void EffectSsBlast_SpawnWhiteShockwave(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3);
// void EffectSsGSpk_SpawnAccel(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, Vec3f* pzParm4, Vec3f* param_5, Color_RGBA8* param_6, Color_RGBA8* param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9);
// void EffectSsGSpk_SpawnNoAccel(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9);
// void EffectSsGSpk_SpawnFuse(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5);
@@ -1255,7 +1256,7 @@ s16 Camera_ClearFlags(Camera* camera, s16 flags);
// void func_800E0238(void);
void func_800E02AC(Camera* camera, Actor* actor);
void func_800E0308(Camera* camera, Actor* actor);
-// void func_800E031C(void);
+f32 func_800E031C(Camera* camera);
void func_800E0348(Camera* camera);
DamageTable* DamageTable_Get(s32 index);
void DamageTable_Clear(DamageTable* damageTable);
@@ -1533,8 +1534,8 @@ void func_800EDF24(Actor* actor, GlobalContext* globalCtx, u32 arg2);
void func_800EDF78(Actor* actor, GlobalContext* globalCtx, s32 iParm3);
void func_800EE0CC(Actor* actor, GlobalContext* globalCtx, s32 iParm3);
s32 func_800EE1D8(GlobalContext* globalCtx);
-u32 func_800EE200(GlobalContext* globalCtx, u32 uParm2);
-u32 func_800EE29C(GlobalContext* globalCtx, u32 uParm2);
+u32 func_800EE200(GlobalContext* globalCtx, u16 uParm2);
+u32 func_800EE29C(GlobalContext* globalCtx, u16 uParm2);
u32 func_800EE2F4(GlobalContext* globalCtx);
void GetItem_Draw(GlobalContext* globalCtx, s16 index);
void func_800EE364(GlobalContext* globalCtx, s16 index);
@@ -1658,7 +1659,7 @@ u32 func_800F5954(u8* param_1, u32 param_2, u32 param_3, u8 param_4, u8 param_5)
f32 func_800F5A8C(u16 arg0, u16 arg1, u16 arg2, GlobalContext* globalContext);
// void func_800F5B10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5);
// void func_800F5CD0(void);
-// void func_800F6834(void);
+void func_800F6834(GlobalContext* globalCtx, s32 waterLightsIndex);
// void func_800F694C(void);
// void func_800F6A04(void);
// void func_800F6A40(void);
@@ -2160,7 +2161,7 @@ void func_80123F2C(GlobalContext* globalCtx, s32 arg1);
// void func_80124020(void);
u8 Player_GetMask(GlobalContext* globalCtx);
void Player_RemoveMask(GlobalContext* globalCtx);
-// void func_8012405C(void);
+s32 func_8012405C(GlobalContext* globalCtx);
// void func_80124088(void);
s32 func_801240C8(Player* player);
// void func_801240DC(void);
@@ -2617,7 +2618,7 @@ void func_8013A46C(s32 flag);
u32 func_8013A4C4(s32 flag);
s16 func_8013A504(s16 val);
s32 func_8013A530(GlobalContext* globalCtx, Actor* actor, s32 flag, Vec3f* pos, Vec3s* rot, f32 distanceMin, f32 distanceMax, s16 angleError);
-Actor* func_8013A7C0(GlobalContext* globalCtx, s32 arg1);
+struct EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5);
Gfx* func_8013A860(GlobalContext* globalCtx, s32 idx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Mtx** mtx, Gfx* gfx);
Gfx* func_8013AB00(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Gfx* gfx);
s32 func_8013AD6C(GlobalContext* globalCtx);
@@ -2630,7 +2631,7 @@ void func_8013B350(Vec3f* arg0, f32* arg1, f32 arg2, s32 arg3, s32 arg4, Vec3s*
s32 func_8013B6B0(Path* path, f32* arg1, s32* arg2, s32 arg3, s32 arg4, s32* arg5, f32* arg6, Vec3f* arg7, s32 arg8);
void func_8013B878(GlobalContext* globalCtx, Path* path, s32 arg2, Vec3f* arg3);
Path* func_8013BB34(GlobalContext* globalCtx, u8 arg1, s32 arg2);
-Actor* func_8013BB7C(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId);
+Actor* SubS_FindNearestActor(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId);
s32 func_8013BC6C(SkelAnime* skelAnime, ActorAnimationEntryS* arg1, s32 arg2);
s32 func_8013BD40(Actor* actor, Path* path, s32 arg2);
Path* func_8013BEDC(GlobalContext* globalCtx, u8 arg1, u8 arg2, s32* arg3);
@@ -2651,7 +2652,7 @@ s32 func_8013D768(Actor* actor, Vec3f* arg1, s16 arg2);
s16 func_8013D83C(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq);
s8 func_8013D8DC(s8 arg0, GlobalContext* globalCtx);
s8 func_8013D924(s16 arg0, GlobalContext* globalCtx);
-Actor* func_ActorCategoryIterateById(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId);
+Actor* SubS_FindActor(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId);
s32 func_8013D9C8(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 arg3);
s32 func_8013DB90(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2);
s32 func_8013DC40(Path* arg0, s32 arg1, s32 arg2, Vec3f* arg3);
@@ -2666,17 +2667,17 @@ s32 func_8013E2D4(Actor* actor, s16 arg1, s16 arg2, s32 arg3);
s32 func_8013E3B8(Actor* actor, s16 cutscenes[], s16 len);
void func_8013E4B0(Vec3f* arg0, Vec3f* arg1, Vec3s* arg2, Plane* plane);
s32 func_8013E5CC(Vec3f* arg0, Vec3s* arg1, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4, Vec3f* arg5);
-Actor* func_8013E640(GlobalContext* globalCtx, Actor* arg1, Actor* actorListStart, u8 actorCategory, s16 actorId, void* arg5, func_8013E640_arg6 arg6);
+Actor* SubS_FindActorCustom(GlobalContext* globalCtx, Actor* actor, Actor* actorListStart, u8 actorCategory, s16 actorId, void* verifyData, VerifyActor verifyActor);
s32 func_8013E748(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, s32 arg4, Vec3s* arg5, func_8013E748_arg6 arg6);
s32 func_8013E7C0(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2);
void func_8013E8F8(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, s32 arg4, s16 arg5, s16 arg6);
s32 func_8013E950(Vec3f* arg0, Vec3f* arg1, s16 arg2, Vec3f* arg3, Vec3f* arg4, s16* arg5, s16* arg6, s16* arg7, s16* arg8, u16 arg9, u16 arg10, u16 arg11, u16 arg12);
// void func_8013EC10(void);
-void func_8013EC44(f32 arg0, u8 arg1, u8 arg2, u8 arg3);
+void func_8013EC44(f32 a, u8 b, u8 c, u8 d);
void func_8013ECE0(f32 xyzDistToPlayerSq, u8 arg1, u8 arg2, u8 arg3);
void func_8013ED9C(void);
void func_8013EDD0(void);
-// void func_8013EE04(void);
+u32 func_8013EE04(void);
void func_8013EE24(void);
// void func_8013EE38(void);
// void func_8013EE48(void);
@@ -3802,7 +3803,7 @@ void func_8019F570(Vec3f* pos, s8 arg1);
void func_8019F88C(Vec3f* arg0, u16 sfxId, UNK_TYPE arg2);
// void func_8019F900(void);
// void func_8019FA18(void);
-void func_8019FAD8(Vec3f* param_1, u16 param_2, f32 param_3);
+void func_8019FAD8(Vec3f* param_1, u16 sfxId, f32 param_3);
// void func_8019FB0C(void);
// void func_8019FC20(void);
// void func_8019FCB8(void);
diff --git a/include/initvars.h b/include/initvars.h
index a1dbe1fa1..797e73876 100644
--- a/include/initvars.h
+++ b/include/initvars.h
@@ -1,6 +1,39 @@
#ifndef _INITVARS_H_
#define _INITVARS_H_
+extern EffectSsInit Effect_Ss_Dust_InitVars;
+extern EffectSsInit Effect_Ss_Kirakira_InitVars;
+extern EffectSsInit Effect_Ss_Bomb2_InitVars;
+extern EffectSsInit Effect_Ss_Blast_InitVars;
+extern EffectSsInit Effect_Ss_G_Spk_InitVars;
+extern EffectSsInit Effect_Ss_D_Fire_InitVars;
+extern EffectSsInit Effect_Ss_Bubble_InitVars;
+extern EffectSsInit Effect_Ss_G_Ripple_InitVars;
+extern EffectSsInit Effect_Ss_G_Splash_InitVars;
+extern EffectSsInit Effect_Ss_G_Fire_InitVars;
+extern EffectSsInit Effect_Ss_Lightning_InitVars;
+extern EffectSsInit Effect_Ss_Dt_Bubble_InitVars;
+extern EffectSsInit Effect_Ss_Hahen_InitVars;
+extern EffectSsInit Effect_Ss_Stick_InitVars;
+extern EffectSsInit Effect_Ss_Sibuki_InitVars;
+extern EffectSsInit Effect_Ss_Stone1_InitVars;
+extern EffectSsInit Effect_Ss_Hitmark_InitVars;
+extern EffectSsInit Effect_Ss_Fhg_Flash_InitVars;
+extern EffectSsInit Effect_Ss_K_Fire_InitVars;
+extern EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars;
+extern EffectSsInit Effect_Ss_Kakera_InitVars;
+extern EffectSsInit Effect_Ss_Ice_Piece_InitVars;
+extern EffectSsInit Effect_Ss_En_Ice_InitVars;
+extern EffectSsInit Effect_Ss_Fire_Tail_InitVars;
+extern EffectSsInit Effect_Ss_En_Fire_InitVars;
+extern EffectSsInit Effect_Ss_Extra_InitVars;
+extern EffectSsInit Effect_Ss_Dead_Db_InitVars;
+extern EffectSsInit Effect_Ss_Dead_Dd_InitVars;
+extern EffectSsInit Effect_Ss_Dead_Ds_InitVars;
+extern EffectSsInit Effect_Ss_Ice_Smoke_InitVars;
+extern EffectSsInit Effect_En_Ice_Block_InitVars;
+extern EffectSsInit Effect_Ss_Sbn_InitVars;
+
extern ActorInit Arms_Hook_InitVars;
extern ActorInit Arrow_Fire_InitVars;
extern ActorInit Arrow_Ice_InitVars;
diff --git a/include/io/controller.h b/include/io/controller.h
index cbd4963ae..9e36f9b62 100644
--- a/include/io/controller.h
+++ b/include/io/controller.h
@@ -99,8 +99,8 @@
typedef struct {
/* 0x00 */ u32 ramarray[15];
- /* 0x3C */ u32 pifstatus;
-} OSPifRam;
+ /* 0x3C */ u32 status;
+} OSPifRam; // size = 0x40
typedef struct {
diff --git a/include/variables.h b/include/variables.h
index 4e4b444eb..17810bab6 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -382,7 +382,7 @@ extern UNK_PTR D_801AE260[3];
// extern UNK_TYPE4 D_801AE2BC;
// extern UNK_TYPE4 D_801AE2CC;
// extern UNK_TYPE4 D_801AE2DC;
-extern EffectSsInfo EffectSS2Info;
+// extern EffectSsInfo sEffectSsInfo;
// extern UNK_TYPE1 D_801AE3B0;
// extern UNK_TYPE1 D_801AE3B4;
// extern UNK_TYPE4 D_801AE3B8;
@@ -410,7 +410,7 @@ extern EffectSsInfo EffectSS2Info;
// extern UNK_TYPE1 D_801AE48A;
// extern UNK_TYPE1 D_801AE48C;
// extern UNK_TYPE1 D_801AE490;
-extern EffectSsOverlay particleOverlayTable[39];
+extern EffectSsOverlay gParticleOverlayTable[39];
// extern FlagSetEntry sFlagEntries[];
// extern s32 sEntryIndex;
// extern u32 sCurrentBit;
@@ -3866,14 +3866,6 @@ extern UNK_TYPE D_0400E3D8;
extern UNK_TYPE D_0400E408;
extern UNK_TYPE D_0400E410;
extern UNK_TYPE D_0400E418;
-extern CollisionHeader D_0400E710; // Pink Deku Flower collision
-extern AnimationHeader D_0400EB7C; // Deku Flower intense flutter animation
-extern Gfx D_0400ED80; // Pink Deku Flower display list
-extern SkeletonHeader D_04011518; // Pink Deku Flower skeleton
-extern AnimationHeader D_040117A8; // Deku Flower small flutter animation
-extern CollisionHeader D_040118D8; // Gold Deku Flower collision
-extern Gfx D_04011BD0; // Gold Deku Flower display list
-extern SkeletonHeader D_040127E8; // Gold Deku Flower skeleton
extern UNK_TYPE D_04012860;
extern UNK_TYPE D_040128BC;
extern u64 D_04014570[];
@@ -3895,7 +3887,8 @@ extern Gfx D_04023210[];
extern UNK_TYPE D_04023288;
extern Gfx D_04023348[];
extern Gfx D_04023428[];
-extern UNK_TYPE D_04025850;
+extern Gfx D_04025850[];
+extern Gfx D_04025970[];
extern UNK_TYPE D_04025DD0;
extern UNK_TYPE D_040281DC;
extern UNK_TYPE D_04028FEC;
@@ -3903,16 +3896,9 @@ extern AnimationHeader D_04029140;
extern Gfx D_04029CB0[];
extern Gfx D_04029CF0[];
extern UNK_TYPE D_04029D20;
-extern AnimationHeader D_0402B494;
-extern AnimatedMaterial D_0402C818;
-extern AnimatedMaterial D_0402C890;
-extern AnimatedMaterial D_0402C908;
-extern AnimatedMaterial D_0402C980;
-extern AnimatedMaterial D_0402C9F8;
-extern FlexSkeletonHeader D_0402CA98;
extern Gfx D_0402E510[];
-extern UNK_TYPE D_0402E65C;
-extern UNK_TYPE D_0402F0EC;
+extern AnimationHeader D_0402E65C;
+extern AnimationHeader D_0402F0EC;
extern Gfx D_04030100[]; // Floor shockwave ring
extern Gfx D_040301B0[];
extern UNK_TYPE D_04032270;
@@ -3937,8 +3923,8 @@ extern UNK_TYPE D_04050D10;
extern UNK_TYPE D_04051180;
extern UNK_TYPE D_04051238;
extern AnimationHeader D_0405140C;
-extern UNK_TYPE D_040527F0;
-extern UNK_TYPE D_040528B0;
+extern Gfx D_040527F0[];
+extern Gfx D_040528B0[];
extern Gfx D_04054A90[];
extern u64 D_04054F20[];
extern UNK_TYPE D_04055628;
@@ -3980,6 +3966,7 @@ extern Gfx D_0406AB30[];
extern UNK_TYPE D_0406B730;
extern UNK_TYPE D_0406BB0C;
extern UNK_TYPE D_0406F380;
+extern Gfx D_040706E0[];
extern UNK_TYPE D_04073F00;
extern UNK_TYPE D_04075400;
extern Gfx D_04075A40[];
@@ -4001,13 +3988,13 @@ extern UNK_TYPE D_04091CE0;
extern Gfx D_05000C40[];
extern UNK_TYPE D_05001D20;
-extern UNK_TYPE D_050061E8;
-extern UNK_TYPE D_05006420;
-extern UNK_TYPE D_050066B0;
+extern Gfx D_050061E8[];
+extern Gfx D_05006420[];
+extern Gfx D_050066B0[];
extern UNK_TYPE D_05007498;
extern Gfx D_05007890[];
-extern UNK_TYPE D_050078A0;
-extern UNK_TYPE D_05007938;
+extern Gfx D_050078A0[];
+extern Gfx D_05007938[];
extern Gfx D_05007980[];
extern UNK_TYPE D_05007E00;
extern UNK_TYPE D_05008018;
@@ -4024,7 +4011,7 @@ extern UNK_TYPE D_0502324C;
// other segments
extern GfxMasterList D_0E000000;
-
+extern Mtx D_01000000;
extern UNK_TYPE D_0F000000;
diff --git a/include/z64.h b/include/z64.h
index de053cecb..aa31b0b0c 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -1554,7 +1554,7 @@ typedef struct {
typedef s32 (*func_8013E748_arg6)(struct GlobalContext*, Actor*, Vec3s*);
-typedef s32 (*func_8013E640_arg6)(struct GlobalContext*, Actor*, Actor*, void*);
+typedef s32 (*VerifyActor)(struct GlobalContext*, Actor*, Actor*, void*);
struct struct_8013DF3C_arg1;
typedef void (*struct_8013DF3C_arg1_unk_func1)(struct GlobalContext*, struct struct_8013DF3C_arg1*);
diff --git a/include/z64actor.h b/include/z64actor.h
index 2b35bec24..9cbf9885e 100644
--- a/include/z64actor.h
+++ b/include/z64actor.h
@@ -15,6 +15,8 @@ struct GlobalContext;
struct Lights;
struct CollisionPoly;
+struct EnDoor;
+
typedef void(*ActorFunc)(struct Actor* this, struct GlobalContext* globalCtx);
typedef struct {
diff --git a/include/z64effect.h b/include/z64effect.h
index b095c89e9..d9211ef5e 100644
--- a/include/z64effect.h
+++ b/include/z64effect.h
@@ -254,7 +254,7 @@ typedef struct {
/* 0x0C */ void* vramEnd;
/* 0x10 */ void* loadedRamAddr;
/* 0x14 */ EffectSsInit* initInfo;
- /* 0x18 */ u32 unk18; // Always 0x01000000?
+ /* 0x18 */ u8 unk18; // Always 1?
} EffectSsOverlay; // size = 0x1C
typedef struct EffectSs {
@@ -279,27 +279,6 @@ typedef struct {
/* 0x8 */ s32 size;
} EffectSsInfo; // size = 0xC
-typedef struct {
- /* 0x0 */ EffectSs* data_table; // Name from debug assert
- /* 0x4 */ s32 searchIndex;
- /* 0x8 */ s32 size;
-} EffectTableInfo; // size = 0xC
-
-typedef struct {
- /* 0x0 */ UNK_TYPE4 unk0;
- /* 0x4 */ EffectSsInitFunc init;
-} ParticleOverlayInfo; // size = 0x8
-
-typedef struct {
- /* 0x00 */ u32 vromStart;
- /* 0x04 */ u32 vromEnd;
- /* 0x08 */ void* vramStart;
- /* 0x0C */ void* vramEnd;
- /* 0x10 */ void* loadedRamAddr;
- /* 0x14 */ ParticleOverlayInfo* overlayInfo;
- /* 0x18 */ u32 unk18; // Always 0x01000000?
-} ParticleOverlay; // size = 0x1C
-
typedef enum {
/* 0x00 */ EFFECT_SS_DUST,
/* 0x01 */ EFFECT_SS_KIRAKIRA,
diff --git a/include/z64item.h b/include/z64item.h
index 7da1b28ad..295144817 100644
--- a/include/z64item.h
+++ b/include/z64item.h
@@ -279,6 +279,7 @@ typedef enum {
/* 0x07 */ GI_RUPEE_HUGE,
/* 0x08 */ GI_WALLET_ADULT,
/* 0x09 */ GI_WALLET_GIANT,
+ /* 0x0A */ GI_RECOVERY_HEART,
/* 0x0C */ GI_HEART_PIECE = 0x0C,
/* 0x0D */ GI_HEART_CONTAINER,
/* 0x16 */ GI_BOMBS_10 = 0x16,
@@ -302,6 +303,7 @@ typedef enum {
/* 0x3C */ GI_KEY_SMALL = 0x3C,
/* 0x3E */ GI_MAP = 0x3E,
/* 0x3F */ GI_COMPASS,
+ /* 0x52 */ GI_SCALE_GOLD = 0x52, // Assumed, used in En_Fishing
/* 0x59 */ GI_BOTTLE_POTION_RED = 0x59,
/* 0x5B */ GI_POTION_RED = 0x5B,
/* 0x5C */ GI_POTION_GREEN,
diff --git a/spec b/spec
index 69a6097c9..08de6f34b 100644
--- a/spec
+++ b/spec
@@ -120,8 +120,6 @@ beginseg
include "build/src/libultra/io/devmgr.o"
include "build/src/libultra/io/pirawdma.o"
include "build/src/libultra/io/contpfs.o"
- include "build/data/boot/contpfs.data.o"
- include "build/data/boot/contpfs.bss.o"
include "build/asm/boot/getcount.text.o"
pad_text
include "build/asm/boot/guMtxL2F.text.o"
@@ -436,9 +434,8 @@ beginseg
include "build/src/code/z_eff_tire_mark.o"
include "build/src/code/z_effect.o"
include "build/src/code/z_effect_soft_sprite.o"
- include "build/data/code/z_effect_soft_sprite.data.o"
include "build/src/code/z_effect_soft_sprite_old_init.o"
- include "build/data/code/z_effect_soft_sprite_old_init.data.o"
+ include "build/src/code/z_effect_soft_sprite_dlftbls.o"
include "build/src/code/flg_set.o"
include "build/data/code/flg_set.bss.o"
include "build/src/code/pad_801DC9C0.o"
@@ -877,8 +874,7 @@ beginseg
name "ovl_En_Peehat"
compress
include "build/src/overlays/actors/ovl_En_Peehat/z_en_peehat.o"
- include "build/data/ovl_En_Peehat/ovl_En_Peehat.data.o"
- include "build/data/ovl_En_Peehat/ovl_En_Peehat.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Peehat/ovl_En_Peehat_reloc.o"
endseg
beginseg
@@ -961,8 +957,7 @@ beginseg
name "ovl_En_St"
compress
include "build/src/overlays/actors/ovl_En_St/z_en_st.o"
- include "build/data/ovl_En_St/ovl_En_St.data.o"
- include "build/data/ovl_En_St/ovl_En_St.reloc.o"
+ include "build/src/overlays/actors/ovl_En_St/ovl_En_St_reloc.o"
endseg
beginseg
@@ -1198,9 +1193,11 @@ beginseg
name "ovl_Object_Kankyo"
compress
include "build/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.o"
- include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.data.o"
- include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.bss.o"
+#ifdef NON_MATCHING
+ include "build/src/overlays/actors/ovl_Object_Kankyo/ovl_Object_Kankyo_reloc.o"
+#else
include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.reloc.o"
+#endif
endseg
beginseg
@@ -1326,9 +1323,11 @@ beginseg
name "ovl_En_Fishing"
compress
include "build/src/overlays/actors/ovl_En_Fishing/z_en_fishing.o"
- include "build/data/ovl_En_Fishing/ovl_En_Fishing.data.o"
- include "build/data/ovl_En_Fishing/ovl_En_Fishing.bss.o"
+#ifdef NON_MATCHING
+ include "build/src/overlays/actors/ovl_En_Fishing/ovl_En_Fishing_reloc.o"
+#else
include "build/data/ovl_En_Fishing/ovl_En_Fishing.reloc.o"
+#endif
endseg
beginseg
@@ -1374,8 +1373,7 @@ beginseg
name "ovl_En_Fish"
compress
include "build/src/overlays/actors/ovl_En_Fish/z_en_fish.o"
- include "build/data/ovl_En_Fish/ovl_En_Fish.data.o"
- include "build/data/ovl_En_Fish/ovl_En_Fish.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Fish/ovl_En_Fish_reloc.o"
endseg
beginseg
@@ -1674,8 +1672,7 @@ beginseg
name "ovl_En_Ishi"
compress
include "build/src/overlays/actors/ovl_En_Ishi/z_en_ishi.o"
- include "build/data/ovl_En_Ishi/ovl_En_Ishi.data.o"
- include "build/data/ovl_En_Ishi/ovl_En_Ishi.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Ishi/ovl_En_Ishi_reloc.o"
endseg
beginseg
@@ -1817,16 +1814,14 @@ beginseg
name "ovl_Obj_Roomtimer"
compress
include "build/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.o"
- include "build/data/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer.data.o"
- include "build/data/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer_reloc.o"
endseg
beginseg
name "ovl_En_Ssh"
compress
include "build/src/overlays/actors/ovl_En_Ssh/z_en_ssh.o"
- include "build/data/ovl_En_Ssh/ovl_En_Ssh.data.o"
- include "build/data/ovl_En_Ssh/ovl_En_Ssh.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Ssh/ovl_En_Ssh_reloc.o"
endseg
beginseg
@@ -2274,8 +2269,7 @@ beginseg
name "ovl_En_Mm2"
compress
include "build/src/overlays/actors/ovl_En_Mm2/z_en_mm2.o"
- include "build/data/ovl_En_Mm2/ovl_En_Mm2.data.o"
- include "build/data/ovl_En_Mm2/ovl_En_Mm2.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Mm2/ovl_En_Mm2_reloc.o"
endseg
beginseg
@@ -2550,9 +2544,7 @@ beginseg
name "ovl_Boss_04"
compress
include "build/src/overlays/actors/ovl_Boss_04/z_boss_04.o"
- include "build/data/ovl_Boss_04/ovl_Boss_04.data.o"
- include "build/data/ovl_Boss_04/ovl_Boss_04.bss.o"
- include "build/data/ovl_Boss_04/ovl_Boss_04.reloc.o"
+ include "build/src/overlays/actors/ovl_Boss_04/ovl_Boss_04_reloc.o"
endseg
beginseg
@@ -2608,8 +2600,11 @@ beginseg
name "ovl_En_Go"
compress
include "build/src/overlays/actors/ovl_En_Go/z_en_go.o"
- include "build/data/ovl_En_Go/ovl_En_Go.data.o"
+#ifdef NON_MATCHING
+ include "build/src/overlays/actors/ovl_En_Go/ovl_En_Go_reloc.o"
+#else
include "build/data/ovl_En_Go/ovl_En_Go.reloc.o"
+#endif
endseg
beginseg
@@ -2646,9 +2641,7 @@ beginseg
name "ovl_Obj_Flowerpot"
compress
include "build/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.o"
- include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.data.o"
- include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.bss.o"
- include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot_reloc.o"
endseg
beginseg
@@ -2928,8 +2921,7 @@ beginseg
name "ovl_En_Wiz_Fire"
compress
include "build/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.o"
- include "build/data/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire.data.o"
- include "build/data/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire_reloc.o"
endseg
beginseg
@@ -3019,8 +3011,7 @@ beginseg
name "ovl_Obj_Hugebombiwa"
compress
include "build/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.o"
- include "build/data/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa.data.o"
- include "build/data/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa_reloc.o"
endseg
beginseg
@@ -3042,17 +3033,14 @@ beginseg
name "ovl_En_Water_Effect"
compress
include "build/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.o"
- include "build/data/ovl_En_Water_Effect/ovl_En_Water_Effect.data.o"
- include "build/data/ovl_En_Water_Effect/ovl_En_Water_Effect.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Water_Effect/ovl_En_Water_Effect_reloc.o"
endseg
beginseg
name "ovl_En_Kusa2"
compress
include "build/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.o"
- include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.data.o"
- include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.bss.o"
- include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Kusa2/ovl_En_Kusa2_reloc.o"
endseg
beginseg
@@ -3623,8 +3611,7 @@ beginseg
name "ovl_En_Kame"
compress
include "build/src/overlays/actors/ovl_En_Kame/z_en_kame.o"
- include "build/data/ovl_En_Kame/ovl_En_Kame.data.o"
- include "build/data/ovl_En_Kame/ovl_En_Kame.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Kame/ovl_En_Kame_reloc.o"
endseg
beginseg
@@ -3842,8 +3829,7 @@ beginseg
name "ovl_En_Col_Man"
compress
include "build/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.o"
- include "build/data/ovl_En_Col_Man/ovl_En_Col_Man.data.o"
- include "build/data/ovl_En_Col_Man/ovl_En_Col_Man.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Col_Man/ovl_En_Col_Man_reloc.o"
endseg
beginseg
@@ -3864,8 +3850,11 @@ beginseg
name "ovl_Obj_Snowball"
compress
include "build/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.o"
- include "build/data/ovl_Obj_Snowball/ovl_Obj_Snowball.data.o"
+#ifdef NON_MATCHING
+ include "build/src/overlays/actors/ovl_Obj_Snowball/ovl_obj_Snowball_reloc.o"
+#else
include "build/data/ovl_Obj_Snowball/ovl_Obj_Snowball.reloc.o"
+#endif
endseg
beginseg
@@ -3880,8 +3869,7 @@ beginseg
name "ovl_En_Gb2"
compress
include "build/src/overlays/actors/ovl_En_Gb2/z_en_gb2.o"
- include "build/data/ovl_En_Gb2/ovl_En_Gb2.data.o"
- include "build/data/ovl_En_Gb2/ovl_En_Gb2.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Gb2/ovl_En_Gb2_reloc.o"
endseg
beginseg
@@ -3980,8 +3968,7 @@ beginseg
name "ovl_Obj_Dowsing"
compress
include "build/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.o"
- include "build/data/ovl_Obj_Dowsing/ovl_Obj_Dowsing.data.o"
- include "build/data/ovl_Obj_Dowsing/ovl_Obj_Dowsing.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Dowsing/ovl_Obj_Dowsing_reloc.o"
endseg
beginseg
@@ -4419,8 +4406,7 @@ beginseg
name "ovl_Obj_Jg_Gakki"
compress
include "build/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.o"
- include "build/data/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki.data.o"
- include "build/data/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki_reloc.o"
endseg
beginseg
@@ -4919,8 +4905,7 @@ beginseg
name "ovl_En_Ruppecrow"
compress
include "build/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.o"
- include "build/data/ovl_En_Ruppecrow/ovl_En_Ruppecrow.data.o"
- include "build/data/ovl_En_Ruppecrow/ovl_En_Ruppecrow.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Ruppecrow/ovl_En_Ruppecrow_reloc.o"
endseg
beginseg
@@ -5105,7 +5090,6 @@ beginseg
name "ovl_En_Bomjima"
compress
include "build/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.o"
- include "build/data/ovl_En_Bomjima/ovl_En_Bomjima.data.o"
include "build/data/ovl_En_Bomjima/ovl_En_Bomjima.reloc.o"
endseg
diff --git a/src/code/graph.c b/src/code/graph.c
index 7ef1715fd..b874fef51 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -88,33 +88,27 @@ GameStateOverlay* Graph_GetNextGameState(GameState* gameState) {
return NULL;
}
-#ifdef NON_MATCHING
-// Regalloc differences
void* Graph_FaultAddrConvFunc(void* address, void* param) {
- u32 addr = address;
- GameStateOverlay* gamestateOvl;
- u32 ramConv;
- u32 ramStart;
- u32 diff;
+ uintptr_t addr = address;
+ GameStateOverlay* gamestateOvl = &gGameStateOverlayTable[0];
+ uintptr_t ramConv;
+ void* ramStart;
+ uintptr_t diff;
s32 i;
- for (i = 0; i < graphNumGameStates; i++) {
- gamestateOvl = &gGameStateOverlayTable[i];
+ for (i = 0; i < graphNumGameStates; i++, gamestateOvl++) {
+ diff = (uintptr_t)gamestateOvl->vramEnd - (uintptr_t)gamestateOvl->vramStart;
ramStart = gamestateOvl->loadedRamAddr;
- diff = (u32)gamestateOvl->vramEnd - (u32)gamestateOvl->vramStart;
- ramConv = (u32)gamestateOvl->vramStart - ramStart;
+ ramConv = (uintptr_t)gamestateOvl->vramStart - (uintptr_t)ramStart;
- if (gamestateOvl->loadedRamAddr != NULL) {
- if (addr >= ramStart && addr < ramStart + diff) {
+ if (ramStart != NULL) {
+ if (addr >= (uintptr_t)ramStart && addr < (uintptr_t)ramStart + diff) {
return addr + ramConv;
}
}
}
return NULL;
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_FaultAddrConvFunc.s")
-#endif
void Graph_Init(GraphicsContext* gfxCtx) {
bzero(gfxCtx, sizeof(GraphicsContext));
diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c
index 47c2202f1..424166f89 100644
--- a/src/code/z_effect_soft_sprite.c
+++ b/src/code/z_effect_soft_sprite.c
@@ -1,20 +1,22 @@
#include "global.h"
+EffectSsInfo sEffectSsInfo = { NULL, 0, 0 };
+
void EffectSS_Init(GlobalContext* globalCtx, s32 numEntries) {
u32 i;
EffectSs* effectsSs;
EffectSsOverlay* overlay;
- EffectSS2Info.data_table = (EffectSs*)THA_AllocEndAlign16(&globalCtx->state.heap, numEntries * sizeof(EffectSs));
- EffectSS2Info.searchIndex = 0;
- EffectSS2Info.size = numEntries;
+ sEffectSsInfo.data_table = (EffectSs*)THA_AllocEndAlign16(&globalCtx->state.heap, numEntries * sizeof(EffectSs));
+ sEffectSsInfo.searchIndex = 0;
+ sEffectSsInfo.size = numEntries;
- for (effectsSs = &EffectSS2Info.data_table[0]; effectsSs < &EffectSS2Info.data_table[EffectSS2Info.size];
+ for (effectsSs = &sEffectSsInfo.data_table[0]; effectsSs < &sEffectSsInfo.data_table[sEffectSsInfo.size];
effectsSs++) {
EffectSS_ResetEntry(effectsSs);
}
- overlay = &particleOverlayTable[0];
+ overlay = &gParticleOverlayTable[0];
for (i = 0; i < EFFECT_SS_MAX; i++) {
overlay->loadedRamAddr = NULL;
overlay++;
@@ -27,30 +29,31 @@ void EffectSS_Clear(GlobalContext* globalCtx) {
EffectSsOverlay* overlay;
void* addr;
- EffectSS2Info.data_table = NULL;
- EffectSS2Info.searchIndex = 0;
- EffectSS2Info.size = 0;
+ sEffectSsInfo.data_table = NULL;
+ sEffectSsInfo.searchIndex = 0;
+ sEffectSsInfo.size = 0;
- // This code is completely useless, as data_table was just set to NULL and size to 0
- for (effectsSs = EffectSS2Info.data_table; effectsSs < EffectSS2Info.data_table + EffectSS2Info.size; effectsSs++) {
+ //! @bug: Effects left in the table are not properly deleted, as data_table was just set to NULL and size to 0
+ for (effectsSs = &sEffectSsInfo.data_table[0]; effectsSs < &sEffectSsInfo.data_table[sEffectSsInfo.size];
+ effectsSs++) {
EffectSS_Delete(effectsSs);
}
// Free memory from loaded particle overlays
- overlay = &particleOverlayTable[0];
+ overlay = &gParticleOverlayTable[0];
for (i = 0; i < EFFECT_SS_MAX; i++) {
addr = overlay->loadedRamAddr;
if (addr != NULL) {
ZeldaArena_Free(addr);
}
- overlay->loadedRamAddr = 0;
+ overlay->loadedRamAddr = NULL;
overlay++;
}
}
EffectSs* EffectSS_GetTable() {
- return EffectSS2Info.data_table;
+ return sEffectSsInfo.data_table;
}
void EffectSS_Delete(EffectSs* effectSs) {
@@ -90,27 +93,27 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) {
s32 foundFree;
s32 i;
- if (EffectSS2Info.searchIndex >= EffectSS2Info.size) {
- EffectSS2Info.searchIndex = 0;
+ if (sEffectSsInfo.searchIndex >= sEffectSsInfo.size) {
+ sEffectSsInfo.searchIndex = 0;
}
// Search for a unused entry
- i = EffectSS2Info.searchIndex;
+ i = sEffectSsInfo.searchIndex;
foundFree = false;
while (true) {
- if (EffectSS2Info.data_table[i].life == -1) {
+ if (sEffectSsInfo.data_table[i].life == -1) {
foundFree = true;
break;
}
i++;
- if (i >= EffectSS2Info.size) {
+ if (i >= sEffectSsInfo.size) {
i = 0; // Loop around the whole table
}
// After a full loop, break out
- if (i == EffectSS2Info.searchIndex) {
+ if (i == sEffectSsInfo.searchIndex) {
break;
}
}
@@ -122,22 +125,22 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) {
// If all slots are in use, search for a slot with a lower priority
// Note that a lower priority is representend by a higher value
- i = EffectSS2Info.searchIndex;
+ i = sEffectSsInfo.searchIndex;
while (true) {
// Equal priority should only be considered "lower" if flag 0 is set
- if ((priority <= EffectSS2Info.data_table[i].priority) &&
- !((priority == EffectSS2Info.data_table[i].priority) && (EffectSS2Info.data_table[i].flags & 1))) {
+ if ((priority <= sEffectSsInfo.data_table[i].priority) &&
+ !((priority == sEffectSsInfo.data_table[i].priority) && (sEffectSsInfo.data_table[i].flags & 1))) {
break;
}
i++;
- if (i >= EffectSS2Info.size) {
+ if (i >= sEffectSsInfo.size) {
i = 0; // Loop around the whole table
}
// After a full loop, return 1 to indicate that we failed to find a suitable slot
- if (i == EffectSS2Info.searchIndex) {
+ if (i == sEffectSsInfo.searchIndex) {
return true;
}
}
@@ -151,8 +154,8 @@ void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) {
if (FrameAdvance_IsEnabled(globalCtx) != true) {
if (EffectSS_FindFreeSpace(effectsSs->priority, &index) == 0) {
- EffectSS2Info.searchIndex = index + 1;
- EffectSS2Info.data_table[index] = *effectsSs;
+ sEffectSsInfo.searchIndex = index + 1;
+ sEffectSsInfo.data_table[index] = *effectsSs;
}
}
}
@@ -160,7 +163,7 @@ void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) {
void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* initData) {
s32 index;
u32 overlaySize;
- EffectSsOverlay* entry = &particleOverlayTable[type];
+ EffectSsOverlay* entry = &gParticleOverlayTable[type];
EffectSsInit* initInfo;
if (EffectSS_FindFreeSpace(priority, &index) != 0) {
@@ -168,8 +171,8 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
return;
}
- EffectSS2Info.searchIndex = index + 1;
- overlaySize = (u32)entry->vramEnd - (u32)entry->vramStart;
+ sEffectSsInfo.searchIndex = index + 1;
+ overlaySize = (uintptr_t)entry->vramEnd - (uintptr_t)entry->vramStart;
if (entry->vramStart == NULL) {
initInfo = entry->initInfo;
@@ -184,27 +187,27 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
Load2_LoadOverlay(entry->vromStart, entry->vromEnd, entry->vramStart, entry->vramEnd, entry->loadedRamAddr);
}
- initInfo = (void*)(u32)(
- entry->initInfo != NULL
- ? (EffectSsInit*)(-((u32)entry->vramStart - (u32)entry->loadedRamAddr) + (u32)entry->initInfo)
- : NULL);
+ initInfo = (u32)((entry->initInfo != NULL)
+ ? (EffectSsInit*)(-((uintptr_t)entry->vramStart - (uintptr_t)entry->loadedRamAddr) +
+ (uintptr_t)entry->initInfo)
+ : NULL);
}
if (initInfo->init != NULL) {
// Delete the previous effect in the slot, in case the slot wasn't free
- EffectSS_Delete(&EffectSS2Info.data_table[index]);
+ EffectSS_Delete(&sEffectSsInfo.data_table[index]);
- EffectSS2Info.data_table[index].type = type;
- EffectSS2Info.data_table[index].priority = priority;
+ sEffectSsInfo.data_table[index].type = type;
+ sEffectSsInfo.data_table[index].priority = priority;
- if (initInfo->init(globalCtx, index, &EffectSS2Info.data_table[index], initData) == 0) {
- EffectSS_ResetEntry(&EffectSS2Info.data_table[index]);
+ if (initInfo->init(globalCtx, index, &sEffectSsInfo.data_table[index], initData) == 0) {
+ EffectSS_ResetEntry(&sEffectSsInfo.data_table[index]);
}
}
}
void EffectSS_UpdateParticle(GlobalContext* globalCtx, s32 index) {
- EffectSs* particle = &EffectSS2Info.data_table[index];
+ EffectSs* particle = &sEffectSsInfo.data_table[index];
if (particle->update != NULL) {
particle->velocity.x += particle->accel.x;
@@ -222,23 +225,23 @@ void EffectSS_UpdateParticle(GlobalContext* globalCtx, s32 index) {
void EffectSS_UpdateAllParticles(GlobalContext* globalCtx) {
s32 i;
- for (i = 0; i < EffectSS2Info.size; i++) {
- if (EffectSS2Info.data_table[i].life > -1) {
- EffectSS2Info.data_table[i].life--;
+ for (i = 0; i < sEffectSsInfo.size; i++) {
+ if (sEffectSsInfo.data_table[i].life > -1) {
+ sEffectSsInfo.data_table[i].life--;
- if (EffectSS2Info.data_table[i].life < 0) {
- EffectSS_Delete(&EffectSS2Info.data_table[i]);
+ if (sEffectSsInfo.data_table[i].life < 0) {
+ EffectSS_Delete(&sEffectSsInfo.data_table[i]);
}
}
- if (EffectSS2Info.data_table[i].life > -1) {
+ if (sEffectSsInfo.data_table[i].life > -1) {
EffectSS_UpdateParticle(globalCtx, i);
}
}
}
void EffectSS_DrawParticle(GlobalContext* globalCtx, s32 index) {
- EffectSs* entry = &EffectSS2Info.data_table[index];
+ EffectSs* entry = &sEffectSsInfo.data_table[index];
if (entry->draw != NULL) {
entry->draw(globalCtx, index, entry);
@@ -252,12 +255,12 @@ void EffectSS_DrawAllParticles(GlobalContext* globalCtx) {
Lights_BindAll(lights, globalCtx->lightCtx.listHead, NULL, globalCtx);
Lights_Draw(lights, globalCtx->state.gfxCtx);
- for (i = 0; i < EffectSS2Info.size; i++) {
- if (EffectSS2Info.data_table[i].life > -1) {
- if ((EffectSS2Info.data_table[i].pos.x > 32000.0f) || (EffectSS2Info.data_table[i].pos.x < -32000.0f) ||
- (EffectSS2Info.data_table[i].pos.y > 32000.0f) || (EffectSS2Info.data_table[i].pos.y < -32000.0f) ||
- (EffectSS2Info.data_table[i].pos.z > 32000.0f) || (EffectSS2Info.data_table[i].pos.z < -32000.0f)) {
- EffectSS_Delete(&EffectSS2Info.data_table[i]);
+ for (i = 0; i < sEffectSsInfo.size; i++) {
+ if (sEffectSsInfo.data_table[i].life > -1) {
+ if ((sEffectSsInfo.data_table[i].pos.x > 32000.0f) || (sEffectSsInfo.data_table[i].pos.x < -32000.0f) ||
+ (sEffectSsInfo.data_table[i].pos.y > 32000.0f) || (sEffectSsInfo.data_table[i].pos.y < -32000.0f) ||
+ (sEffectSsInfo.data_table[i].pos.z > 32000.0f) || (sEffectSsInfo.data_table[i].pos.z < -32000.0f)) {
+ EffectSS_Delete(&sEffectSsInfo.data_table[i]);
} else {
EffectSS_DrawParticle(globalCtx, i);
}
diff --git a/src/code/z_effect_soft_sprite_dlftbls.c b/src/code/z_effect_soft_sprite_dlftbls.c
new file mode 100644
index 000000000..e215cdee9
--- /dev/null
+++ b/src/code/z_effect_soft_sprite_dlftbls.c
@@ -0,0 +1,56 @@
+#include "global.h"
+#include "initvars.h"
+
+#define EFFECT_SS_OVERLAY(name) \
+ { \
+ SEGMENT_ROM_START(ovl_##name), SEGMENT_ROM_END(ovl_##name), SEGMENT_START(ovl_##name), \
+ SEGMENT_END(ovl_##name), NULL, &name##_InitVars, 1, \
+ }
+
+#define EFFECT_SS_OVERLAY_INTERNAL(name) \
+ { 0, 0, NULL, NULL, NULL, &name##_InitVars, 1 }
+
+#define EFFECT_SS_OVERLAY_UNSET \
+ { 0 }
+
+EffectSsOverlay gParticleOverlayTable[] = {
+ EFFECT_SS_OVERLAY(Effect_Ss_Dust),
+ EFFECT_SS_OVERLAY(Effect_Ss_Kirakira),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_Bomb2),
+ EFFECT_SS_OVERLAY(Effect_Ss_Blast),
+ EFFECT_SS_OVERLAY(Effect_Ss_G_Spk),
+ EFFECT_SS_OVERLAY(Effect_Ss_D_Fire),
+ EFFECT_SS_OVERLAY(Effect_Ss_Bubble),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_G_Ripple),
+ EFFECT_SS_OVERLAY(Effect_Ss_G_Splash),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_G_Fire),
+ EFFECT_SS_OVERLAY(Effect_Ss_Lightning),
+ EFFECT_SS_OVERLAY(Effect_Ss_Dt_Bubble),
+ EFFECT_SS_OVERLAY(Effect_Ss_Hahen),
+ EFFECT_SS_OVERLAY(Effect_Ss_Stick),
+ EFFECT_SS_OVERLAY(Effect_Ss_Sibuki),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_Stone1),
+ EFFECT_SS_OVERLAY(Effect_Ss_Hitmark),
+ EFFECT_SS_OVERLAY(Effect_Ss_Fhg_Flash),
+ EFFECT_SS_OVERLAY(Effect_Ss_K_Fire),
+ EFFECT_SS_OVERLAY(Effect_Ss_Solder_Srch_Ball),
+ EFFECT_SS_OVERLAY(Effect_Ss_Kakera),
+ EFFECT_SS_OVERLAY(Effect_Ss_Ice_Piece),
+ EFFECT_SS_OVERLAY(Effect_Ss_En_Ice),
+ EFFECT_SS_OVERLAY(Effect_Ss_Fire_Tail),
+ EFFECT_SS_OVERLAY(Effect_Ss_En_Fire),
+ EFFECT_SS_OVERLAY(Effect_Ss_Extra),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_Dead_Db),
+ EFFECT_SS_OVERLAY(Effect_Ss_Dead_Dd),
+ EFFECT_SS_OVERLAY(Effect_Ss_Dead_Ds),
+ EFFECT_SS_OVERLAY_UNSET,
+ EFFECT_SS_OVERLAY(Effect_Ss_Ice_Smoke),
+ EFFECT_SS_OVERLAY(Effect_En_Ice_Block),
+ EFFECT_SS_OVERLAY(Effect_Ss_Sbn),
+};
diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c
index 4303d3db2..1c69f57f3 100644
--- a/src/code/z_effect_soft_sprite_old_init.c
+++ b/src/code/z_effect_soft_sprite_old_init.c
@@ -124,32 +124,32 @@ void func_800B1054(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f*
EffectSsDust_Spawn(globalCtx, 1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 1);
}
-extern Color_RGBA8 D_801AE3B0;
-extern Color_RGBA8 D_801AE3B4;
+static Color_RGBA8 sDustBrownPrim = { 170, 130, 90, 255 };
+static Color_RGBA8 sDustBrownEnv = { 100, 60, 20, 255 };
void func_800B10C0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
- EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, 100, 5, 10, 0);
+ EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0);
}
void func_800B1130(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
- EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, 100, 5, 10, 0);
+ EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0);
}
void func_800B11A0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) {
- EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, 10, 0);
+ EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0);
}
void func_800B1210(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) {
- EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, 10, 0);
+ EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0);
}
void func_800B1280(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep,
s16 life) {
- EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, life, 0);
+ EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0);
}
void func_800B12F0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep,
s16 life) {
- EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, life, 0);
+ EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0);
}
void func_800B1360(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
@@ -206,12 +206,9 @@ void func_800B1598(GlobalContext* globalCtx, f32 randScale, Vec3f* srcPos) {
}
}
-extern Color_RGBA8 D_801AE3B8;
-extern Color_RGBA8 D_801AE3BC;
-
void EffectSsKiraKira_SpawnSmallYellow(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
- Color_RGBA8 primColor = D_801AE3B8;
- Color_RGBA8 envColor = D_801AE3BC;
+ Color_RGBA8 primColor = { 255, 255, 200, 255 };
+ Color_RGBA8 envColor = { 255, 200, 0, 0 };
EffectSsKiraKira_SpawnDispersed(globalCtx, pos, velocity, accel, &primColor, &envColor, 1000, 16);
}
@@ -307,12 +304,12 @@ void EffectSsBlast_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity,
EffectSs_Spawn(globalCtx, EFFECT_SS_BLAST, 128, &initParams);
}
-extern Color_RGBA8 D_801AE3C0;
-extern Color_RGBA8 D_801AE3C4;
-
void EffectSsBlast_SpawnWhiteCustomScale(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep, s16 life) {
- EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, &D_801AE3C0, &D_801AE3C4, scale, scaleStep, 35, life);
+ static Color_RGBA8 primColor = { 255, 255, 255, 255 };
+ static Color_RGBA8 envColor = { 200, 200, 200, 0 };
+
+ EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, &primColor, &envColor, scale, scaleStep, 35, life);
}
void EffectSsBlast_SpawnShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
@@ -320,11 +317,11 @@ void EffectSsBlast_SpawnShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* v
EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, primColor, envColor, 100, 375, 35, life);
}
-extern Color_RGBA8 D_801AE3C8;
-extern Color_RGBA8 D_801AE3CC;
-
void EffectSsBlast_SpawnWhiteShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
- EffectSsBlast_SpawnShockwave(globalCtx, pos, velocity, accel, &D_801AE3C8, &D_801AE3CC, 10);
+ static Color_RGBA8 primColor = { 255, 255, 255, 255 };
+ static Color_RGBA8 envColor = { 200, 200, 200, 0 };
+
+ EffectSsBlast_SpawnShockwave(globalCtx, pos, velocity, accel, &primColor, &envColor, 10);
}
// EffectSsGSpk Spawn Functions
@@ -364,24 +361,18 @@ void EffectSsGSpk_SpawnNoAccel(GlobalContext* globalCtx, Actor* actor, Vec3f* po
EffectSs_Spawn(globalCtx, EFFECT_SS_G_SPK, 128, &initParams);
}
-extern Color_RGBA8 D_801AE3D0;
-extern Color_RGBA8 D_801AE3D4;
-
void EffectSsGSpk_SpawnFuse(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
- Color_RGBA8 primColor = D_801AE3D0;
- Color_RGBA8 envColor = D_801AE3D4;
+ Color_RGBA8 primColor = { 255, 255, 150, 255 };
+ Color_RGBA8 envColor = { 255, 0, 0, 0 };
EffectSsGSpk_SpawnSmall(globalCtx, actor, pos, velocity, accel, &primColor, &envColor);
}
-extern Color_RGBA8 D_801AE3D8;
-extern Color_RGBA8 D_801AE3DC;
-
// unused
void EffectSsGSpk_SpawnRandColor(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
s16 scale, s16 scaleStep) {
- Color_RGBA8 primColor = D_801AE3D8;
- Color_RGBA8 envColor = D_801AE3DC;
+ Color_RGBA8 primColor = { 255, 255, 150, 255 };
+ Color_RGBA8 envColor = { 255, 0, 0, 0 };
s32 randOffset = (Rand_ZeroOne() * 20.0f) - 10.0f;
primColor.r += randOffset;
@@ -585,12 +576,10 @@ void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstSca
}
}
-extern Vec3f D_801AE3E0;
-
void func_800B2364(GlobalContext* globalCtx, Vec3f* pos, Gfx* dList) {
- Vec3f posVec = D_801AE3E0;
+ Vec3f accel = { 0.0f, -2.0f, 0.0f };
- EffectSsHahen_Spawn(globalCtx, pos, &gZeroVec3f, &posVec, 1, 5, 1, 10, dList);
+ EffectSsHahen_Spawn(globalCtx, pos, &gZeroVec3f, &accel, 1, 5, 1, 10, dList);
}
// EffectSsStick Spawn Functions
@@ -624,12 +613,9 @@ void EffectSsSibuki_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity,
EffectSs_Spawn(globalCtx, EFFECT_SS_SIBUKI, 128, &initParams);
}
-extern Vec3f D_801AE3EC;
-extern Vec3f D_801AE3F8;
-
void EffectSsSibuki_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos) {
s16 i;
- Vec3f zeroVec = D_801AE3EC;
+ Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
s16 randDirection = Rand_ZeroOne() * 1.99f;
for (i = 0; i < KREG(19) + 30; i++) {
@@ -759,11 +745,6 @@ void EffectSsIcePiece_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 scale, Vec
EffectSs_Spawn(globalCtx, EFFECT_SS_ICE_PIECE, 128, &initParams);
}
-extern Vec3f D_801AE3F8;
-extern Vec3f D_801AE404[10];
-
-#ifdef NON_MATCHING
-/* needs data migration to match */
void EffectSsIcePiece_SpawnBurst(GlobalContext* globalCtx, Vec3f* refPos, f32 scale) {
static Vec3f accel = { 0.0f, 0.0f, 0.0f };
static Vec3f vecScales[] = {
@@ -799,15 +780,11 @@ void EffectSsIcePiece_SpawnBurst(GlobalContext* globalCtx, Vec3f* refPos, f32 sc
&accel, 25);
}
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsIcePiece_SpawnBurst.s")
-#endif
// EffectSsEnIce Spawn Functions
void EffectSsEnIce_SpawnFlyingVec3f(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Color_RGBA8* prim,
Color_RGBA8* env, f32 scale) {
-
EffectSsEnIceInitParams initParams;
initParams.actor = actor;
@@ -824,11 +801,11 @@ void EffectSsEnIce_SpawnFlyingVec3f(GlobalContext* globalCtx, Actor* actor, Vec3
EffectSs_Spawn(globalCtx, EFFECT_SS_EN_ICE, 80, &initParams);
}
-extern Color_RGBA8 D_801AE47C;
-extern Color_RGBA8 D_801AE480;
-
void func_800B2B44(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 scale) {
- EffectSsEnIce_SpawnFlyingVec3f(globalCtx, actor, pos, &D_801AE47C, &D_801AE480, scale);
+ static Color_RGBA8 primColor = { 150, 150, 150, 250 };
+ static Color_RGBA8 envColor = { 235, 245, 255, 255 };
+
+ EffectSsEnIce_SpawnFlyingVec3f(globalCtx, actor, pos, &primColor, &envColor, scale);
}
void func_800B2B7C(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, f32 scale) {
@@ -874,29 +851,21 @@ void EffectSsFireTail_Spawn(GlobalContext* globalCtx, Actor* actor, Vec3f* pos,
EffectSs_Spawn(globalCtx, EFFECT_SS_FIRE_TAIL, 128, &initParams);
}
-extern Color_RGBA8 D_801AE484;
-extern Color_RGBA8 D_801AE488;
-
-#ifdef NON_MATCHING
-// needs data migration to match
void EffectSsFireTail_SpawnFlame(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 arg3, s16 bodyPart,
f32 colorIntensity) {
+ static Color_RGBA8 primColor = { 255, 255, 0, 255 };
+ static Color_RGBA8 envColor = { 255, 0, 0, 255 };
- D_801AE484.g = (s32)(255.0f * colorIntensity);
- D_801AE484.b = 0;
+ primColor.g = (s32)(255.0f * colorIntensity);
+ primColor.b = 0;
- D_801AE488.g = 0;
- D_801AE488.b = 0;
- D_801AE484.r = D_801AE488.r = (s32)(255.0f * colorIntensity);
+ envColor.g = 0;
+ envColor.b = 0;
+ primColor.r = envColor.r = (s32)(255.0f * colorIntensity);
- EffectSsFireTail_Spawn(globalCtx, actor, pos, arg3, &actor->velocity, 15, &D_801AE484, &D_801AE488,
+ EffectSsFireTail_Spawn(globalCtx, actor, pos, arg3, &actor->velocity, 15, &primColor, &envColor,
(colorIntensity == 1.0f) ? 0 : 1, bodyPart, 1);
}
-#else
-void EffectSsFireTail_SpawnFlame(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 arg3, s16 bodyPart,
- f32 colorIntensity);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsFireTail_SpawnFlame.s")
-#endif
void EffectSsFireTail_SpawnFlameOnPlayer(GlobalContext* globalCtx, f32 scale, s16 bodyPart, f32 colorIntensity) {
Player* player = GET_PLAYER(globalCtx);
@@ -982,12 +951,17 @@ void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity,
EffectSs_Spawn(globalCtx, EFFECT_SS_DEAD_DB, 120, &initParams);
}
-extern Color_RGBA8 D_801AE48C;
-extern Color_RGBA8 D_801AE490[4];
-
void func_800B3030(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep,
s32 colorIndex) {
- EffectSsDeadDb_Spawn(globalCtx, pos, velocity, accel, &D_801AE48C, &D_801AE490[colorIndex], scale, scaleStep, 9);
+ static Color_RGBA8 primColor = { 255, 255, 255, 255 };
+ static Color_RGBA8 envColors[] = {
+ { 255, 0, 0, 255 },
+ { 0, 255, 0, 255 },
+ { 0, 0, 255, 255 },
+ { 150, 150, 150, 255 },
+ };
+
+ EffectSsDeadDb_Spawn(globalCtx, pos, velocity, accel, &primColor, &envColors[colorIndex], scale, scaleStep, 9);
}
// EffectSsDeadDd Spawn Functions
diff --git a/src/code/z_en_hy.c b/src/code/z_en_hy.c
index 73adc5fa5..323dc14f8 100644
--- a/src/code/z_en_hy.c
+++ b/src/code/z_en_hy.c
@@ -66,7 +66,7 @@ Actor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx) {
f32 minDist = 0.0f;
do {
- doorIter = func_ActorCategoryIterateById(globalCtx, doorIter, ACTORCAT_DOOR, ACTOR_EN_DOOR);
+ doorIter = SubS_FindActor(globalCtx, doorIter, ACTORCAT_DOOR, ACTOR_EN_DOOR);
door = doorIter;
dist = Actor_DistanceBetweenActors(actor, door);
if (!isSetup || (dist < minDist)) {
diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c
index 595ffba90..ff564b7c0 100644
--- a/src/code/z_en_item00.c
+++ b/src/code/z_en_item00.c
@@ -829,29 +829,22 @@ s16 func_800A7650(s16 dropId) {
return dropId;
}
-#ifdef NON_MATCHING
-// Reordering issues
-EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) {
+Actor* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) {
s32 pad;
- EnItem00* spawnedActor = NULL;
- s32 pad2;
- s32 param10000;
- s16 param8000;
- s16 param7F00;
- s32 param20000;
- s32 paramFF;
+ Actor* spawnedActor = NULL;
+ s32 newParamFF;
+ s32 param10000 = params & 0x10000;
+ s16 param8000 = params & 0x8000;
+ s16 param7F00 = params & 0x7F00;
+ s32 param20000 = params & 0x20000;
+ s32 paramFF = params & 0xFF;
s32 i;
- param10000 = params & 0x10000;
- param8000 = params & 0x8000;
- param7F00 = params & 0x7F00;
- param20000 = params & 0x20000;
- paramFF = params & 0xFF;
-
params &= 0x7FFF;
+ newParamFF = params & 0xFF;
if (paramFF == ITEM00_3_HEARTS) {
- for (i = 0; i != 3; i++) {
+ for (i = 0; i < 3; i++) {
spawnedActor = Item_DropCollectible(globalCtx, spawnPos, param7F00 | ITEM00_HEART | param8000);
}
} else if (paramFF == ITEM00_MUSHROOM_CLOUD) {
@@ -860,20 +853,18 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_KINOKO, spawnPos->x, spawnPos->y, spawnPos->z, 0, 0,
0, param7F00);
}
- } else if (((paramFF == ITEM00_FLEXIBLE) || ((params & 0xFF) == ITEM00_BIG_FAIRY)) && (param10000 == 0)) {
- if ((params & 0xFF) == ITEM00_FLEXIBLE) {
- // TODO: fix cast, this actor is not an EnItem00
- spawnedActor =
- (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f,
+ } else if (((paramFF == ITEM00_FLEXIBLE) || (newParamFF == ITEM00_BIG_FAIRY)) && (param10000 == 0)) {
+ newParamFF = params & 0xFF;
+ if (newParamFF == ITEM00_FLEXIBLE) {
+ spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f,
spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102);
if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) {
Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
}
} else {
- // TODO: fix cast, this actor is not an EnItem00
- spawnedActor = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELFORG, spawnPos->x,
- spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0,
- ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7);
+ spawnedActor =
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f,
+ spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7);
if (param20000 == 0) {
if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) {
Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
@@ -882,59 +873,50 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa
}
} else {
if (param8000 == 0) {
- params = func_800A7650(params & 0xFF);
+ params = func_800A7650(newParamFF);
}
- if (params != (u32)ITEM00_NO_DROP) {
- spawnedActor = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x,
- spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param7F00);
+ if ((s32)params != ITEM00_NO_DROP) {
+ spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x, spawnPos->y,
+ spawnPos->z, 0, 0, 0, (s32)params | param8000 | param7F00);
if ((spawnedActor != NULL) && (param8000 == 0)) {
if (param10000 == 0) {
- spawnedActor->actor.velocity.y = 8.0f;
+ spawnedActor->velocity.y = 8.0f;
} else {
- spawnedActor->actor.velocity.y = -2.0f;
+ spawnedActor->velocity.y = -2.0f;
}
- spawnedActor->actor.speedXZ = 2.0f;
- spawnedActor->actor.gravity = -0.9f;
- spawnedActor->actor.world.rot.y = randPlusMinusPoint5Scaled(65536.0f);
- Actor_SetScale(&spawnedActor->actor, 0.0f);
- spawnedActor->actionFunc = func_800A6780;
- spawnedActor->unk152 = 0xDC;
- if ((spawnedActor->actor.params != ITEM00_SMALL_KEY) &&
- (spawnedActor->actor.params != ITEM00_HEART_PIECE) &&
- (spawnedActor->actor.params != ITEM00_HEART_CONTAINER)) {
- spawnedActor->actor.room = -1;
+ spawnedActor->speedXZ = 2.0f;
+ spawnedActor->gravity = -0.9f;
+ spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(65536.0f);
+ Actor_SetScale(spawnedActor, 0.0f);
+ ((EnItem00*)spawnedActor)->actionFunc = func_800A6780;
+ ((EnItem00*)spawnedActor)->unk152 = 0xDC;
+ if ((spawnedActor->params != ITEM00_SMALL_KEY) && (spawnedActor->params != ITEM00_HEART_PIECE) &&
+ (spawnedActor->params != ITEM00_HEART_CONTAINER)) {
+ spawnedActor->room = -1;
}
- spawnedActor->actor.flags |= 0x0010;
+ spawnedActor->flags |= 0x0010;
}
}
}
return spawnedActor;
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectible.s")
-#endif
-#ifdef NON_MATCHING
-// Regalloc, minor reordering
-Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) {
+Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, s32 params) {
Actor* spawnedActor = NULL;
- u32 pad;
- u32 param10000;
- s16 param8000;
- s16 param7F00;
+ s32 pad;
+ s32 param10000 = params & 0x10000;
+ s16 param8000 = params & 0x8000;
+ s16 param7F00 = params & 0x7F00;
- param10000 = params & 0x10000;
- param8000 = params & 0x8000;
- param7F00 = params & 0x7F00;
params &= 0xFF;
- if (params == ITEM00_3_HEARTS) {
+ if ((params & 0xFF) == ITEM00_3_HEARTS) {
return NULL;
}
- if (((params == ITEM00_FLEXIBLE) || (params == ITEM00_BIG_FAIRY)) && (param10000 == 0)) {
- if (params == ITEM00_FLEXIBLE) {
+ if ((((params & 0xFF) == ITEM00_FLEXIBLE) || ((params & 0xFF) == ITEM00_BIG_FAIRY)) && (param10000 == 0)) {
+ if ((params & 0xFF) == ITEM00_FLEXIBLE) {
spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f,
spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102);
} else {
@@ -946,10 +928,10 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para
Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
}
} else {
- params = func_800A7650(params);
- if (params != (u32)ITEM00_NO_DROP) {
+ params = func_800A7650(params & 0xFF);
+ if (params != ITEM00_NO_DROP) {
spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x, spawnPos->y,
- spawnPos->z, 0, 0, 0, params | param8000 | param7F00);
+ spawnPos->z, 0, 0, 0, (s32)params | param8000 | param7F00);
if (spawnedActor != NULL) {
if (param8000 == 0) {
spawnedActor->velocity.y = 0.0f;
@@ -968,9 +950,6 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para
return spawnedActor;
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectible2.s")
-#endif
u8 sDropTable[DROP_TABLE_SIZE * DROP_TABLE_NUMBER] = {
ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP, ITEM00_NO_DROP,
@@ -1048,17 +1027,14 @@ u8 sDropTableAmounts[DROP_TABLE_SIZE * DROP_TABLE_NUMBER] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};
-#ifdef NON_MATCHING
-// Many regalloc and reordering issues
void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3f* spawnPos, s16 params) {
EnItem00* spawnedActor;
u8 dropId;
s32 dropQuantity;
- s16 dropTableIndex;
- s16 param8000;
+ s16 dropTableIndex = Rand_ZeroOne() * 16.0f;
+ s16 param8000 = params & 0x8000;
+ u8 dropFlag;
- dropTableIndex = Rand_ZeroOne() * 16.0f;
- param8000 = params & 0x8000;
params &= 0x1F0;
if (params < 0x101) {
@@ -1066,50 +1042,54 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3
dropQuantity = sDropTableAmounts[params + dropTableIndex];
if (dropId == ITEM00_MASK) {
- dropQuantity = 1;
- if (gSaveContext.save.playerForm != PLAYER_FORM_GORON) {
- if (gSaveContext.save.playerForm != PLAYER_FORM_ZORA) {
- if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) {
- dropId = ITEM00_RUPEE_GREEN;
- } else {
- dropId = ITEM00_ARROWS_10;
- }
- } else {
+ switch (gSaveContext.save.playerForm) {
+ case PLAYER_FORM_HUMAN:
+ dropId = ITEM00_ARROWS_10;
+ break;
+ case PLAYER_FORM_ZORA:
dropId = ITEM00_HEART;
- }
- } else {
- dropId = ITEM00_MAGIC_SMALL;
+ break;
+ case PLAYER_FORM_GORON:
+ dropId = ITEM00_MAGIC_SMALL;
+ break;
+ default:
+ dropId = ITEM00_RUPEE_GREEN;
+ break;
}
+ dropQuantity = 1;
}
if (fromActor != NULL) {
- if (fromActor->dropFlag != 0) {
- if ((fromActor->dropFlag & 1) != 0) {
+ dropFlag = fromActor->dropFlag;
+ if (dropFlag != 0) {
+ if (fromActor->dropFlag & 1) {
+ params = 0x10;
dropId = ITEM00_ARROWS_30;
+ dropQuantity = 1;
+ } else if (fromActor->dropFlag & 2) {
params = 0x10;
- } else if ((fromActor->dropFlag & 2) != 0) {
dropId = ITEM00_HEART;
- params = 0x10;
- } else if ((fromActor->dropFlag & 0x20) != 0) {
+ dropQuantity = 1;
+ } else if (fromActor->dropFlag & 0x20) {
dropId = ITEM00_RUPEE_PURPLE;
+ dropQuantity = 1;
}
- dropQuantity = 1;
}
}
if (dropId == ITEM00_FLEXIBLE) {
- if (gSaveContext.save.playerData.health < 0x11) {
+ if (gSaveContext.save.playerData.health <= 0x10) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f,
spawnPos->z, 0, 0, 0, 2);
Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
return;
}
- if (gSaveContext.save.playerData.health < 0x31) {
+ if (gSaveContext.save.playerData.health <= 0x30) {
params = 0x10;
dropId = ITEM00_HEART;
dropQuantity = 3;
- } else if (gSaveContext.save.playerData.health < 0x51) {
+ } else if (gSaveContext.save.playerData.health <= 0x50) {
params = 0x10;
dropId = ITEM00_HEART;
dropQuantity = 1;
@@ -1134,6 +1114,8 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3
params = 0xA0;
dropId = ITEM00_RUPEE_RED;
dropQuantity = 1;
+ } else {
+ return;
}
}
@@ -1169,18 +1151,16 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3
}
}
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectibleRandom.s")
-#endif
-s32 D_801AE194[32] = { ITEM00_NO_DROP, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP,
- ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, ITEM00_NO_DROP, ITEM00_RUPEE_HUGE,
- ITEM00_COMPASS, ITEM00_MUSHROOM_CLOUD, ITEM00_HEART, ITEM00_3_HEARTS,
- ITEM00_HEART_PIECE, ITEM00_HEART_CONTAINER, ITEM00_MAGIC_SMALL, ITEM00_MAGIC_LARGE,
- ITEM00_FLEXIBLE, ITEM00_BIG_FAIRY, ITEM00_NO_DROP, ITEM00_NUTS_10,
- ITEM00_NO_DROP, ITEM00_BOMBS_A, ITEM00_NO_DROP, ITEM00_NO_DROP,
- ITEM00_NO_DROP, ITEM00_STICK, ITEM00_NO_DROP, ITEM00_NO_DROP,
- ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_ARROWS_10, ITEM00_ARROWS_30 };
+s32 D_801AE194[32] = {
+ ITEM00_NO_DROP, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP, ITEM00_RUPEE_RED,
+ ITEM00_RUPEE_PURPLE, ITEM00_NO_DROP, ITEM00_RUPEE_HUGE, ITEM00_COMPASS, ITEM00_MUSHROOM_CLOUD,
+ ITEM00_HEART, ITEM00_3_HEARTS, ITEM00_HEART_PIECE, ITEM00_HEART_CONTAINER, ITEM00_MAGIC_SMALL,
+ ITEM00_MAGIC_LARGE, ITEM00_FLEXIBLE, ITEM00_BIG_FAIRY, ITEM00_NO_DROP, ITEM00_NUTS_10,
+ ITEM00_NO_DROP, ITEM00_BOMBS_A, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP,
+ ITEM00_STICK, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP,
+ ITEM00_ARROWS_10, ITEM00_ARROWS_30,
+};
s32 func_800A8150(s32 index) {
if ((index < 0) || (index >= ARRAY_COUNT(D_801AE194))) {
@@ -1190,9 +1170,7 @@ s32 func_800A8150(s32 index) {
return D_801AE194[index];
}
-u8 D_801AE214[32] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
+u8 D_801AE214[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
s32 func_800A817C(s32 index) {
if ((index < 0) || (index >= ARRAY_COUNT(D_801AE214))) {
diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c
index 1ab44acc1..3255b86d8 100644
--- a/src/code/z_sub_s.c
+++ b/src/code/z_sub_s.c
@@ -1,6 +1,40 @@
-#include "global.h"
+/*
+ * File: z_sub_s.c
+ * Description: Various miscellaneous helpers
+ */
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A7C0.s")
+#include "global.h"
+#include "overlays/actors/ovl_En_Door/z_en_door.h"
+
+/**
+ * Finds the first EnDoor instance with unk_1A4 == 5 and the specified unk_1A5.
+ */
+EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5) {
+ Actor* actor = NULL;
+ EnDoor* door;
+
+ while (true) {
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_DOOR, ACTOR_EN_DOOR);
+ door = (EnDoor*)actor;
+
+ if (actor == NULL) {
+ break;
+ }
+
+ if ((door->unk_1A4 == 5) && (door->unk_1A5 == (u8)unk_1A5)) {
+ break;
+ }
+
+ if (actor->next == NULL) {
+ door = NULL;
+ break;
+ }
+
+ actor = actor->next;
+ }
+
+ return door;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s")
@@ -26,7 +60,40 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB34.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB7C.s")
+/**
+ * Finds the nearest actor instance of a specified Id and category to an actor.
+ */
+Actor* SubS_FindNearestActor(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId) {
+ Actor* actorIter = NULL;
+ Actor* actorTmp;
+ f32 dist;
+ Actor* closestActor = NULL;
+ f32 minDist = 99999.0f;
+ s32 isSetup = false;
+
+ do {
+ actorIter = SubS_FindActor(globalCtx, actorIter, actorCategory, actorId);
+
+ actorTmp = actorIter;
+ if (actorTmp == NULL) {
+ break;
+ }
+ actorIter = actorTmp;
+
+ if (actorIter != actor) {
+ dist = Actor_DistanceBetweenActors(actor, actorIter);
+ if (!isSetup || dist < minDist) {
+ closestActor = actorIter;
+ minDist = dist;
+ isSetup = true;
+ }
+ }
+
+ actorIter = actorIter->next;
+ } while (actorIter != NULL);
+
+ return closestActor;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BC6C.s")
@@ -68,7 +135,22 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D924.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_ActorCategoryIterateById.s")
+/**
+ * Finds the first actor instance of a specified Id and category.
+ */
+Actor* SubS_FindActor(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId) {
+ Actor* actor = actorListStart;
+
+ if (actor == NULL) {
+ actor = globalCtx->actorCtx.actorList[actorCategory].first;
+ }
+
+ while (actor != NULL && actorId != actor->id) {
+ actor = actor->next;
+ }
+
+ return actor;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D9C8.s")
@@ -100,7 +182,27 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E5CC.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E640.s")
+/**
+ * Finds the first actor instance of a specified Id and category verified with a custom callback.
+ * The callback should return `true` when the actor is succesfully verified.
+ */
+Actor* SubS_FindActorCustom(GlobalContext* globalCtx, Actor* actor, Actor* actorListStart, u8 actorCategory,
+ s16 actorId, void* verifyData, VerifyActor verifyActor) {
+ Actor* actorIter = actorListStart;
+
+ if (actorListStart == NULL) {
+ actorIter = globalCtx->actorCtx.actorList[actorCategory].first;
+ }
+
+ while (actorIter != NULL && (actorId != actorIter->id ||
+ (actorId == actorIter->id &&
+ (verifyActor == NULL ||
+ (verifyActor != NULL && !verifyActor(globalCtx, actor, actorIter, verifyData)))))) {
+ actorIter = actorIter->next;
+ }
+
+ return actorIter;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E748.s")
diff --git a/src/libultra/io/contchannelreset.c b/src/libultra/io/contchannelreset.c
index 5a66274a9..d0f1fbd9b 100644
--- a/src/libultra/io/contchannelreset.c
+++ b/src/libultra/io/contchannelreset.c
@@ -7,7 +7,7 @@ s32 __osContChannelReset(OSMesgQueue* mq, s32 channel) {
__osSiGetAccess();
- __osPfsPifRam.pifstatus = 1;
+ __osPfsPifRam.status = 1;
for (i = 0; i < channel; i++) {
*bufptr++ = 0;
diff --git a/src/libultra/io/contpfs.c b/src/libultra/io/contpfs.c
index 3dd0c96ca..fd4c4e459 100644
--- a/src/libultra/io/contpfs.c
+++ b/src/libultra/io/contpfs.c
@@ -1,6 +1,42 @@
#include "ultra64.h"
#include "global.h"
+__OSInode __osPfsInodeCache;
+OSViMode osViModeNtscHpn1 = {
+ 8, // type
+ {
+ // comRegs
+ 0x324E, // ctrl
+ 0x500, // width
+ 0x3E52239, // burst
+ 0x20C, // vSync
+ 0xC15, // hSync
+ 0xC150C15, // leap
+ 0x6C02EC, // hStart
+ 0x400, // xScale
+ 0, // vCurrent
+ },
+ { // fldRegs
+ {
+ // [0]
+ 0x500, // origin
+ 0x400, // yScale
+ 0x2301FD, // vStart
+ 0xE0204, // vBurst
+ 2, // vIntr
+ },
+ {
+ // [1]
+ 0xA00, // origin
+ 0x400, // yScale
+ 0x2501FF, // vStart
+ 0xE0204, // vBurst
+ 2, // vIntr
+ } },
+};
+s32 __osPfsInodeCacheChannel = -1;
+u8 __osPfsInodeCacheBank = 250;
+
u16 __osSumcalc(u8* ptr, s32 length) {
s32 i;
u32 sum = 0;
diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c
index 47b7968d3..b54d894f3 100644
--- a/src/libultra/io/contreaddata.c
+++ b/src/libultra/io/contreaddata.c
@@ -47,7 +47,7 @@ void __osPackReadData() {
__osContPifRam.ramarray[i] = 0;
}
- __osContPifRam.pifstatus = 1;
+ __osContPifRam.status = 1;
readformat.dummy = 255;
readformat.txsize = 1;
readformat.rxsize = 4;
diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c
index d84ba2d71..bd8270993 100644
--- a/src/libultra/io/controller.c
+++ b/src/libultra/io/controller.c
@@ -78,7 +78,7 @@ void __osPackRequestData(u8 poll) {
__osContPifRam.ramarray[i] = 0;
}
- __osContPifRam.pifstatus = 1;
+ __osContPifRam.status = 1;
ptr = (u8*)__osContPifRam.ramarray;
requestHeader.align = 255;
requestHeader.txsize = 1;
diff --git a/src/libultra/io/motor.c b/src/libultra/io/motor.c
index b8216dfc7..649a8b368 100644
--- a/src/libultra/io/motor.c
+++ b/src/libultra/io/motor.c
@@ -20,7 +20,7 @@ s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) {
}
__osSiGetAccess();
- osPifBuffers[pfs->channel].pifstatus = 1;
+ osPifBuffers[pfs->channel].status = 1;
buf += pfs->channel;
for (i = 0; i < BLOCKSIZE; i++) {
((__OSContRamReadFormat*)buf)->data[i] = vibrate;
diff --git a/src/libultra/io/pfsgetstatus.c b/src/libultra/io/pfsgetstatus.c
index 8127dde21..1d8e6dcf5 100644
--- a/src/libultra/io/pfsgetstatus.c
+++ b/src/libultra/io/pfsgetstatus.c
@@ -1,7 +1,75 @@
+#include "ultra64.h"
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetStatus.s")
+void __osPfsRequestOneChannel(s32 channel, u8 poll);
+void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData);
-#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsRequestOneChannel.s")
+s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) {
+ s32 ret = 0;
+ OSMesg msg;
+ OSContStatus data;
-#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetOneChannelData.s")
+ __osPfsInodeCacheBank = 250;
+
+ __osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS);
+ ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
+ osRecvMesg(queue, &msg, OS_MESG_BLOCK);
+
+ ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
+ osRecvMesg(queue, &msg, OS_MESG_BLOCK);
+
+ __osPfsGetOneChannelData(channel, &data);
+ if (((data.status & CONT_CARD_ON) != 0) && ((data.status & CONT_CARD_PULL) != 0)) {
+ return PFS_ERR_NEW_PACK;
+ } else if (data.errno || ((data.status & CONT_CARD_ON) == 0)) {
+ return PFS_ERR_NOPACK;
+ } else if ((data.status & CONT_ADDR_CRC_ER) != 0) {
+ return PFS_ERR_CONTRFAIL;
+ }
+ return ret;
+}
+
+void __osPfsRequestOneChannel(s32 channel, u8 poll) {
+ u8* bufptr;
+ __OSContRequestHeaderAligned req;
+ s32 idx;
+
+ __osContLastPoll = CONT_CMD_END;
+ __osPfsPifRam.status = CONT_CMD_READ_BUTTON;
+
+ bufptr = (u8*)&__osPfsPifRam;
+
+ req.txsize = 1;
+ req.rxsize = 3;
+ req.poll = poll;
+ req.typeh = 0xFF;
+ req.typel = 0xFF;
+ req.status = 0xFF;
+
+ for (idx = 0; idx < channel; idx++) {
+ *bufptr++ = 0;
+ }
+
+ *((__OSContRequestHeaderAligned*)bufptr) = req;
+ bufptr += sizeof(req);
+ *((u8*)bufptr) = CONT_CMD_END;
+}
+
+void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData) {
+ u8* bufptr = (u8*)&__osPfsPifRam;
+ __OSContRequestHeaderAligned req;
+ s32 idx;
+
+ for (idx = 0; idx < channel; idx++) {
+ bufptr++;
+ }
+
+ req = *((__OSContRequestHeaderAligned*)bufptr);
+ contData->errno = (req.rxsize & 0xC0) >> 4;
+ if (contData->errno) {
+ return;
+ }
+
+ contData->type = (req.typel << 8) | req.typeh;
+ contData->status = req.status;
+}
diff --git a/src/libultra/io/pfsisplug.c b/src/libultra/io/pfsisplug.c
index 358af0c98..474c7f914 100644
--- a/src/libultra/io/pfsisplug.c
+++ b/src/libultra/io/pfsisplug.c
@@ -55,7 +55,7 @@ void __osPfsRequestData(u8 poll) {
__osContLastPoll = poll;
- __osPfsPifRam.pifstatus = 1;
+ __osPfsPifRam.status = 1;
req.align = 0xFF;
req.txsize = 1;
diff --git a/src/libultra/io/pfsreadwritefile.c b/src/libultra/io/pfsreadwritefile.c
index bc2b9741c..b5ab6e4b4 100644
--- a/src/libultra/io/pfsreadwritefile.c
+++ b/src/libultra/io/pfsreadwritefile.c
@@ -1,5 +1,124 @@
+#include "ultra64.h"
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/__osPfsGetNextPage.s")
+#define CHECK_IPAGE(p, pfs) \
+ (((p).ipage >= (pfs).inodeStartPage) && ((p).inode_t.bank < (pfs).banks) && ((p).inode_t.page >= 0x01) && \
+ ((p).inode_t.page < 0x80))
-#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/osPfsReadWriteFile.s")
+s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page) {
+ s32 ret;
+
+ if (page->inode_t.bank != *bank) {
+ *bank = page->inode_t.bank;
+ if ((ret = __osPfsRWInode(pfs, inode, PFS_READ, *bank)) != 0) {
+ return ret;
+ }
+ }
+ *page = inode->inodePage[page->inode_t.page];
+
+ if (!CHECK_IPAGE(*page, *pfs)) {
+ if (page->ipage == PFS_EOF) {
+ return PFS_ERR_INVALID;
+ }
+ return PFS_ERR_INCONSISTENT;
+ }
+ return 0;
+}
+
+s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data) {
+ s32 ret;
+ __OSDir dir;
+ __OSInode inode;
+ __OSInodeUnit curPage;
+ s32 curBlock;
+ s32 blockSize;
+ u8* buffer;
+ u8 bank;
+ u16 blockno;
+
+ if ((fileNo >= pfs->dir_size) || (fileNo < 0)) {
+ return PFS_ERR_INVALID;
+ }
+ if ((size <= 0) || ((size % BLOCKSIZE) != 0)) {
+ return PFS_ERR_INVALID;
+ }
+ if ((offset < 0) || ((offset % BLOCKSIZE) != 0)) {
+ return PFS_ERR_INVALID;
+ }
+ if (!(pfs->status & PFS_INITIALIZED)) {
+ return PFS_ERR_INVALID;
+ }
+ if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) {
+ return PFS_ERR_NEW_PACK;
+ }
+ if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) {
+ return ret;
+ }
+ if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir)) != 0) {
+ return ret;
+ }
+ if ((dir.company_code == 0) || (dir.game_code == 0)) {
+ return PFS_ERR_INVALID;
+ }
+ if (!CHECK_IPAGE(dir.start_page, *pfs)) {
+ if (dir.start_page.ipage == PFS_EOF) {
+ return PFS_ERR_INVALID;
+ }
+ return PFS_ERR_INCONSISTENT;
+ }
+ if ((flag == PFS_READ) && ((dir.status & PFS_WRITTEN) == 0)) {
+ return PFS_ERR_BAD_DATA;
+ }
+
+ bank = 255;
+ curBlock = offset / BLOCKSIZE;
+ curPage = dir.start_page;
+
+ while (curBlock >= 8) {
+ if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) {
+ return ret;
+ }
+ curBlock -= 8;
+ }
+
+ blockSize = size / BLOCKSIZE;
+ buffer = data;
+
+ while (blockSize > 0) {
+ if (curBlock == 8) {
+ if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) {
+ return ret;
+ }
+ curBlock = 0;
+ }
+ if (pfs->activebank != curPage.inode_t.bank && (ret = __osPfsSelectBank(pfs, curPage.inode_t.bank)) != 0) {
+ return ret;
+ }
+
+ blockno = curPage.inode_t.page * PFS_ONE_PAGE + curBlock;
+ if (flag == PFS_READ) {
+ ret = __osContRamRead(pfs->queue, pfs->channel, blockno, buffer);
+ } else {
+ ret = __osContRamWrite(pfs->queue, pfs->channel, blockno, buffer, 0);
+ }
+ if (ret != 0) {
+ return ret;
+ }
+
+ buffer += BLOCKSIZE;
+ curBlock++;
+ blockSize--;
+ }
+
+ if (flag == PFS_WRITE && !(dir.status & PFS_WRITTEN)) {
+ dir.status |= PFS_WRITTEN;
+ if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) {
+ return ret;
+ }
+ if ((ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir, 0)) != 0) {
+ return ret;
+ }
+ }
+
+ return __osPfsGetStatus(pfs->queue, pfs->channel);
+}
diff --git a/src/libultra/voice/voicegetstatus.c b/src/libultra/voice/voicegetstatus.c
index 833f5ad27..d8e7edb67 100644
--- a/src/libultra/voice/voicegetstatus.c
+++ b/src/libultra/voice/voicegetstatus.c
@@ -12,7 +12,7 @@ s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) {
do {
if (ret != CONT_ERR_CONTRFAIL) {
- __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON;
+ __osContPifRam.status = CONT_CMD_READ_BUTTON;
for (i = 0; i < port; i++, *ptr++ = 0) {
;
diff --git a/src/overlays/actors/ovl_Boss_04/z_boss_04.c b/src/overlays/actors/ovl_Boss_04/z_boss_04.c
index 3e3ca12c1..ace591bb9 100644
--- a/src/overlays/actors/ovl_Boss_04/z_boss_04.c
+++ b/src/overlays/actors/ovl_Boss_04/z_boss_04.c
@@ -5,6 +5,7 @@
*/
#include "z_boss_04.h"
+#include "objects/object_boss04/object_boss04.h"
#define FLAGS 0x00000035
@@ -15,14 +16,18 @@ void Boss04_Destroy(Actor* thisx, GlobalContext* globalCtx);
void Boss04_Update(Actor* thisx, GlobalContext* globalCtx);
void Boss04_Draw(Actor* thisx, GlobalContext* globalCtx);
+void func_809EC544(Boss04* this);
void func_809EC568(Boss04* this, GlobalContext* globalCtx);
+void func_809ECD00(Boss04* this, GlobalContext* globalCtx);
void func_809ECD18(Boss04* this, GlobalContext* globalCtx);
+void func_809ECEF4(Boss04* this);
void func_809ECF58(Boss04* this, GlobalContext* globalCtx);
+void func_809ED224(Boss04* this);
void func_809ED2A0(Boss04* this, GlobalContext* globalCtx);
-#if 0
-// static DamageTable sDamageTable = {
-static DamageTable D_809EE150 = {
+static u8 D_809EE4D0;
+
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(1, 0xF),
/* Deku Stick */ DMG_ENTRY(1, 0xF),
/* Horse trample */ DMG_ENTRY(0, 0x0),
@@ -69,75 +74,777 @@ const ActorInit Boss_04_InitVars = {
(ActorFunc)Boss04_Draw,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_809EE190[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit1[1] = {
{
- { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK3,
+ { 0xF7CFFFFF, 0x00, 0x08 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 50 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_809EE1B4 = {
- { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 1, D_809EE190, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit1 = {
+ {
+ COLTYPE_HIT3,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit1,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_809EE1C4[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit2[1] = {
{
- { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK3,
+ { 0xF7CFFFFF, 0x00, 0x08 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 70 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_809EE1E8 = {
- { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 1, D_809EE1C4, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit2 = {
+ {
+ COLTYPE_METAL,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit2,
};
-#endif
+void func_809EC040(s32 index, ColliderJntSph* collider, Vec3f* arg2) {
+ collider->elements[index].dim.worldSphere.center.x = arg2->x;
+ collider->elements[index].dim.worldSphere.center.y = arg2->y;
+ collider->elements[index].dim.worldSphere.center.z = arg2->z;
+ collider->elements[index].dim.worldSphere.radius =
+ collider->elements[index].dim.modelSphere.radius * collider->elements[index].dim.scale;
+}
-extern DamageTable D_809EE150;
-extern ColliderJntSphElementInit D_809EE190[1];
-extern ColliderJntSphInit D_809EE1B4;
-extern ColliderJntSphElementInit D_809EE1C4[1];
-extern ColliderJntSphInit D_809EE1E8;
+void Boss04_Init(Actor* thisx, GlobalContext* globalCtx2) {
+ static Vec3f D_809EE1F8[] = {
+ { -1000.0f, 0.0f, 0.0f },
+ { 1000.0f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1000.0f },
+ { 0.0f, 0.0f, 1000.0f },
+ };
+ GlobalContext* globalCtx = globalCtx2;
+ Boss04* this = THIS;
+ s32 i;
+ CollisionPoly* spC0;
+ Vec3f spB4;
+ Vec3f spA8;
+ s32 spA4;
+ f32 phi_f20;
+ f32 phi_f24;
+ Vec3f sp90;
+ s16 phi_s0_2;
+ s32 pad;
-extern UNK_TYPE D_0600004C;
-extern UNK_TYPE D_06004510;
+ if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC040.s")
+ this->actor.params = 0x64;
+ Actor_SetScale(&this->actor, 0.1f);
+ this->actor.targetMode = 5;
+ this->actor.hintId = 0x19;
+ this->actor.colChkInfo.health = 20;
+ this->actor.colChkInfo.damageTable = &sDamageTable;
+ this->unk_700 = 1.0f;
+ this->unk_6FC = 1.0f;
+ this->unk_6F8 = 1.0f;
+ Collider_InitAndSetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit1, this->collider1Elements);
+ Collider_InitAndSetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit2, this->collider2Elements);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_boss04_Skel_0045E8, &object_boss04_Anim_00004C,
+ this->jointTable, this->morphtable, 9);
+ spA8.y = this->actor.world.pos.y + 200.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Init.s")
+ for (i = 0; i < ARRAY_COUNT(D_809EE1F8); i++) {
+ spA8.x = D_809EE1F8[i].x + this->actor.world.pos.x;
+ spA8.z = D_809EE1F8[i].z + this->actor.world.pos.z;
+ if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &spA8, &spB4, &spC0, 1, 0, 0, 1,
+ &spA4)) {
+ if (i == 0) {
+ this->unk_6D8 = spB4.x;
+ } else if (i == 1) {
+ this->unk_6DC = spB4.x;
+ } else if (i == 2) {
+ this->unk_6E0 = spB4.z;
+ } else if (i == 3) {
+ this->unk_6E4 = spB4.z;
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Destroy.s")
+ this->unk_6E8 = this->unk_6D8 + ((this->unk_6DC - this->unk_6D8) * 0.5f);
+ this->unk_6F0 = this->unk_6E0 + ((this->unk_6E4 - this->unk_6E0) * 0.5f);
+ this->actor.world.pos.x = this->unk_6E8;
+ this->actor.world.pos.z = this->unk_6F0;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 35.0f, 60.0f, 60.0f, 4);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC544.s")
+ if ((KREG(64) != 0) || (gSaveContext.eventInf[6] & 1)) {
+ func_809ECD00(this, globalCtx);
+ this->actor.world.pos.y = this->actor.floorHeight + 160.0f;
+ phi_f24 = this->actor.floorHeight;
+ D_809EE4D0 = KREG(41) + 50;
+ } else {
+ func_809EC544(this);
+ this->actor.world.pos.y = KREG(70) + (this->actor.floorHeight + 590.0f);
+ phi_f24 = KREG(71) + (this->actor.floorHeight + 550.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC568.s")
+ phi_f20 = 110.0f;
+ this->unk_6F6 = 82;
+ phi_s0_2 = 0;
+ for (i = 0; i < 82; i++) {
+ Matrix_RotateY(phi_s0_2, MTXMODE_NEW);
+ Matrix_GetStateTranslationAndScaledZ(phi_f20, &sp90);
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON2, this->unk_6E8 + sp90.x,
+ phi_f24, this->unk_6F0 + sp90.z, 0, 0, 0, i);
+ phi_f20 += 2.5f;
+ phi_s0_2 += 0x1300;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECD00.s")
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON2, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 100);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECD18.s")
+void Boss04_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECEF4.s")
+void func_809EC544(Boss04* this) {
+ this->actionFunc = func_809EC568;
+ this->actor.flags &= ~1;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECF58.s")
+void func_809EC568(Boss04* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ f32 x;
+ f32 y;
+ f32 z;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED224.s")
+ this->unk_704++;
+ this->unk_1FE = 15;
+ if ((this->unk_708 != 0) && (this->unk_708 < 10)) {
+ this->actor.world.pos.y = (Math_SinS(this->unk_1F4 * 512) * 10.0f) + (this->actor.floorHeight + 160.0f);
+ Matrix_RotateY(this->actor.yawTowardsPlayer, MTXMODE_NEW);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED2A0.s")
+ switch (this->unk_708) {
+ case 0:
+ this->unk_2C8 = 50;
+ this->unk_2D0 = 2000.0f;
+ if ((player->stateFlags1 & 0x100000) && (this->actor.projectedPos.z > 0.0f) &&
+ (fabsf(this->actor.projectedPos.x) < 300.0f) && (fabsf(this->actor.projectedPos.y) < 300.0f)) {
+ if ((this->unk_704 >= 15) && (ActorCutscene_GetCurrentIndex() == -1)) {
+ Actor* boss;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED45C.s")
+ this->unk_708 = 10;
+ this->unk_704 = 0;
+ func_800EA0D4(globalCtx, &globalCtx->csCtx);
+ this->unk_70A = func_801694DC(globalCtx);
+ func_80169590(globalCtx, 0, 1);
+ func_80169590(globalCtx, this->unk_70A, 7);
+ func_800B7298(globalCtx, &this->actor, 7);
+ player->actor.world.pos.x = this->unk_6E8;
+ player->actor.world.pos.z = this->unk_6F0 + 410.0f;
+ player->actor.shape.rot.y = 0x7FFF;
+ player->actor.world.rot.y = player->actor.shape.rot.y;
+ Math_Vec3f_Copy(&this->unk_70C, &player->actor.world.pos);
+ this->unk_70C.y += 100.0f;
+ Math_Vec3f_Copy(&this->unk_718, &this->actor.world.pos);
+ func_8016566C(150);
+ this->unk_744 = 60.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED50C.s")
+ boss = globalCtx->actorCtx.actorList[ACTORCAT_BOSS].first;
+ while (boss != NULL) {
+ if (boss->id == ACTOR_EN_WATER_EFFECT) {
+ Actor_MarkForDeath(boss);
+ }
+ boss = boss->next;
+ }
+ }
+ } else {
+ this->unk_704 = 0;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Update.s")
+ case 10:
+ if (this->unk_704 == 3) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_DEMO_EYE);
+ this->unk_74A = 1;
+ }
+ this->unk_2D0 = 10000.0f;
+ this->unk_2C8 = 300;
+ Math_ApproachF(&this->unk_744, 20.0f, 0.3f, 11.0f);
+ if (this->unk_704 == 40) {
+ this->unk_708 = 11;
+ this->unk_704 = 0;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EDCCC.s")
+ case 11:
+ if (this->unk_704 > 50) {
+ this->unk_708 = 12;
+ this->unk_704 = 0;
+ this->actor.gravity = -3.0f;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EDECC.s")
+ case 13:
+ if (this->unk_704 == 45) {
+ this->unk_708 = 1;
+ this->unk_704 = 0;
+ func_800B7298(globalCtx, &this->actor, 0x15);
+ this->actor.gravity = 0.0f;
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Draw.s")
+ case 12:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_ATTACK - SFX_FLAG);
+ Math_ApproachF(&this->unk_718.x, this->actor.world.pos.x, 0.5f, 1000.0f);
+ Math_ApproachF(&this->unk_718.y, this->actor.world.pos.y, 0.5f, 1000.0f);
+ Math_ApproachF(&this->unk_718.z, this->actor.world.pos.z, 0.5f, 1000.0f);
+ if (this->actor.bgCheckFlags & 2) {
+ play_sound(NA_SE_IT_BIG_BOMB_EXPLOSION);
+ this->unk_6F4 = 15;
+ this->unk_708 = 13;
+ this->unk_704 = 0;
+ this->unk_2DA = 10;
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_SPLASH);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KONB_JUMP_LEV_OLD - SFX_FLAG);
+ this->unk_748 = 20;
+ }
+ break;
+
+ case 1:
+ player->actor.shape.rot.y = 0x7FFF;
+ player->actor.world.rot.y = player->actor.shape.rot.y;
+ Matrix_GetStateTranslationAndScaledZ(-100.0f, &this->unk_70C);
+
+ this->unk_70C.x += player->actor.world.pos.x;
+ this->unk_70C.y = func_800B6FC8(player) + player->actor.world.pos.y + 36.0f;
+ this->unk_70C.z += player->actor.world.pos.z;
+
+ this->unk_718.x = player->actor.world.pos.x;
+ this->unk_718.y = (func_800B6FC8(player) + player->actor.world.pos.y) - 4.0f;
+ this->unk_718.z = player->actor.world.pos.z;
+
+ if (this->unk_704 >= 35) {
+ this->unk_704 = 0;
+ this->unk_708 = 2;
+ this->unk_728 = -200.0f;
+ }
+ break;
+
+ case 2:
+ case 3:
+ Matrix_GetStateTranslationAndScaledZ(500.0f, &this->unk_70C);
+ this->unk_70C.x += this->actor.world.pos.x;
+ this->unk_70C.y += this->actor.world.pos.y - 50.0f;
+ this->unk_70C.z += this->actor.world.pos.z;
+ this->unk_718.x = this->actor.world.pos.x;
+ this->unk_718.z = this->actor.world.pos.z;
+ this->unk_718.y = (this->actor.world.pos.y - 70.0f) + this->unk_728;
+ Math_ApproachZeroF(&this->unk_728, 0.05f, this->unk_73C);
+ Math_ApproachF(&this->unk_73C, 3.0f, 1.0f, 0.05f);
+ if (this->unk_704 == 20) {
+ this->unk_708 = 3;
+ }
+
+ if (this->unk_704 == 70) {
+ this->unk_2C8 = 300;
+ this->unk_2D0 = 0.0f;
+ D_809EE4D0 = 1;
+ this->unk_2E2 = 60;
+ this->unk_2E0 = 93;
+ }
+
+ if (this->unk_704 > 140) {
+ Camera* sp5C = Play_GetCamera(globalCtx, MAIN_CAM);
+
+ this->unk_708 = 0;
+ func_809ECD00(this, globalCtx);
+ sp5C->eye = this->unk_70C;
+ sp5C->eyeNext = this->unk_70C;
+ sp5C->at = this->unk_718;
+ func_80169AFC(globalCtx, this->unk_70A, 0);
+ this->unk_70A = 0;
+ func_800EA0EC(globalCtx, &globalCtx->csCtx);
+ func_800B7298(globalCtx, &this->actor, 6);
+ func_80165690();
+ gSaveContext.eventInf[6] |= 1;
+ }
+ break;
+ }
+
+ if (this->unk_70A != 0) {
+ Vec3f sp50;
+
+ ShrinkWindow_SetLetterboxTarget(0x1B);
+ if (this->unk_748 != 0) {
+ this->unk_748--;
+ }
+ Math_Vec3f_Copy(&sp50, &this->unk_718);
+ sp50.y += Math_SinS(this->unk_748 * 0x4000) * this->unk_748 * 1.5f;
+ Play_CameraSetAtEye(globalCtx, this->unk_70A, &sp50, &this->unk_70C);
+ func_80169940(globalCtx, this->unk_70A, this->unk_744);
+ Math_ApproachF(&this->unk_744, 60.0f, 0.1f, 1.0f);
+ }
+ this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
+ x = player->actor.world.pos.x - this->actor.world.pos.x;
+ y = player->actor.world.pos.y - this->actor.world.pos.y;
+ z = player->actor.world.pos.z - this->actor.world.pos.z;
+ this->actor.shape.rot.x = Math_Atan2S(-y, sqrtf(SQ(x) + SQ(z)));
+}
+
+void func_809ECD00(Boss04* this, GlobalContext* globalCtx) {
+ this->actionFunc = func_809ECD18;
+}
+
+void func_809ECD18(Boss04* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (this->unk_1F4 >= 0x500) {
+ this->unk_1F4 -= 0x300;
+ this->unk_1F7 += 1;
+ }
+
+ Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 10, 0x200);
+ this->actor.world.pos.y = (this->actor.floorHeight + KREG(17) + 160.0f) + (Math_SinS(this->unk_1F4 * 512) * 10.0f);
+ Math_ApproachF(&this->actor.speedXZ, this->unk_6D4, 1.0f, 0.5f);
+
+ if (this->unk_1F8 == 0) {
+ this->unk_1F8 = Rand_ZeroFloat(100.0f) + 50.0f;
+ this->unk_6D4 = Rand_ZeroFloat(3.0f);
+ if (Rand_ZeroOne() < 0.1f) {
+ Math_Vec3f_Copy(&this->unk_6C8, &player->actor.world.pos);
+ } else {
+ this->unk_6C8.x = randPlusMinusPoint5Scaled(600.0f) + this->unk_6E8;
+ this->unk_6C8.z = randPlusMinusPoint5Scaled(600.0f) + this->unk_6F0;
+ }
+ }
+
+ Math_ApproachS(&this->actor.world.rot.y,
+ Math_Atan2S(this->unk_6C8.x - this->actor.world.pos.x, this->unk_6C8.z - this->actor.world.pos.z), 5,
+ 0x200);
+
+ if (((s8)this->actor.colChkInfo.health <= 10) || (KREG(88) != 0)) {
+ KREG(88) = 0;
+ func_809ECEF4(this);
+ }
+}
+
+void func_809ECEF4(Boss04* this) {
+ this->actionFunc = func_809ECF58;
+ Math_Vec3s_Copy(&this->actor.world.rot, &this->actor.shape.rot);
+ this->unk_1F8 = 0;
+ this->unk_1F6 = 1;
+ this->unk_1FA = 60;
+ this->actor.speedXZ = 0.0f;
+ this->actor.gravity = -3.0f;
+}
+
+void func_809ECF58(Boss04* this, GlobalContext* globalCtx) {
+ Vec3f sp3C;
+
+ if ((this->unk_1FE == 14) || ((this->actor.bgCheckFlags & 8) && (this->unk_1F8 == 0))) {
+ this->unk_1F8 = 20;
+ if ((Rand_ZeroOne() < 0.2f) && (this->unk_1FE == 0)) {
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ this->unk_2D0 = 10000.0f;
+ this->unk_2C8 = 100;
+ } else {
+ this->actor.world.rot.y = BINANG_ROT180((s16)Rand_ZeroFloat(8000.0f) + this->actor.world.rot.y);
+ }
+
+ this->actor.speedXZ = 0.0f;
+
+ if (this->actor.bgCheckFlags & 8) {
+ play_sound(NA_SE_IT_BIG_BOMB_EXPLOSION);
+ func_800BC848(&this->actor, globalCtx, 15, 10);
+ this->unk_6F4 = 15;
+ sp3C.x = this->actor.focus.pos.x;
+ sp3C.y = this->actor.focus.pos.y;
+ sp3C.z = this->actor.focus.pos.z;
+ func_800BBFB0(globalCtx, &sp3C, 100.0f, 40, 500, 10, 0);
+ }
+ }
+
+ Math_ApproachS(&this->actor.shape.rot.x, Math_SinS(this->unk_1F4 * 0xFB8) * 5000.0f, 5, 0x800);
+ Math_ApproachS(&this->actor.shape.rot.z, Math_SinS(this->unk_1F4 * 0xCD0) * 3000.0f, 5, 0x800);
+
+ if (this->unk_6F4 == 0) {
+ Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 5, 0x1000);
+ if (this->unk_1FA == 0) {
+ Math_ApproachF(&this->actor.speedXZ, 20.0f, 1.0f, 1.0f);
+ sp3C.x = this->actor.world.pos.x;
+ sp3C.y = this->actor.floorHeight + 2.0f;
+ sp3C.z = this->actor.world.pos.z;
+ EffectSsGRipple_Spawn(globalCtx, &sp3C, 1400, 500, 0);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_ATTACK - SFX_FLAG);
+ }
+ }
+
+ if (KREG(88) != 0) {
+ KREG(88) = 0;
+ func_809ED224(this);
+ this->unk_1FE = 100;
+ this->unk_200 = 100;
+ }
+}
+
+void func_809ED224(Boss04* this) {
+ this->actionFunc = func_809ED2A0;
+ this->unk_1F8 = 60;
+ this->unk_1FA = 100;
+ this->actor.speedXZ = 0.0f;
+ this->unk_2D0 = 10000.0f;
+ this->unk_2C8 = 200;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_DEAD);
+ this->actor.flags &= ~1;
+ func_801A2ED8();
+ this->unk_1F6 = 10;
+}
+
+void func_809ED2A0(Boss04* this, GlobalContext* globalCtx) {
+ this->unk_2DA = 10;
+
+ if (this->unk_1F8 >= 5) {
+ this->unk_6FC = (Math_SinS(this->unk_1F8 * 0x3000) * 10.0f * 0.01f) + 1.0f;
+ this->unk_700 = (Math_CosS(this->unk_1F8 * 0x3000) * 10.0f * 0.01f) + 1.0f;
+ this->unk_6F8 = this->unk_700;
+ }
+
+ if (this->unk_1F8 == 5) {
+ this->unk_6F8 *= 1.3f;
+ this->unk_6FC *= 1.3f;
+ this->unk_700 *= 1.3f;
+ }
+
+ if (this->unk_1F8 == 3) {
+ this->actor.flags &= ~1;
+ this->unk_700 = 0.0f;
+ this->unk_6FC = 0.0f;
+ this->unk_6F8 = 0.0f;
+ }
+
+ if ((this->unk_1F8 == 2) || (this->unk_1F8 == 5)) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_EXPLOSION);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_BIG_BOMB_EXPLOSION);
+ }
+
+ if (this->unk_1FA == 3) {
+ this->unk_1F6 = 11;
+ }
+
+ if (this->unk_1FA == 0) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_809ED45C(Boss04* this, GlobalContext* globalCtx) {
+ ColliderJntSphElement* temp_v0;
+ u8 damage;
+
+ if ((this->unk_1FE == 0) && (this->collider1.elements[0].info.bumperFlags & BUMP_HIT)) {
+ this->collider1.elements[0].info.bumperFlags &= ~BUMP_HIT;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_DAMAGE);
+ damage = this->actor.colChkInfo.damage;
+ this->actor.colChkInfo.health = this->actor.colChkInfo.health - damage;
+ if ((s8)this->actor.colChkInfo.health <= 0) {
+ func_809ED224(this);
+ this->unk_1FE = 100;
+ this->unk_200 = 100;
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ } else {
+ this->unk_2DA = 15;
+ this->unk_1FE = 15;
+ this->unk_200 = 15;
+ }
+ }
+}
+
+void func_809ED50C(Boss04* this) {
+ s32 i;
+
+ this->unk_2DE += this->unk_2E2;
+ this->unk_2DC += this->unk_2E0;
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, 10.0f, MTXMODE_APPLY);
+ Matrix_GetStateTranslation(&this->unk_6BC);
+ Matrix_Scale(this->actor.scale.x * 13.0f, this->actor.scale.y * 13.0f, this->actor.scale.z * 16.0f, MTXMODE_APPLY);
+ Matrix_RotateY(this->unk_2DC, MTXMODE_APPLY);
+ Matrix_InsertXRotation_s(this->unk_2DE, MTXMODE_APPLY);
+ Matrix_StatePush();
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_2E4); i++) {
+ Matrix_RotateStateAroundXAxis(0.3926991f);
+ Matrix_GetStateTranslationAndScaledZ(100.0f, &this->unk_2E4[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(38.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_3A4); i++) {
+ Matrix_RotateStateAroundXAxis(0.41887903f);
+ Matrix_GetStateTranslationAndScaledZ(92.0f, &this->unk_3A4[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(-38.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_458); i++) {
+ Matrix_RotateStateAroundXAxis(0.41887903f);
+ Matrix_GetStateTranslationAndScaledZ(92.0f, &this->unk_458[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(71.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_50C); i++) {
+ Matrix_RotateStateAroundXAxis(0.5711987f);
+ Matrix_GetStateTranslationAndScaledZ(71.0f, &this->unk_50C[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(-71.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_590); i++) {
+ Matrix_RotateStateAroundXAxis(0.5711987f);
+ Matrix_GetStateTranslationAndScaledZ(71.0f, &this->unk_590[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(92.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_614); i++) {
+ Matrix_RotateStateAroundXAxis(1.0471976f);
+ Matrix_GetStateTranslationAndScaledZ(38.0f, &this->unk_614[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(-92.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_65C); i++) {
+ Matrix_RotateStateAroundXAxis(1.0471976f);
+ Matrix_GetStateTranslationAndScaledZ(38.0f, &this->unk_65C[i]);
+ }
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(100.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+
+ Matrix_GetStateTranslation(&this->unk_6A4);
+ Matrix_StatePop();
+ Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_GetStateTranslation(&this->unk_6B0);
+}
+
+void Boss04_Update(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ Boss04* this = THIS;
+ s16 temp_v0_8;
+ s32 pad;
+
+ this->unk_1F4++;
+ if (KREG(63) == 0) {
+ if (this->unk_1F8 != 0) {
+ this->unk_1F8--;
+ }
+
+ if (this->unk_1FA != 0) {
+ this->unk_1FA--;
+ }
+
+ if (this->unk_2C8 != 0) {
+ this->unk_2C8--;
+ }
+ if (this->unk_1FE != 0) {
+ this->unk_1FE--;
+ }
+
+ if (this->unk_200 != 0) {
+ this->unk_200--;
+ }
+
+ if (this->unk_2DA != 0) {
+ this->unk_2DA--;
+ }
+
+ if (this->unk_6F4 != 0) {
+ this->unk_6F4--;
+ }
+
+ this->actionFunc(this, globalCtx);
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ this->actor.world.pos.y -= 100.0f;
+ this->actor.prevPos.y -= 100.0f;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 100.0f, 120.0f, 200.0f, 5);
+ this->actor.world.pos.y += 100.0f;
+ this->actor.prevPos.y += 100.0f;
+ }
+
+ if (this->unk_200 == 10) {
+ this->unk_2D0 = 0.0f;
+ this->unk_2C8 = Rand_ZeroFloat(100.0f) + 60.0f;
+ }
+
+ if (this->unk_2C8 == 0) {
+ this->unk_2C8 = Rand_ZeroFloat(100.0f) + 60.0f;
+ this->unk_2D0 = 10000.0f - this->unk_2D0;
+ }
+
+ Math_ApproachF(&this->unk_2CC, this->unk_2D0, 0.2f, 1000.0f);
+ if (this->actionFunc != func_809ED2A0) {
+ temp_v0_8 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ if (ABS_ALT(temp_v0_8) < 0x6000) {
+ if (temp_v0_8 > 0x2500) {
+ this->unk_2D6 = 0x2500;
+ } else if (temp_v0_8 < -0x2500) {
+ this->unk_2D6 = -0x2500;
+ } else {
+ this->unk_2D6 = temp_v0_8;
+ }
+ } else {
+ this->unk_2D6 = 0;
+ }
+ Math_ApproachS(&this->unk_2D4, this->unk_2D6, 5, 0x800);
+ this->unk_2D8 = 2000;
+ this->unk_700 = (Math_SinS(this->unk_6F4 * 0x3000) * this->unk_6F4 * 0.02f) + 1.0f;
+ this->unk_6FC = (Math_CosS(this->unk_6F4 * 0x3000) * this->unk_6F4 * 0.02f) + 1.0f;
+ this->unk_6F8 = this->unk_6FC;
+ this->actor.shape.yOffset = (this->unk_6FC - 1.0f) * 1000.0f;
+ func_809ED45C(this, globalCtx);
+ if (this->unk_2CC > 3000.0f) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base);
+ this->actor.flags |= 1;
+ } else {
+ this->actor.flags &= ~1;
+ }
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ func_809ED50C(this);
+ }
+
+ if (D_809EE4D0 != 0) {
+ D_809EE4D0--;
+ if (D_809EE4D0 == 0) {
+ func_801A2E54(0x38);
+ }
+ }
+
+ if (this->unk_74A != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_EXIST - SFX_FLAG);
+ }
+}
+
+s32 Boss04_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ Boss04* this = THIS;
+
+ if (limbIndex == KREG(32)) {
+ if (!(this->unk_1F4 & 3)) {
+ *dList = NULL;
+ }
+ rot->x += KREG(33) * 256;
+ rot->y += KREG(34) * 256;
+ rot->z += KREG(35) * 256;
+ }
+
+ if ((limbIndex == 5) || (limbIndex == 7)) {
+ rot->y = (rot->y + (s16)this->unk_2CC) - 0x500;
+ }
+
+ if (limbIndex == 4) {
+ rot->y += this->unk_2D8;
+ rot->z += this->unk_2D4;
+ if (this->unk_2DA != 0) {
+ rot->y = (s16)(Math_SinS(this->unk_1F4 * 0x3000) * (this->unk_2DA * 500)) + rot->y;
+ rot->z = (s16)(Math_SinS(this->unk_1F4 * 0x3500) * (this->unk_2DA * 300)) + rot->z;
+ }
+ }
+
+ return false;
+}
+
+void Boss04_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f D_809EE228 = { 0.0f, -200.0f, 0.0f };
+ static Vec3f D_809EE234 = { 0.0f, 720.0f, 0.0f };
+ Boss04* this = THIS;
+ Vec3f sp18;
+
+ if (limbIndex == 1) {
+ Matrix_GetStateTranslationAndScaledY(-500.0f, &this->actor.focus.pos);
+ Matrix_MultiplyVector3fByState(&D_809EE228, &sp18);
+ func_809EC040(0, &this->collider1, &sp18);
+ Matrix_MultiplyVector3fByState(&D_809EE234, &sp18);
+ func_809EC040(0, &this->collider2, &sp18);
+ }
+}
+
+void Boss04_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ Boss04* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ if (this->unk_200 & 1) {
+ POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099);
+ }
+
+ Matrix_InsertTranslation(0.0f, 0.0f, 800.0f, MTXMODE_APPLY);
+ Matrix_Scale(this->unk_6F8, this->unk_6FC, this->unk_700, MTXMODE_APPLY);
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ Boss04_OverrideLimbDraw, Boss04_PostLimbDraw, &this->actor);
+
+ POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP);
+
+ if (this->actionFunc != func_809EC568) {
+ func_8012C448(globalCtx->state.gfxCtx);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 150);
+ gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_004510);
+
+ Matrix_InsertTranslation(this->unk_6BC.x, this->actor.floorHeight, this->unk_6BC.z, MTXMODE_NEW);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, -20.0f, MTXMODE_APPLY);
+ Matrix_Scale(this->unk_6F8 * 1.8f, 0.0f, this->unk_700 * 2.8f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_004550);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_Boss_04/z_boss_04.h b/src/overlays/actors/ovl_Boss_04/z_boss_04.h
index 7dec60d9c..f4542cf3a 100644
--- a/src/overlays/actors/ovl_Boss_04/z_boss_04.h
+++ b/src/overlays/actors/ovl_Boss_04/z_boss_04.h
@@ -9,9 +9,70 @@ typedef void (*Boss04ActionFunc)(struct Boss04*, GlobalContext*);
typedef struct Boss04 {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0xC0];
+ /* 0x0144 */ SkelAnime skelAnime;
+ /* 0x0188 */ Vec3s jointTable[9];
+ /* 0x01BE */ Vec3s morphtable[9];
+ /* 0x01F4 */ s16 unk_1F4;
+ /* 0x01F6 */ s8 unk_1F6;
+ /* 0x01F7 */ u8 unk_1F7;
+ /* 0x01F8 */ s16 unk_1F8;
+ /* 0x01FA */ s16 unk_1FA;
+ /* 0x01FC */ UNK_TYPE1 unk_1FC[2];
+ /* 0x01FE */ s16 unk_1FE;
+ /* 0x0200 */ s16 unk_200;
/* 0x0204 */ Boss04ActionFunc actionFunc;
- /* 0x0208 */ char unk_208[0x544];
+ /* 0x0208 */ ColliderJntSph collider1;
+ /* 0x0228 */ ColliderJntSphElement collider1Elements[1];
+ /* 0x0268 */ ColliderJntSph collider2;
+ /* 0x0288 */ ColliderJntSphElement collider2Elements[1];
+ /* 0x02C8 */ s16 unk_2C8;
+ /* 0x02CC */ f32 unk_2CC;
+ /* 0x02D0 */ f32 unk_2D0;
+ /* 0x02D4 */ s16 unk_2D4;
+ /* 0x02D6 */ s16 unk_2D6;
+ /* 0x02D8 */ s16 unk_2D8;
+ /* 0x02DA */ s16 unk_2DA;
+ /* 0x02DC */ s16 unk_2DC;
+ /* 0x02DE */ s16 unk_2DE;
+ /* 0x02E0 */ s16 unk_2E0;
+ /* 0x02E2 */ s16 unk_2E2;
+ /* 0x02E4 */ Vec3f unk_2E4[16];
+ /* 0x02E4 */ Vec3f unk_3A4[15];
+ /* 0x02E4 */ Vec3f unk_458[15];
+ /* 0x02E4 */ Vec3f unk_50C[11];
+ /* 0x02E4 */ Vec3f unk_590[11];
+ /* 0x02E4 */ Vec3f unk_614[6];
+ /* 0x02E4 */ Vec3f unk_65C[6];
+ /* 0x02E4 */ Vec3f unk_6A4;
+ /* 0x02E4 */ Vec3f unk_6B0;
+ /* 0x06BC */ Vec3f unk_6BC;
+ /* 0x06C8 */ Vec3f unk_6C8;
+ /* 0x06D4 */ f32 unk_6D4;
+ /* 0x06D8 */ f32 unk_6D8;
+ /* 0x06DC */ f32 unk_6DC;
+ /* 0x06E0 */ f32 unk_6E0;
+ /* 0x06E4 */ f32 unk_6E4;
+ /* 0x06E8 */ f32 unk_6E8;
+ /* 0x06EC */ UNK_TYPE1 unk_6EC[4];
+ /* 0x06F0 */ f32 unk_6F0;
+ /* 0x06F4 */ s16 unk_6F4;
+ /* 0x06F6 */ s16 unk_6F6;
+ /* 0x06F8 */ f32 unk_6F8;
+ /* 0x06FC */ f32 unk_6FC;
+ /* 0x0700 */ f32 unk_700;
+ /* 0x0704 */ u32 unk_704;
+ /* 0x0708 */ s16 unk_708;
+ /* 0x070A */ s16 unk_70A;
+ /* 0x070C */ Vec3f unk_70C;
+ /* 0x0718 */ Vec3f unk_718;
+ /* 0x0724 */ UNK_TYPE1 unk_724[4];
+ /* 0x0728 */ f32 unk_728;
+ /* 0x072C */ UNK_TYPE1 unk_72C[0x10];
+ /* 0x073C */ f32 unk_73C;
+ /* 0x0740 */ UNK_TYPE1 unk_740[4];
+ /* 0x0744 */ f32 unk_744;
+ /* 0x0748 */ s16 unk_748;
+ /* 0x074A */ u8 unk_74A;
} Boss04; // size = 0x74C
extern const ActorInit Boss_04_InitVars;
diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
index 7ea98689e..43b7d3feb 100644
--- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
+++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
@@ -464,7 +464,7 @@ void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx) {
Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye);
this->cutsceneSubCamId = SUBCAM_FREE;
if (this->actor.params == ENBIGPO_SUMMONED) {
- dampe = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_TK);
+ dampe = SubS_FindActor(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_TK);
if (dampe != NULL) {
// if dampe exists, switch to viewing his running away cutscene
dampe->params = this->actor.cutscene;
diff --git a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c
index 9e207b43a..95e8a0e1e 100644
--- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c
+++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c
@@ -2585,8 +2585,7 @@ void EnBigslime_ApplyDamageEffectBigslime(EnBigslime* this, GlobalContext* globa
EnBigslime_SetPlayerParams(this, globalCtx);
this->rotation = 0;
EnBigslime_SetupFreeze(this);
- minislime = (EnMinislime*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_ITEMACTION,
- ACTOR_ARROW_ICE);
+ minislime = (EnMinislime*)SubS_FindActor(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_ARROW_ICE);
if (minislime != NULL) {
minislime->shakeRefPos.z = -100.0f;
}
diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c
index 7648d83c6..7c39c53e5 100644
--- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c
+++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c
@@ -116,8 +116,7 @@ void func_809CCEE8(EnBji01* this, GlobalContext* globalCtx) {
return;
}
} else {
- this->moonsTear =
- (ObjMoonStone*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE);
+ this->moonsTear = (ObjMoonStone*)SubS_FindActor(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE);
}
func_800B8500(&this->actor, globalCtx, 60.0f, 10.0f, 0);
}
@@ -350,8 +349,7 @@ void EnBji01_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_SetScale(&this->actor, 0.01f);
func_8013E3B8(&this->actor, this->cutscenes,
ARRAY_COUNT(this->cutscenes)); /* initializes all elements of cutscenes to -1 */
- this->moonsTear =
- (ObjMoonStone*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE);
+ this->moonsTear = (ObjMoonStone*)SubS_FindActor(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE);
switch (gSaveContext.save.entranceIndex) {
case 0x4C00: /* Observatory from ECT */
diff --git a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h
index ce6fd6724..9ac9fafa0 100644
--- a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h
+++ b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h
@@ -10,7 +10,12 @@ typedef void (*EnBombalActionFunc)(struct EnBombal*, GlobalContext*);
typedef struct EnBombal {
/* 0x0000 */ Actor actor;
/* 0x0144 */ EnBombalActionFunc actionFunc;
- /* 0x0148 */ char unk_148[0x28FC];
+ /* 0x0148 */ char unk148[0x4];
+ /* 0x014C */ s16 unk_14C;
+ /* 0x0150 */ f32 unk_150;
+ /* 0x0154 */ char unk154[0x150];
+ /* 0x02A4 */ Vec3f unk_2A4;
+ /* 0x02B0 */ char unk2B0[0x2794];
} EnBombal; // size = 0x2A44
extern const ActorInit En_Bombal_InitVars;
diff --git a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c
index 5a003ef85..16eb0d18f 100644
--- a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c
+++ b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c
@@ -4,7 +4,9 @@
* Description: Bombers - Jim
*/
+#include "overlays/actors/ovl_En_Bombal/z_en_bombal.h"
#include "z_en_bomjima.h"
+#include "objects/object_cs/object_cs.h"
#define FLAGS 0x00000019
@@ -16,8 +18,11 @@ void EnBomjima_Update(Actor* thisx, GlobalContext* globalCtx);
void EnBomjima_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_80BFEA94(EnBomjima* this, GlobalContext* globalCtx);
+void func_80BFEB1C(EnBomjima* this);
void func_80BFEB64(EnBomjima* this, GlobalContext* globalCtx);
+void func_80BFEFF0(EnBomjima* this);
void func_80BFF03C(EnBomjima* this, GlobalContext* globalCtx);
+void func_80BFF120(EnBomjima* this);
void func_80BFF174(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFF430(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFF52C(EnBomjima* this, GlobalContext* globalCtx);
@@ -26,13 +31,17 @@ void func_80BFF754(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFF9B0(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFFB40(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFFBC4(EnBomjima* this, GlobalContext* globalCtx);
+void func_80BFFCFC(EnBomjima* this);
void func_80BFFD48(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFFE48(EnBomjima* this, GlobalContext* globalCtx);
void func_80BFFF54(EnBomjima* this, GlobalContext* globalCtx);
void func_80C00168(EnBomjima* this, GlobalContext* globalCtx);
+void func_80C00234(EnBomjima* this);
void func_80C00284(EnBomjima* this, GlobalContext* globalCtx);
-#if 0
+static s32 D_80C009F0 = 0;
+static s32 D_80C009F4 = 0;
+
const ActorInit En_Bomjima_InitVars = {
ACTOR_EN_BOMJIMA,
ACTORCAT_NPC,
@@ -45,83 +54,1075 @@ const ActorInit En_Bomjima_InitVars = {
(ActorFunc)EnBomjima_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80C00A18 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 10, 30, 0, { 0, 0, 0 } },
};
+static u16 D_80C00A44[] = {
+ 0x0719,
+ 0x071A,
+ 0x071B,
+ 0x0708,
+};
+
+static u16 D_80C00A4C[] = {
+ 0x0739,
+ 0x073A,
+ 0x073B,
+ 0x0000,
+};
+
+static u16 D_80C00A54[] = { 0x0739, 0x073A, 0x073B, 0x0714, 0x0709, 0x070A, 0x070B,
+ 0x070C, 0x070D, 0x070E, 0x070F, 0x0712, 0x0713 };
+
+static u16 D_80C00A70[] = { 0x0739, 0x073A, 0x073B, 0x0759, 0x0753, 0x0754, 0x0755,
+ 0x0756, 0x070D, 0x0757, 0x0758, 0x0712, 0x0713 };
+
+static u16 D_80C00A8C[] = {
+ 0x0736,
+ 0x0737,
+ 0x0738,
+ 0x074E,
+};
+
+static AnimationHeader* sAnimations[] = {
+ &object_cs_Anim_0064B8, &object_cs_Anim_00FAF4, &object_cs_Anim_0057C8, &object_cs_Anim_0053F4,
+ &object_cs_Anim_002044, &object_cs_Anim_01007C, &object_cs_Anim_00349C, &object_cs_Anim_004960,
+ &object_cs_Anim_005128, &object_cs_Anim_004C1C, &object_cs_Anim_001A1C, &object_cs_Anim_003EE4,
+ &object_cs_Anim_00478C, &object_cs_Anim_00433C, &object_cs_Anim_0060E8, &object_cs_Anim_001708,
+ &object_cs_Anim_005DC4, &object_cs_Anim_0026B0, &object_cs_Anim_0036B0, &object_cs_Anim_0031C4,
+};
+
+static u8 D_80C00AE4[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00,
+};
+
+void EnBomjima_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnBomjima* this = THIS;
+ s32 cs;
+ s32 i;
+
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 19.0f);
+ this->actor.gravity = -3.0f;
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &object_cs_Anim_0064B8, this->jointTable,
+ this->morphTable, 21);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ gSaveContext.save.weekEventReg[83] &= (u8)~0x4;
+ this->actor.targetMode = 0;
+ this->unk_2E6 = ENBOMJIMA_GET_F0(&this->actor);
+ this->unk_2E4 = ENBOMJIMA_GET_F(&this->actor);
+ Actor_SetScale(&this->actor, 0.01f);
+
+ if (this->unk_2E6 == 0) {
+ cs = this->actor.cutscene;
+ i = 0;
+
+ while (cs != -1) {
+ // clang-format off
+ this->unk_2D4[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs);
+ // clang-format on
+ i++;
+ }
+
+ this->actionFunc = func_80BFEA94;
+ } else if (this->unk_2E6 == 2) {
+ func_80BFFCFC(this);
+ }
+
+ if ((gSaveContext.save.weekEventReg[75] & 0x40) || (gSaveContext.save.weekEventReg[73] & 0x10) ||
+ (gSaveContext.save.weekEventReg[85] & 2)) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnBomjima_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnBomjima* this = THIS;
+
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
+
+void func_80BFE32C(EnBomjima* this, GlobalContext* globalCtx, s32 arg2) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ this->unk_2CA = arg2;
+ if (player->transformation == PLAYER_FORM_GORON) {
+ this->unk_2C8 = 1;
+ }
+ if (player->transformation == PLAYER_FORM_ZORA) {
+ this->unk_2C8 = 2;
+ }
+
+ switch (this->unk_2CA) {
+ case 0:
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ this->actor.textId = 0x759;
+ if (!(gSaveContext.save.weekEventReg[73] & 0x20)) {
+ this->actor.textId = 0x708;
+ }
+ } else if (player->transformation == PLAYER_FORM_HUMAN) {
+ this->actor.textId = 0x75A;
+ if (!(gSaveContext.save.weekEventReg[84] & 0x80)) {
+ this->actor.textId = 0x719;
+ }
+ } else if ((this->unk_2C8 == 1) || (this->unk_2C8 == 2)) {
+ this->actor.textId = D_80C00A44[this->unk_2C8];
+ }
+ break;
+
+ case 1:
+ this->actor.textId = D_80C00A4C[this->unk_2C8];
+ break;
+
+ case 2:
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ this->actor.textId = D_80C00A54[this->unk_2C8];
+ return;
+ }
+ this->actor.textId = D_80C00A70[this->unk_2C8];
+ break;
+
+ case 3:
+ this->actor.textId = D_80C00A8C[this->unk_2C8];
+ break;
+ }
+}
+
+void func_80BFE494(EnBomjima* this, s32 arg1, f32 arg2) {
+ this->unk_2EC = arg1;
+ this->unk_2CC = Animation_GetLastFrame(sAnimations[arg1]);
+ Animation_Change(&this->skelAnime, sAnimations[this->unk_2EC], arg2, 0.0f, this->unk_2CC, D_80C00AE4[this->unk_2EC],
+ -4.0f);
+}
+
+void func_80BFE524(EnBomjima* this) {
+ if ((this->unk_2EC == 5) &&
+ (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) ||
+ Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 18.0f))) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK);
+ }
+
+ if ((this->unk_2EC == 18) &&
+ (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 2.0f) ||
+ Animation_OnFrame(&this->skelAnime, 4.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK);
+ }
+
+ if ((this->unk_2EC == 15) && Animation_OnFrame(&this->skelAnime, 15.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND);
+ }
+
+ if ((this->unk_2EC == 6) && Animation_OnFrame(&this->skelAnime, 8.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND);
+ }
+}
+
+void func_80BFE65C(EnBomjima* this) {
+ this->unk_2BC = 0;
+ this->unk_2C0 = 0;
+ this->unk_2BE = 0;
+ this->unk_2A2 = 0;
+ this->unk_290 = 0;
+ this->unk_29A = 0;
+}
+
+void func_80BFE67C(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 sp84 = this->skelAnime.curFrame;
+ f32 x;
+ f32 z;
+ s16 abs;
+ s16 abs2;
+ Vec3f sp6C;
+ Vec3f sp60;
+ Vec3f sp54;
+ CollisionPoly* sp50;
+ s32 sp4C;
+
+ this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4);
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+
+ switch (this->unk_2A2) {
+ case 0:
+ if (this->unk_2C0 == 0) {
+ Math_Vec3f_Copy(&sp54, &this->actor.home.pos);
+
+ sp54.x += randPlusMinusPoint5Scaled(150.0f);
+ sp54.z += randPlusMinusPoint5Scaled(150.0f);
+
+ abs = ABS_ALT(BINANG_SUB(this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp54)));
+ if ((abs < 0x4000) && !BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp54, &sp6C,
+ &sp50, 1, 0, 0, 1, &sp4C)) {
+ func_80BFE494(this, 5, 1.0f);
+ Math_Vec3f_Copy(&this->unk_2A4, &sp54);
+ this->unk_2BE = Rand_S16Offset(30, 50);
+ this->unk_2A2++;
+ }
+ }
+ break;
+
+ case 1:
+ if (sp84 >= 0.0f) {
+ this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4);
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 10, 2000, 20);
+ }
+
+ abs2 = BINANG_SUB(this->actor.world.rot.y, this->unk_2DC);
+ if ((s16)ABS_ALT(abs2) < 0x100) {
+ Math_Vec3f_Copy(&sp60, &this->actor.world.pos);
+
+ sp60.x += Math_SinS(this->actor.world.rot.y) * 60.0f;
+ sp60.z += Math_CosS(this->actor.world.rot.y) * 60.0f;
+
+ if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp60, &sp6C, &sp50, 1, 0, 0, 1,
+ &sp4C)) {
+ this->unk_2C0 = 0;
+ if (Rand_ZeroOne() < 0.5f) {
+ func_80BFE494(this, 19, 1.0f);
+ } else {
+ func_80BFE494(this, 0, 1.0f);
+ }
+ this->unk_2A2 = 0;
+ this->unk_2D0 = 0.0f;
+ break;
+ }
+ }
+
+ x = this->unk_2A4.x - this->actor.world.pos.x;
+ z = this->unk_2A4.z - this->actor.world.pos.z;
+
+ if ((this->unk_2BE == 0) || (sqrtf(SQ(x) + SQ(z)) < 4.0f)) {
+ this->unk_2C0 = Rand_S16Offset(20, 20);
+ if (!(this->unk_2C0 & 1)) {
+ func_80BFE494(this, 19, 1.0f);
+ } else {
+ func_80BFE494(this, 0, 1.0f);
+ }
+ this->unk_2A2 = 0;
+ this->unk_2D0 = 0.0f;
+ } else if (sp84 >= 0.0f) {
+ Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, this->unk_2D0);
+ Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, this->unk_2D0);
+ Math_ApproachF(&this->unk_2D0, 1.0f, 0.3f, 0.5f);
+ }
+ break;
+ }
+}
+
+void func_80BFEA94(EnBomjima* this, GlobalContext* globalCtx) {
+ Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first;
+
+ while (actor != NULL) {
+ if (actor->id != ACTOR_EN_BOMBAL) {
+ actor = actor->next;
+ continue;
+ }
+
+ this->unk_2F0 = (EnBombal*)actor;
+ Math_Vec3f_Copy(&this->unk_2B0, &actor->world.pos);
+ if (this->unk_2F4 == 0) {
+ this->unk_2F4 = this->unk_2F0->actor.cutscene;
+ }
+ func_80BFEB1C(this);
+ break;
+ }
+}
+
+void func_80BFEB1C(EnBomjima* this) {
+ func_80BFE494(this, 1, 1.0f);
+ func_80BFE65C(this);
+ this->unk_2A0 = 0;
+ this->actionFunc = func_80BFEB64;
+}
+
+void func_80BFEB64(EnBomjima* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s32 pad[2];
+ Vec3f sp40;
+
+ func_80BFE32C(this, globalCtx, 0);
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ if (gSaveContext.save.weekEventReg[73] & 0x20) {
+ this->unk_2C8 = 3;
+ func_80BFE32C(this, globalCtx, 3);
+ } else if (gSaveContext.save.weekEventReg[77] & 2) {
+ this->unk_2C8 = 11;
+ func_80BFE32C(this, globalCtx, 2);
+ }
+ } else if (player->transformation == PLAYER_FORM_HUMAN) {
+ if (gSaveContext.save.weekEventReg[84] & 0x80) {
+ this->unk_2C8 = 0;
+ func_80BFE32C(this, globalCtx, 3);
+ } else if (gSaveContext.save.weekEventReg[85] & 1) {
+ this->unk_2C8 = 11;
+ func_80BFE32C(this, globalCtx, 2);
+ }
+ }
+
+ if (Text_GetFaceReaction(globalCtx, 0x11) != 0) {
+ this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11);
+ }
+
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ this->unk_2DC = this->actor.yawTowardsPlayer;
+ func_80C00234(this);
+ return;
+ }
+
+ if (ActorCutscene_GetCurrentIndex() == -1) {
+ func_800B8614(&this->actor, globalCtx, 70.0f);
+ }
+
+ if ((this->unk_2F0->actor.update == NULL) || (this->unk_2F0->actor.colChkInfo.health == 0)) {
+ func_80BFEFF0(this);
+ return;
+ }
+
+ switch (this->unk_2A2) {
+ case 0:
+ func_80BFE494(this, 4, 1.0f);
+ this->unk_29A = -7000;
+ this->unk_2A2++;
+ break;
+
+ case 1:
+ this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2F0->actor.world.pos);
+ if (Animation_OnFrame(&this->skelAnime, 19.0f)) {
+ this->unk_2C0 = 5;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_SHOT_BREATH);
+ }
+
+ if (this->unk_2C0 == 1) {
+ s16 sp3E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2F0->actor.world.pos);
+
+ if (Rand_ZeroOne() < 0.5f) {
+ sp3E += 0x4000;
+ } else {
+ sp3E += 0xC000;
+ }
+
+ sp40.x = (Math_SinS(sp3E) * (Rand_ZeroFloat(20.0f) + 40.0f)) + this->unk_2F0->actor.world.pos.x;
+ sp40.y = this->unk_2F0->actor.world.pos.y - randPlusMinusPoint5Scaled(40.0f);
+ sp40.z = (Math_CosS(sp3E) * (Rand_ZeroFloat(20.0f) + 40.0f)) + this->unk_2F0->actor.world.pos.z;
+
+ Audio_PlaySoundAtPosition(globalCtx, &sp40, 50, NA_SE_EV_BOMBERS_SHOT_EXPLOSUIN);
+ EffectSsHitMark_SpawnFixedScale(globalCtx, 0, &sp40);
+ this->unk_2BC++;
+
+ if (((s16)Rand_ZeroFloat(2.0f) + 3) < this->unk_2BC) {
+ func_80BFE494(this, 5, 1.0f);
+ this->unk_29A = 0;
+ Math_Vec3f_Copy(&this->unk_2A4, &this->actor.home.pos);
+ this->unk_2A4.x += randPlusMinusPoint5Scaled(150.0f);
+ this->unk_2A4.z += randPlusMinusPoint5Scaled(150.0f);
+ this->unk_2A2++;
+ }
+ }
+ break;
+
+ case 2:
+ this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4);
+ Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 2.0f);
+ Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 2.0f);
+ if (sqrtf(SQ(this->actor.world.pos.x - this->unk_2A4.x) + SQ(this->actor.world.pos.z - this->unk_2A4.z)) <
+ 4.0f) {
+ func_80BFE65C(this);
+ }
+ break;
+ }
+
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+}
+
+void func_80BFEFF0(EnBomjima* this) {
+ this->unk_2F0 = NULL;
+ func_80BFE494(this, 19, 1.0f);
+ func_80BFE65C(this);
+ this->unk_2A0 = 1;
+ this->actionFunc = func_80BFF03C;
+}
+
+void func_80BFF03C(EnBomjima* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ ActorCutscene_SetIntentToPlay(this->unk_2D4[0]);
+ } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D4[0])) {
+ ActorCutscene_SetIntentToPlay(this->unk_2D4[0]);
+ } else {
+ player->stateFlags1 &= ~0x20;
+ gSaveContext.save.weekEventReg[83] &= (u8)~4;
+ this->actor.world.rot.y = func_800DFCDC(GET_ACTIVE_CAM(globalCtx));
+ this->unk_2DC = func_800DFCDC(GET_ACTIVE_CAM(globalCtx));
+ ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D4[0], &this->actor);
+ func_80BFF120(this);
+ }
+}
+
+void func_80BFF120(EnBomjima* this) {
+ func_80BFE65C(this);
+ this->unk_2C4 = 30;
+ func_80BFE494(this, 6, 1.0f);
+ this->unk_2DE = 0;
+ this->unk_2A0 = 2;
+ this->actionFunc = func_80BFF174;
+}
+
+void func_80BFF174(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 sp2C = this->skelAnime.curFrame;
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (this->unk_2C4 == 1) {
+ ActorCutscene_Stop(this->unk_2D4[0]);
+ this->unk_2DE = 1;
+ }
+
+ if (Text_GetFaceReaction(globalCtx, 0x11) != 0) {
+ this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11);
+ }
+
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ this->unk_2DC = this->actor.yawTowardsPlayer;
+ func_80C00234(this);
+ return;
+ }
+
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+
+ if ((this->unk_2CC <= sp2C) && (this->unk_2BC < 5)) {
+ this->unk_2BC++;
+ if (this->unk_2EC != 19) {
+ func_80BFE494(this, 19, 1.0f);
+ }
+ }
+
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ if (gSaveContext.save.weekEventReg[73] & 0x20) {
+ this->unk_2C8 = 3;
+ func_80BFE32C(this, globalCtx, 3);
+ } else {
+ if (!(gSaveContext.save.weekEventReg[77] & 2)) {
+ if (this->unk_2E8 == 0) {
+ this->unk_2C8 = 4;
+ } else {
+ this->unk_2C8 = 3;
+ }
+ } else {
+ this->unk_2C8 = 11;
+ }
+ func_80BFE32C(this, globalCtx, 2);
+ }
+ } else if (player->transformation == PLAYER_FORM_HUMAN) {
+ if (gSaveContext.save.weekEventReg[84] & 0x80) {
+ this->unk_2C8 = 0;
+ func_80BFE32C(this, globalCtx, 3);
+ } else {
+ if (!(gSaveContext.save.weekEventReg[85] & 1)) {
+ if (this->unk_2EA == 0) {
+ this->unk_2C8 = 4;
+ } else {
+ this->unk_2C8 = 3;
+ }
+ } else {
+ this->unk_2C8 = 11;
+ }
+ func_80BFE32C(this, globalCtx, 2);
+ }
+ } else if (this->unk_2CA != 1) {
+ func_80BFE32C(this, globalCtx, 1);
+ }
+
+ if (this->unk_2DE != 0) {
+ if (this->unk_2BC >= 5) {
+ func_80BFE67C(this, globalCtx);
+ }
+ func_800B8614(&this->actor, globalCtx, 70.0f);
+ }
+}
+
+void func_80BFF3F0(EnBomjima* this) {
+ func_80BFE494(this, 15, 1.0f);
+ this->unk_2A0 = 3;
+ this->actionFunc = func_80BFF430;
+}
+
+void func_80BFF430(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if (this->unk_2CC <= curFrame) {
+ EnBombal* bombal = (EnBombal*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOMBAL, this->unk_2B0.x,
+ this->unk_2B0.y, this->unk_2B0.z, 0, 0, 0, 0);
+
+ if (bombal != NULL) {
+ bombal->unk_150 = 0.0f;
+ bombal->unk_14C = this->unk_2F4;
+ func_800B86C8(&this->actor, globalCtx, &bombal->actor);
+ gSaveContext.save.weekEventReg[83] &= (u8)~4;
+ func_80BFE65C(this);
+ func_801477B4(globalCtx);
+ this->actionFunc = func_80BFEA94;
+ }
+ }
+}
+
+void func_80BFF4F4(EnBomjima* this) {
+ func_80BFE65C(this);
+ this->unk_2A0 = 4;
+ this->actionFunc = func_80BFF52C;
+}
+
+void func_80BFF52C(EnBomjima* this, GlobalContext* globalCtx) {
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ func_8019F208();
+ func_80BFE65C(this);
+ this->unk_28E = 0;
+ this->unk_29A = 0;
+ this->unk_2C8 = 8;
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ this->actor.textId = D_80C00A54[this->unk_2C8];
+ } else {
+ this->actor.textId = D_80C00A70[this->unk_2C8];
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ play_sound(NA_SE_SY_FOUND);
+ func_80BFE494(this, 15, 1.0f);
+ this->unk_2A0 = 5;
+ this->actionFunc = func_80BFF6CC;
+ } else {
+ Player* player = GET_PLAYER(globalCtx);
+
+ func_8019F230();
+ func_80BFE65C(this);
+ this->unk_2C8 = 10;
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ this->actor.textId = D_80C00A54[this->unk_2C8];
+ this->unk_2E8 = 1;
+ } else {
+ this->actor.textId = D_80C00A70[this->unk_2C8];
+ this->unk_2EA = 1;
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ func_80C00234(this);
+ }
+ }
+}
+
+void func_80BFF6CC(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if (this->unk_2CC <= curFrame) {
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ func_80BFE494(this, 1, 1.0f);
+ this->actionFunc = func_80BFF754;
+ }
+ }
+}
+
+#ifdef NON_EQUIVALENT
+// Data indexing is wrong
+
+typedef struct {
+ /* 0x00 */ s16 unk_00;
+ /* 0x02 */ s16 unk_02;
+} EnBombjimaStruct;
+
+void func_80BFF754(EnBomjima* this, GlobalContext* globalCtx) {
+ static EnBombjimaStruct D_80C00AF8[] = {
+ { 0x4000, 0x003C },
+ { 0x4000, 0x001E },
+ { 0xC000, 0x001E },
+ { 0xC000, 0x003C },
+ };
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f spA0;
+ EnBombal* temp_s3;
+ s32 i;
+ f32 x;
+ f32 y;
+ f32 z;
+
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ ActorCutscene_SetIntentToPlay(this->unk_2D4[1]);
+ return;
+ }
+
+ if (!ActorCutscene_GetCanPlayNext(this->unk_2D4[1])) {
+ ActorCutscene_SetIntentToPlay(this->unk_2D4[1]);
+ return;
+ }
+
+ for (i = 1; i < 5; i++) {
+ Math_Vec3f_Copy(&spA0, &player->actor.world.pos);
+
+ x = spA0.x - this->actor.world.pos.x;
+ y = spA0.y - this->actor.world.pos.y;
+ z = spA0.z - this->actor.world.pos.z;
+
+ spA0.x += x * (2.0f + (i * 0.2f));
+ spA0.y += y * (2.0f + (i * 0.2f));
+ spA0.z += z * (2.0f + (i * 0.2f));
+
+ temp_s3 = (EnBombal*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOMJIMA, spA0.x,
+ spA0.y, spA0.z, 0, 0, 0, i + 32);
+ if (temp_s3 != NULL) {
+ s32 idx1 = (i * 2) - 1;
+ s32 idx2 = i * 2;
+
+ Math_Vec3f_Copy(&spA0, &this->actor.world.pos);
+
+ spA0.x += Math_SinS(D_80C00AF8[idx1 - 1].unk_00 + this->actor.world.rot.y) * D_80C00AF8[idx2].unk_02;
+ spA0.z += Math_CosS(D_80C00AF8[idx2].unk_00 + this->actor.world.rot.y) * D_80C00AF8[idx2].unk_02;
+
+ Math_Vec3f_Copy(&temp_s3->unk_2A4, &spA0);
+ }
+ }
+
+ D_80C009F0 = 0;
+ ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D4[1], &this->actor);
+ this->actionFunc = func_80BFF9B0;
+}
+#else
+static s16 D_80C00AF8[][2] = {
+ { 0x4000, 0x003C },
+ { 0x4000, 0x001E },
+ { 0xC000, 0x001E },
+ { 0xC000, 0x003C },
+};
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF754.s")
#endif
-extern ColliderCylinderInit D_80C00A18;
+void func_80BFF9B0(EnBomjima* this, GlobalContext* globalCtx) {
+ if (D_80C009F0 >= 4) {
+ Player* player = GET_PLAYER(globalCtx);
-extern UNK_TYPE D_060064B8;
+ D_80C009F0 = 0;
+ this->unk_2C8 = 9;
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ gSaveContext.save.weekEventReg[73] |= 0x10;
+ gSaveContext.save.weekEventReg[77] |= 2;
+ } else {
+ gSaveContext.save.weekEventReg[85] |= 2;
+ gSaveContext.save.weekEventReg[85] |= 1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Init.s")
+ gSaveContext.save.weekEventReg[11] &= (u8)~1;
+ gSaveContext.save.weekEventReg[11] &= (u8)~2;
+ gSaveContext.save.weekEventReg[11] &= (u8)~4;
+ gSaveContext.save.weekEventReg[11] &= (u8)~8;
+ gSaveContext.save.weekEventReg[11] &= (u8)~0x10;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Destroy.s")
+ gSaveContext.save.weekEventReg[76] &= (u8)~1;
+ gSaveContext.save.weekEventReg[76] &= (u8)~2;
+ gSaveContext.save.weekEventReg[76] &= (u8)~4;
+ gSaveContext.save.weekEventReg[76] &= (u8)~8;
+ gSaveContext.save.weekEventReg[76] &= (u8)~0x10;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE32C.s")
+ gSaveContext.save.bombersCaughtNum = 0;
+ gSaveContext.save.bombersCaughtOrder[0] = 0;
+ gSaveContext.save.bombersCaughtOrder[1] = 0;
+ gSaveContext.save.bombersCaughtOrder[2] = 0;
+ gSaveContext.save.bombersCaughtOrder[3] = 0;
+ gSaveContext.save.bombersCaughtOrder[4] = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE494.s")
+ func_80BFE494(this, 3, 1.0f);
+ this->unk_2C8 = 9;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE524.s")
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ this->actor.textId = D_80C00A54[this->unk_2C8];
+ } else {
+ this->actor.textId = D_80C00A70[this->unk_2C8];
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ this->actionFunc = func_80BFFB40;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE65C.s")
+void func_80BFFB40(EnBomjima* this, GlobalContext* globalCtx) {
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ func_80BFE494(this, 15, 1.0f);
+ D_80C009F0 = 100;
+ this->unk_2DC = 0;
+ this->actionFunc = func_80BFFBC4;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE67C.s")
+void func_80BFFBC4(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 curFrame = this->skelAnime.curFrame;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEA94.s")
+ if ((this->unk_2EC != 1) && (this->unk_2CC <= curFrame)) {
+ func_80BFE494(this, 1, 1.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB1C.s")
+ if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) {
+ this->unk_2C2 = Rand_S16Offset(5, 5);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB64.s")
+ if (this->unk_2C2 == 1) {
+ this->unk_2DC = -10000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEFF0.s")
+ Math_SmoothStepToS(&this->unk_290, this->unk_2DC, 1, 5000, 0);
+ if (D_80C009F0 >= 104) {
+ D_80C009F0 = 0;
+ func_801477B4(globalCtx);
+ globalCtx->nextEntranceIndex = Entrance_CreateIndexFromSpawn(6);
+ gSaveContext.nextCutsceneIndex = 0;
+ globalCtx->sceneLoadFlag = 20;
+ globalCtx->unk_1887F = 0x56;
+ gSaveContext.nextTransition = 3;
+ ActorCutscene_Stop(this->unk_2D4[1]);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF03C.s")
+void func_80BFFCFC(EnBomjima* this) {
+ func_80BFE65C(this);
+ func_80BFE494(this, 18, 1.0f);
+ this->unk_2A0 = 6;
+ this->actionFunc = func_80BFFD48;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF120.s")
+void func_80BFFD48(EnBomjima* this, GlobalContext* globalCtx) {
+ s32 pad[2];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF174.s")
+ this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4);
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+ Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 4.0f);
+ Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 4.0f);
+ if (sqrtf(SQ(this->actor.world.pos.x - this->unk_2A4.x) + SQ(this->actor.world.pos.z - this->unk_2A4.z)) < 4.0f) {
+ D_80C009F0++;
+ this->unk_2DC = this->actor.parent->world.rot.y;
+ func_80BFE494(this, 0, 1.0f);
+ this->actionFunc = func_80BFFE48;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF3F0.s")
+void func_80BFFE48(EnBomjima* this, GlobalContext* globalCtx) {
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+ Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 4.0f);
+ Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 4.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF430.s")
+ if (D_80C009F0 >= 100) {
+ if (this->unk_2E4 != 4) {
+ func_80BFE494(this, 15, 1.0f);
+ this->unk_2DC = 0;
+ func_80BFE65C(this);
+ this->actionFunc = func_80BFFF54;
+ } else {
+ Math_SmoothStepToS(&this->unk_290, 10000, 1, 5000, 0);
+ if (D_80C009F0 >= 103) {
+ this->unk_2DC = 0;
+ func_80BFE494(this, 15, 1.0f);
+ func_80BFE65C(this);
+ this->actionFunc = func_80BFFF54;
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF4F4.s")
+void func_80BFFF54(EnBomjima* this, GlobalContext* globalCtx) {
+ f32 curFrame = this->skelAnime.curFrame;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF52C.s")
+ Math_SmoothStepToS(&this->unk_290, this->unk_2DC, 1, 5000, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF6CC.s")
+ if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) {
+ this->unk_2C2 = Rand_S16Offset(5, 5);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF754.s")
+ if (this->unk_2C2 == 1) {
+ this->unk_2DC = -10000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF9B0.s")
+ if (this->unk_2E4 != 4) {
+ if ((this->unk_2EC != 0) && (this->unk_2CC <= curFrame)) {
+ D_80C009F0++;
+ func_80BFE494(this, 0, 1.0f);
+ }
+ } else if ((this->unk_2EC != 8) && (this->unk_2CC <= curFrame)) {
+ func_80BFE494(this, 8, 1.0f);
+ D_80C009F4 = 1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFB40.s")
+ if (this->unk_2EC == 8) {
+ if ((D_80C009F4 == 1) && Animation_OnFrame(&this->skelAnime, 7.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_HUMAN_BOUND);
+ D_80C009F4 = 2;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFBC4.s")
+ if ((this->unk_2CC <= curFrame) && (this->unk_2C0 == 0)) {
+ this->unk_2C0 = 10;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFCFC.s")
+ if (this->unk_2C0 == 1) {
+ D_80C009F0++;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFD48.s")
+void func_80C0011C(EnBomjima* this) {
+ func_80BFE65C(this);
+ func_80BFE494(this, 0, 1.0f);
+ this->unk_2A0 = 7;
+ this->actionFunc = func_80C00168;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFE48.s")
+void func_80C00168(EnBomjima* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFF54.s")
+ if (player->transformation == PLAYER_FORM_HUMAN) {
+ this->unk_2C8 = 4;
+ } else if (player->transformation == PLAYER_FORM_DEKU) {
+ this->unk_2C8 = 7;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C0011C.s")
+ func_80BFE32C(this, globalCtx, 0);
+ func_80BFE67C(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00168.s")
+ if (Text_GetFaceReaction(globalCtx, 0x11) != 0) {
+ this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00234.s")
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ this->unk_2DC = this->actor.yawTowardsPlayer;
+ func_80C00234(this);
+ } else {
+ func_800B8614(&this->actor, globalCtx, 70.0f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00284.s")
+void func_80C00234(EnBomjima* this) {
+ func_80BFE494(this, 3, 1.0f);
+ this->collider.dim.radius = 15;
+ this->collider.dim.height = 40;
+ func_80BFE65C(this);
+ this->actionFunc = func_80C00284;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Update.s")
+void func_80C00284(EnBomjima* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ f32 sp28 = this->skelAnime.curFrame;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C007F4.s")
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0);
+ if (((this->unk_2A0 == 0) || (this->unk_2C8 == 10) || (this->unk_2C8 == 11) || (this->unk_2CA == 1)) &&
+ (this->unk_2CC <= sp28)) {
+ if (!(this->unk_2BC & 1)) {
+ func_80BFE494(this, 3, 1.0f);
+ } else {
+ func_80BFE494(this, 16, 1.0f);
+ }
+ this->unk_2BC++;
+ this->unk_2BC &= 1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Draw.s")
+ if ((player->transformation != PLAYER_FORM_GORON) && (player->transformation != PLAYER_FORM_ZORA)) {
+ if (player->transformation == PLAYER_FORM_HUMAN) {
+ this->unk_28E = -4000;
+ }
+ } else {
+ this->unk_28E = -6000;
+ }
+
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ this->collider.dim.radius = 10;
+ this->collider.dim.height = 30;
+ if ((this->unk_2A0 == 4) || (this->unk_2CA == 1) || ((this->unk_2CA == 3) && (this->unk_2C8 >= 2))) {
+ this->unk_28E = 0;
+ if (player->stateFlags1 & 0x20) {
+ player->stateFlags1 &= ~0x20;
+ }
+
+ if ((this->unk_2F0 == 0) || (this->unk_2F0->actor.update == NULL) ||
+ (this->unk_2F0->actor.colChkInfo.health <= 0)) {
+ func_80BFF3F0(this);
+ } else {
+ func_80BFE65C(this);
+ func_801477B4(globalCtx);
+ this->actionFunc = func_80BFEA94;
+ }
+ return;
+ }
+
+ func_801477B4(globalCtx);
+
+ switch (this->unk_2CA) {
+ case 0:
+ this->unk_28E = 0;
+ if (this->unk_2A0 == 7) {
+ func_80C0011C(this);
+ } else {
+ func_80BFEB1C(this);
+ }
+ break;
+
+ case 2:
+ if (this->unk_2C8 == 10) {
+ func_80BFE65C(this);
+ this->unk_28E = 0;
+ func_80BFE494(this, 1, 1.0f);
+ this->unk_2A0 = 2;
+ this->actionFunc = func_80BFF174;
+ return;
+ }
+
+ this->unk_2C8++;
+ if (player->transformation == PLAYER_FORM_DEKU) {
+ if ((this->unk_2E8 != 0) && (this->unk_2C8 == 4)) {
+ this->unk_2C8 = 6;
+ }
+ this->actor.textId = D_80C00A54[this->unk_2C8];
+ } else {
+ if ((this->unk_2EA != 0) && (this->unk_2C8 == 4)) {
+ this->unk_2C8 = 6;
+ }
+ this->actor.textId = D_80C00A70[this->unk_2C8];
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ if ((this->unk_2C8 == 7) || (this->unk_2C8 == 12)) {
+ func_80BFF4F4(this);
+ }
+ break;
+
+ case 3:
+ this->unk_2C8++;
+ this->actor.textId = D_80C00A8C[this->unk_2C8];
+ func_80151938(globalCtx, this->actor.textId);
+ if (this->unk_2C8 >= 2) {
+ func_80BFE494(this, 17, 1.0f);
+ }
+ break;
+ }
+ }
+}
+
+void EnBomjima_Update(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnBomjima* this = THIS;
+
+ if (this->unk_2BE != 0) {
+ this->unk_2BE--;
+ }
+
+ if (this->unk_2C2 != 0) {
+ this->unk_2C2--;
+ }
+
+ if (this->unk_2C0 != 0) {
+ this->unk_2C0--;
+ }
+
+ if (this->unk_2C6 != 0) {
+ this->unk_2C6--;
+ }
+
+ if (this->unk_2C4 != 0) {
+ this->unk_2C4--;
+ }
+
+ SkelAnime_Update(&this->skelAnime);
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ func_80BFE524(this);
+ Actor_SetHeight(&this->actor, 20.0f);
+ this->actionFunc(this, globalCtx);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 5000, 0);
+ Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 1000, 0);
+ Math_SmoothStepToS(&this->unk_294, this->unk_29A, 1, 1000, 0);
+
+ if (this->unk_2E2 == 0) {
+ this->unk_2E0++;
+ if (this->unk_2E0 >= 3) {
+ this->unk_2E0 = 0;
+ this->unk_2E2 = (s16)Rand_ZeroFloat(60.0f) + 20;
+ }
+ }
+
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D);
+ this->actor.uncullZoneForward = 500.0f;
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+s32 EnBomjima_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnBomjima* this = THIS;
+
+ if (limbIndex == 8) {
+ rot->z += this->unk_294;
+ }
+
+ if ((limbIndex == 15) && (this->unk_2E6 == 2)) {
+ *dList = NULL;
+ }
+
+ if (limbIndex == 17) {
+ rot->x += this->unk_28A;
+ rot->z += this->unk_288;
+ }
+
+ if ((limbIndex == 19) && (this->unk_2E6 == 2)) {
+ *dList = NULL;
+ }
+
+ if ((limbIndex == 20) && (this->unk_2E6 == 0)) {
+ *dList = NULL;
+ }
+
+ return false;
+}
+
+#include "overlays/ovl_En_Bomjima/ovl_En_Bomjima.c"
+
+void EnBomjima_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ static Gfx* D_80C00B28[] = {
+ gEnBomjima_D_80C00B08, gEnBomjima_D_80C00B18, gEnBomjima_D_80C00B18,
+ gEnBomjima_D_80C00B18, gEnBomjima_D_80C00B18,
+ };
+ static TexturePtr D_80C00B3C[] = {
+ &object_cs_Tex_00C520,
+ &object_cs_Tex_00CD20,
+ &object_cs_Tex_00D520,
+ };
+ static TexturePtr D_80C00B48[] = {
+ &object_cs_Tex_00E620, &object_cs_Tex_00EA20, &object_cs_Tex_00EE20,
+ &object_cs_Tex_00DD20, &object_cs_Tex_00F220,
+ };
+ EnBomjima* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C00B3C[this->unk_2E0]));
+ gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C00B48[this->unk_2E4]));
+ gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_80C00B28[this->unk_2E4]));
+
+ Scene_SetRenderModeXlu(globalCtx, 0, 1);
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ EnBomjima_OverrideLimbDraw, NULL, &this->actor);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h
index b24725d21..c01e70bd5 100644
--- a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h
+++ b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h
@@ -7,11 +7,53 @@ struct EnBomjima;
typedef void (*EnBomjimaActionFunc)(struct EnBomjima*, GlobalContext*);
+#define ENBOMJIMA_GET_F0(thisx) (((thisx)->params >> 4) & 0xF)
+#define ENBOMJIMA_GET_F(thisx) ((thisx)->params & 0xF)
+
typedef struct EnBomjima {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x140];
- /* 0x0284 */ EnBomjimaActionFunc actionFunc;
- /* 0x0288 */ char unk_288[0xBC];
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ Vec3s jointTable[21];
+ /* 0x206 */ Vec3s morphTable[21];
+ /* 0x284 */ EnBomjimaActionFunc actionFunc;
+ /* 0x288 */ s16 unk_288;
+ /* 0x28A */ s16 unk_28A;
+ /* 0x28C */ UNK_TYPE1 unk28C[2];
+ /* 0x28E */ s16 unk_28E;
+ /* 0x290 */ s16 unk_290;
+ /* 0x292 */ UNK_TYPE1 unk292[2];
+ /* 0x294 */ s16 unk_294;
+ /* 0x296 */ UNK_TYPE1 unk296[4];
+ /* 0x29A */ s16 unk_29A;
+ /* 0x29C */ UNK_TYPE1 unk29C[4];
+ /* 0x2A0 */ s16 unk_2A0;
+ /* 0x2A2 */ s16 unk_2A2;
+ /* 0x2A4 */ Vec3f unk_2A4;
+ /* 0x2B0 */ Vec3f unk_2B0;
+ /* 0x2BC */ s16 unk_2BC;
+ /* 0x2BE */ s16 unk_2BE;
+ /* 0x2C0 */ s16 unk_2C0;
+ /* 0x2C2 */ s16 unk_2C2;
+ /* 0x2C4 */ s16 unk_2C4;
+ /* 0x2C6 */ s16 unk_2C6;
+ /* 0x2C8 */ s16 unk_2C8;
+ /* 0x2CA */ s16 unk_2CA;
+ /* 0x2CC */ f32 unk_2CC;
+ /* 0x2D0 */ f32 unk_2D0;
+ /* 0x2D4 */ s16 unk_2D4[2];
+ /* 0x2D8 */ UNK_TYPE1 unk2D8[4]; // maybe a part of the above?
+ /* 0x2DC */ s16 unk_2DC;
+ /* 0x2DE */ s16 unk_2DE;
+ /* 0x2E0 */ s16 unk_2E0;
+ /* 0x2E2 */ s16 unk_2E2;
+ /* 0x2E4 */ s16 unk_2E4;
+ /* 0x2E6 */ s16 unk_2E6;
+ /* 0x2E8 */ s16 unk_2E8;
+ /* 0x2EA */ s16 unk_2EA;
+ /* 0x2EC */ s32 unk_2EC;
+ /* 0x2F0 */ EnBombal* unk_2F0;
+ /* 0x2F4 */ s16 unk_2F4;
+ /* 0x2F8 */ ColliderCylinder collider;
} EnBomjima; // size = 0x344
extern const ActorInit En_Bomjima_InitVars;
diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
index f76b22296..04180ab47 100644
--- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
+++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
@@ -538,7 +538,7 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) {
func_80169590(globalCtx, 0, 1);
func_80169590(globalCtx, this->camId, 7);
func_800B7298(globalCtx, &this->actor, 4);
- camera = Play_GetCamera(globalCtx, 0);
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
this->eye.x = camera->eye.x;
this->eye.y = camera->eye.y;
this->eye.z = camera->eye.z;
@@ -557,7 +557,7 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) {
player->actor.speedXZ = 0.0f;
if (func_80152498(&globalCtx->msgCtx) == 0) {
- camera = Play_GetCamera(globalCtx, 0);
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
camera->eye = this->eye;
camera->eyeNext = this->eye;
camera->at = this->at;
diff --git a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c
index d65232214..c3c404750 100644
--- a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c
+++ b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c
@@ -1,10 +1,12 @@
/*
* File: z_en_col_man.c
* Overlay: ovl_En_Col_Man
- * Description: Piece of Heart spawned by Fish2
+ * Description: Lab HP, Garo Master falling rocks, Garo Master bomb
*/
#include "z_en_col_man.h"
+#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00100000
@@ -13,17 +15,35 @@
void EnColMan_Init(Actor* thisx, GlobalContext* globalCtx);
void EnColMan_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnColMan_Update(Actor* thisx, GlobalContext* globalCtx);
-
+void func_80AFDD60(EnColMan* this);
void func_80AFDE00(EnColMan* this, GlobalContext* globalCtx);
-void func_80AFDF00(EnColMan* this, GlobalContext* globalCtx);
+void EnColMan_SetHeartPieceCollectedAndKill(EnColMan* this, GlobalContext* globalCtx);
+void func_80AFDF60(EnColMan* this);
void func_80AFDFB4(EnColMan* this, GlobalContext* globalCtx);
+void func_80AFE234(EnColMan* this);
void func_80AFE25C(EnColMan* this, GlobalContext* globalCtx);
+void func_80AFE414(Actor* thisx, GlobalContext* globalCtx);
+void func_80AFE4AC(Actor* thisx, GlobalContext* globalCtx);
+void func_80AFE584(Actor* thisx, GlobalContext* globalCtx);
+void func_80AFE650(Actor* thisx, GlobalContext* globalCtx);
-#if 0
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80AFE730 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 10, 11, 1, { 0, 0, 0 } },
};
@@ -39,34 +59,217 @@ const ActorInit En_Col_Man_InitVars = {
(ActorFunc)NULL,
};
-#endif
+static Color_RGBA8 primColor = { 60, 50, 20, 255 };
+static Color_RGBA8 envColor = { 40, 30, 30, 255 };
-extern ColliderCylinderInit D_80AFE730;
+void EnColMan_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnColMan* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Init.s")
+ Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ this->actor.targetMode = 1;
+ this->scale = (BREG(55) / 1000.0f) + 0.01f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Destroy.s")
+ switch (this->actor.params) {
+ case EN_COL_MAN_HEART_PIECE:
+ case EN_COL_MAN_RECOVERY_HEART:
+ default:
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f);
+ func_80AFDD60(this);
+ break;
+ case EN_COL_MAN_FALLING_ROCK:
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f);
+ func_80AFDF60(this);
+ break;
+ case EN_COL_MAN_CUTSCENE_BOMB:
+ case EN_COL_MAN_GAMEPLAY_BOMB:
+ func_80AFE234(this);
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDD60.s")
+void EnColMan_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnColMan* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDE00.s")
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDF00.s")
+void func_80AFDD60(EnColMan* this) {
+ if (!(gSaveContext.save.weekEventReg[56] & 2)) {
+ this->actor.draw = func_80AFE414;
+ this->actor.shape.yOffset = 700.0f;
+ if (this->actor.params == EN_COL_MAN_HEART_PIECE) {
+ this->actor.gravity = -2.0f;
+ }
+ this->type = EN_COL_MAN_HEART_PIECE;
+ } else {
+ this->actor.draw = func_80AFE4AC;
+ this->actor.shape.yOffset = 300.0f;
+ this->actor.shape.shadowScale = 5.0f;
+ if (this->actor.params == EN_COL_MAN_HEART_PIECE) {
+ this->actor.gravity = -2.0f;
+ }
+ this->type = EN_COL_MAN_RECOVERY_HEART;
+ }
+ this->actionFunc = func_80AFDE00;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDF60.s")
+void func_80AFDE00(EnColMan* this, GlobalContext* globalCtx) {
+ if (this->actor.bgCheckFlags & 1) {
+ if (this->actor.params == EN_COL_MAN_HEART_PIECE) {
+ this->actor.params = EN_COL_MAN_RECOVERY_HEART;
+ this->actor.speedXZ = 2.0f;
+ this->actor.velocity.y = 8.0f;
+ } else {
+ this->actor.speedXZ = 0.0f;
+ }
+ }
+ if (!(gSaveContext.save.weekEventReg[56] & 2)) {
+ this->actor.shape.rot.y += 0x3E8;
+ }
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ this->actor.parent = NULL;
+ this->actor.draw = NULL;
+ this->actionFunc = EnColMan_SetHeartPieceCollectedAndKill;
+ } else if (!(gSaveContext.save.weekEventReg[56] & 2)) {
+ func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 40.0f, 40.0f);
+ } else {
+ func_800B8A1C(&this->actor, globalCtx, GI_RECOVERY_HEART, 40.0f, 40.0f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDFB4.s")
+void EnColMan_SetHeartPieceCollectedAndKill(EnColMan* this, GlobalContext* globalCtx) {
+ if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) {
+ gSaveContext.save.weekEventReg[56] |= 2;
+ Actor_MarkForDeath(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE234.s")
+void func_80AFDF60(EnColMan* this) {
+ this->actor.draw = func_80AFE584;
+ this->actor.flags |= 0x10;
+ this->actor.flags |= 0x20;
+ this->type = EN_COL_MAN_FALLING_ROCK;
+ this->actionFunc = func_80AFDFB4;
+ this->actor.shape.shadowScale = 5.0f;
+ this->actor.gravity = -3.0f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE25C.s")
+void func_80AFDFB4(EnColMan* this, GlobalContext* globalCtx) {
+ s32 i;
+ Vec3f velocity;
+ Vec3f accel;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Update.s")
+ this->scale = (BREG(55) / 10000.0f) + 0.0015f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE414.s")
+ if ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f)) {
+ if (!this->hasSetRandomValues) {
+ this->actor.world.rot.y = randPlusMinusPoint5Scaled(30000.0f);
+ this->actor.speedXZ = 2.0f + BREG(56) + Rand_ZeroFloat(2.0f);
+ this->actor.velocity.y = 12.0f + BREG(57) + Rand_ZeroFloat(5.0f);
+ this->hasSetRandomValues = true;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_ANSATSUSYA_ROCK);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE4AC.s")
+ for (i = 0; i < 2; i++) {
+ velocity.x = randPlusMinusPoint5Scaled(2.0f);
+ velocity.y = Rand_ZeroFloat(2.0f) + 1.0f;
+ velocity.z = randPlusMinusPoint5Scaled(2.0f);
+ accel.y = -0.1f;
+ accel.z = 0.0f;
+ accel.x = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE584.s")
+ func_800B0EB0(globalCtx, &this->actor.world.pos, &velocity, &accel, &primColor, &envColor,
+ Rand_ZeroFloat(50.0f) + 60.0f, 30, Rand_ZeroFloat(5.0f) + 20.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE650.s")
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_80AFE234(EnColMan* this) {
+ this->actor.draw = func_80AFE650;
+ this->type = EN_COL_MAN_CUTSCENE_BOMB;
+ this->actionFunc = func_80AFE25C;
+}
+
+void func_80AFE25C(EnColMan* this, GlobalContext* globalCtx) {
+ this->scale = BREG(55) * 0.01f + 0.05f;
+
+ if (BREG(60) || (this->actor.world.rot.z != 0)) {
+ if (this->actor.params == EN_COL_MAN_CUTSCENE_BOMB) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.parent->world.pos.x,
+ this->actor.parent->world.pos.y, this->actor.parent->world.pos.z, 0, 0, 0,
+ CLEAR_TAG_SMALL_EXPLOSION);
+ } else {
+ EnBom* bomb = (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0);
+
+ if (bomb != NULL) {
+ bomb->timer = 0;
+ }
+ }
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION);
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnColMan_Update(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnColMan* this = THIS;
+
+ Actor_SetScale(&this->actor, this->scale);
+ this->actionFunc(this, globalCtx);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 30.0f, 30.0f, 0x1F);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+void func_80AFE414(Actor* thisx, GlobalContext* globalCtx) {
+ EnColMan* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ func_800B8118(&this->actor, globalCtx, 0);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_05AAB0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80AFE4AC(Actor* thisx, GlobalContext* globalCtx) {
+ EnColMan* this = THIS;
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ func_8012C28C(globalCtx->state.gfxCtx);
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP);
+ POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP);
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&gameplay_keep_Tex_05E6F0));
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80AFE584(Actor* thisx, GlobalContext* globalCtx) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ func_8012C28C(globalCtx->state.gfxCtx);
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
+ gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30);
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80AFE650(Actor* thisx, GlobalContext* globalCtx) {
+ func_8012C28C(globalCtx->state.gfxCtx);
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP);
+ POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP);
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&gameplay_keep_Tex_05CEF0));
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0);
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h
index 6bab3c11a..ab1ac285d 100644
--- a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h
+++ b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h
@@ -8,10 +8,21 @@ struct EnColMan;
typedef void (*EnColManActionFunc)(struct EnColMan*, GlobalContext*);
typedef struct EnColMan {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ EnColManActionFunc actionFunc;
- /* 0x0148 */ char unk_148[0x58];
-} EnColMan; // size = 0x1A0
+ /* 0x000 */ Actor actor;
+ /* 0x144 */ EnColManActionFunc actionFunc;
+ /* 0x148 */ s16 type; // never used, only set
+ /* 0x14C */ s32 hasSetRandomValues;
+ /* 0x150 */ f32 scale;
+ /* 0x154 */ ColliderCylinder collider;
+} EnColMan; /* size = 0x1A0 */
+
+typedef enum {
+ /* 0 */ EN_COL_MAN_HEART_PIECE,
+ /* 1 */ EN_COL_MAN_RECOVERY_HEART,
+ /* 2 */ EN_COL_MAN_FALLING_ROCK,
+ /* 3 */ EN_COL_MAN_CUTSCENE_BOMB,
+ /* 4 */ EN_COL_MAN_GAMEPLAY_BOMB,
+} EnColManType;
extern const ActorInit En_Col_Man_InitVars;
diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.c b/src/overlays/actors/ovl_En_Dno/z_en_dno.c
index bd102567b..78adfa208 100644
--- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c
+++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c
@@ -135,7 +135,7 @@ void func_80A714B4(EnDno* this, GlobalContext* globalCtx) {
Actor* actor = NULL;
do {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (actor != NULL) {
if ((s32)ENDNO_GET_F(actor) == ENDNO_GET_F_1) {
Actor_SetSwitchFlag(globalCtx, ENDNO_GET_7F0(actor));
@@ -165,8 +165,7 @@ void func_80A715DC(EnDno* this, GlobalContext* globalCtx) {
Vec3f sp70;
do {
- crace =
- (BgCraceMovebg*)func_ActorCategoryIterateById(globalCtx, &crace->actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
+ crace = (BgCraceMovebg*)SubS_FindActor(globalCtx, &crace->actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (crace != NULL) {
if (ENDNO_GET_F(&crace->actor) == ENDNO_GET_F_0 && !(crace->unk_170 & 1)) {
if (func_8013E5CC(&crace->actor.home.pos, &crace->actor.home.rot, &D_80A73B2C, &this->actor.prevPos,
@@ -188,7 +187,7 @@ void func_80A71788(EnDno* this, GlobalContext* globalCtx) {
Actor* actor = NULL;
do {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (actor != NULL) {
Actor_UnsetSwitchFlag(globalCtx, ENDNO_GET_7F0(actor));
actor = actor->next;
@@ -202,7 +201,7 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor* actor = NULL;
while (true) {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_DNO);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_DNO);
if (actor != NULL) {
if (actor != thisx) {
Actor_MarkForDeath(thisx);
@@ -249,7 +248,7 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_MarkForDeath(thisx);
} else {
func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C);
- this->unk_460 = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_DNQ);
+ this->unk_460 = SubS_FindActor(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_DNQ);
if (this->unk_460 == NULL) {
Actor_MarkForDeath(thisx);
} else {
diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.h b/src/overlays/actors/ovl_En_Door/z_en_door.h
index 7331339fc..6ed5aac15 100644
--- a/src/overlays/actors/ovl_En_Door/z_en_door.h
+++ b/src/overlays/actors/ovl_En_Door/z_en_door.h
@@ -12,7 +12,10 @@ typedef struct EnDoor {
/* 0x144 */ char unk_144[0x5C];
/* 0x1A0 */ s8 unk_1A0;
/* 0x1A1 */ s8 unk_1A1;
- /* 0x1A2 */ char unk_1A2[0x5];
+ /* 0x1A2 */ char unk_1A2[0x2];
+ /* 0x1A4 */ u8 unk_1A4;
+ /* 0x1A5 */ u8 unk_1A5;
+ /* 0x1A6 */ s8 unk_1A6;
/* 0x1A7 */ s8 unk_1A7;
/* 0x1A8 */ char unk_1A8[0x20];
/* 0x1C8 */ EnDoorActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c
index 4e7a97a8f..7628bb81a 100644
--- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c
+++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c
@@ -5,6 +5,7 @@
*/
#include "z_en_elforg.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00000010
@@ -72,7 +73,8 @@ void EnElforg_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_SetScale(&this->actor, 0.01f);
this->flags = 0;
this->direction = 0;
- SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0402CA98, &D_0402B494, this->jointTable, this->jointTable, 10);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gStrayFairySkel, &gStrayFairyFlyingAnim, this->jointTable,
+ this->jointTable, STRAY_FAIRY_LIMB_MAX);
this->skelAnime.playSpeed = 1.0f;
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
this->actor.shape.shadowAlpha = 255;
@@ -575,13 +577,14 @@ s32 EnElforg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi
EnElforg* this = THIS;
if (this->direction < 0) {
- if (limbIndex == 9) {
+ if (limbIndex == STRAY_FAIRY_LIMB_LEFT_FACING_HEAD) {
*dList = NULL;
}
- } else if (limbIndex == 1) {
+ } else if (limbIndex == STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD) {
*dList = NULL;
}
- return 0;
+
+ return false;
}
void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) {
@@ -589,22 +592,23 @@ void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnElforg* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx);
+
func_8012C2DC(globalCtx->state.gfxCtx);
switch (this->area) {
case STRAY_FAIRY_AREA_WOODFALL:
- AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C908));
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyWoodfallTexAnim));
break;
case STRAY_FAIRY_AREA_SNOWHEAD:
- AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C890));
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairySnowheadTexAnim));
break;
case STRAY_FAIRY_AREA_GREAT_BAY:
- AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C980));
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyGreatBayTexAnim));
break;
case STRAY_FAIRY_AREA_STONE_TOWER:
- AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C9F8));
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyStoneTowerTexAnim));
break;
default:
- AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C818));
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyClockTownTexAnim));
break;
}
Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY);
diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h
index 5195235a3..fbf982beb 100644
--- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h
+++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h
@@ -33,6 +33,20 @@ typedef enum {
STRAY_FAIRY_AREA_MAX
} StrayFairyArea;
+typedef enum {
+ /* 0 */ STRAY_FAIRY_LIMB_NONE,
+ /* 1 */ STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD,
+ /* 2 */ STRAY_FAIRY_LIMB_LEFT_WING,
+ /* 3 */ STRAY_FAIRY_LIMB_RIGHT_WING,
+ /* 4 */ STRAY_FAIRY_LIMB_GLOW,
+ /* 5 */ STRAY_FAIRY_LIMB_TORSO,
+ /* 6 */ STRAY_FAIRY_LIMB_RIGHT_ARM,
+ /* 7 */ STRAY_FAIRY_LIMB_PELVIS_AND_LEGS,
+ /* 8 */ STRAY_FAIRY_LIMB_LEFT_ARM,
+ /* 9 */ STRAY_FAIRY_LIMB_LEFT_FACING_HEAD,
+ /* 10 */ STRAY_FAIRY_LIMB_MAX,
+} StrayFairyLimbs;
+
struct EnElforg;
typedef void (*EnElforgActionFunc)(struct EnElforg*, GlobalContext*);
@@ -40,11 +54,11 @@ typedef void (*EnElforgActionFunc)(struct EnElforg*, GlobalContext*);
typedef struct EnElforg {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
- /* 0x188 */ Vec3s jointTable[10];
+ /* 0x188 */ Vec3s jointTable[STRAY_FAIRY_LIMB_MAX];
/* 0x1C4 */ ColliderCylinder collider;
/* 0x210 */ Actor* enemy;
/* 0x214 */ u16 flags;
- /* 0x216 */ s16 direction; // negative when facing left, positive when facing right
+ /* 0x216 */ s16 direction; // negative when facing right, positive when facing left
/* 0x218 */ s16 area;
/* 0x21C */ s32 timer;
/* 0x220 */ s32 secondaryTimer;
diff --git a/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/src/overlays/actors/ovl_En_Fish/z_en_fish.c
index 61f08534b..8368dbc7d 100644
--- a/src/overlays/actors/ovl_En_Fish/z_en_fish.c
+++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.c
@@ -5,6 +5,7 @@
*/
#include "z_en_fish.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00000000
@@ -15,19 +16,56 @@ void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnFish_Update(Actor* thisx, GlobalContext* globalCtx);
void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_8091FA60[1] = {
+void func_8091DF68(Actor* thisx, GlobalContext* globalCtx);
+void func_8091E070(EnFish* this);
+void func_8091E128(Actor* thisx, GlobalContext* globalCtx);
+void func_8091E2E0(EnFish* this);
+void func_8091E34C(Actor* thisx, GlobalContext* globalCtx2);
+void func_8091E5EC(EnFish* this);
+void func_8091E658(Actor* thisx, GlobalContext* globalCtx);
+void func_8091E810(EnFish* this);
+void func_8091E880(Actor* thisx, GlobalContext* globalCtx);
+void func_8091E9A4(EnFish* this);
+void func_8091EAF0(Actor* thisx, GlobalContext* globalCtx);
+void func_8091ECF4(EnFish* this);
+void func_8091ED70(Actor* thisx, GlobalContext* globalCtx);
+void func_8091EF30(EnFish* this);
+void func_8091EFE8(Actor* thisx, GlobalContext* globalCtx);
+void func_8091F344(EnFish* this);
+void func_8091F3BC(Actor* thisx, GlobalContext* globalCtx);
+void func_8091F994(Actor* thisx, GlobalContext* globalCtx);
+
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 5 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_8091FA84 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 1, D_8091FA60, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit,
+};
+
+static Color_RGB8 D_8091FA94[] = {
+ { 255, 155, 55 },
+ { 255, 47, 157 },
+ { 215, 97, 7 },
};
const ActorInit En_Fish_InitVars = {
@@ -42,87 +80,874 @@ const ActorInit En_Fish_InitVars = {
(ActorFunc)EnFish_Draw,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8091FAC0[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 720, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 40, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 40, ICHAIN_STOP),
};
-#endif
+f32 func_8091D630(Vec3f* arg0, Vec3f* arg1) {
+ return SQ(arg0->x - arg1->x) + SQ(arg0->z - arg1->z);
+}
-extern ColliderJntSphElementInit D_8091FA60[1];
-extern ColliderJntSphInit D_8091FA84;
-extern InitChainEntry D_8091FAC0[];
+void func_8091D660(EnFish* this) {
+ Animation_Change(&this->skelAnime, &gameplay_keep_Anim_02F0EC, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gameplay_keep_Anim_02F0EC), 1, 2.0f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D630.s")
+void func_8091D6C4(EnFish* this) {
+ Animation_Change(&this->skelAnime, &gameplay_keep_Anim_02E65C, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gameplay_keep_Anim_02E65C), 1, 2.0f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D660.s")
+void func_8091D728(EnFish* this) {
+ f32 phi_f0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D6C4.s")
+ this->actor.scale.x = this->unk_250 * this->unk_25C;
+ this->actor.scale.y = this->unk_254 * this->unk_25C;
+ this->actor.scale.z = this->unk_258 * this->unk_25C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D728.s")
+ if (this->actor.scale.z > 0.00001f) {
+ phi_f0 = 1.0f / this->actor.scale.z;
+ } else {
+ phi_f0 = 0.0f;
+ }
+ this->unk_264 = 16.0f * phi_f0;
+ this->unk_266 = 12.0f * phi_f0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D7C4.s")
+void func_8091D7C4(EnFish* this) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D840.s")
+ Math_ScaledStepToS(&this->actor.world.rot.x, this->unk_268, this->unk_26E);
+ Math_ScaledStepToS(&this->actor.world.rot.y, this->unk_26A, this->unk_270);
+ if (this->actor.world.rot.z != this->unk_26C) {
+ Math_ScaledStepToS(&this->actor.world.rot.z, this->unk_26C, this->unk_272);
+ }
+ this->actor.shape.rot = this->actor.world.rot;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D904.s")
+void func_8091D840(Actor* thisx, GlobalContext* globalCtx, s32 arg2, f32 arg3) {
+ EnFish* this = THIS;
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D944.s")
+ for (i = 0; i < arg2; i++) {
+ EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, arg3, arg3, (Rand_ZeroOne() * 0.09f) + 0.06f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DA14.s")
+void func_8091D904(EnFish* this) {
+ this->unk_242 = 400;
+ this->unk_25C = this->unk_260 * 0.1f;
+ func_8091D728(this);
+ this->actor.draw = NULL;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Init.s")
+Actor* func_8091D944(EnFish* this, GlobalContext* globalCtx) {
+ f32 distSq;
+ Actor* retActor = NULL;
+ f32 minDistSq = FLT_MAX;
+ Actor* foundActor = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Destroy.s")
+ while (foundActor != NULL) {
+ if ((foundActor->id == ACTOR_EN_FISH) && (foundActor->params == ENFISH_2) &&
+ (foundActor->room == this->actor.room)) {
+ distSq = Math3D_Vec3fDistSq(&foundActor->world.pos, &this->actor.world.pos);
+ if (retActor == NULL) {
+ retActor = foundActor;
+ minDistSq = distSq;
+ } else if (distSq < minDistSq) {
+ minDistSq = distSq;
+ }
+ }
+ foundActor = foundActor->next;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DD48.s")
+ return retActor;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DDF4.s")
+s32 func_8091DA14(EnFish* this, GlobalContext* globalCtx) {
+ return globalCtx->sceneNum == SCENE_LABO && func_8091D944(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DEE4.s")
+void EnFish_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnFish* this = THIS;
+ s16 sp36 = this->actor.params;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DF68.s")
+ Collider_InitJntSph(globalCtx, &this->collider);
+ if (sp36 == ENFISH_2) {
+ this->actor.draw = NULL;
+ this->actor.update = func_8091F994;
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E070.s")
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ this->unk_250 = 1.0f;
+ this->unk_254 = 1.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E128.s")
+ if (sp36 == ENFISH_MINUS1) {
+ this->unk_258 = (Rand_ZeroOne() * 0.9f) + 0.6f;
+ this->unk_25C = ((Rand_ZeroOne() * 1.2f) + 0.6f) * 0.01f;
+ } else {
+ this->unk_258 = 1.0f;
+ this->unk_25C = 0.01f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E2E0.s")
+ this->unk_260 = this->unk_25C;
+ func_8091D728(this);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E34C.s")
+ if ((this->unk_258 * this->unk_25C * 100.0f) < 1.02f) {
+ this->unk_278 = 2;
+ } else if ((this->unk_258 * this->unk_25C * 100.0f) < 2.0f) {
+ this->unk_278 = 1;
+ } else {
+ this->unk_278 = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E5EC.s")
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gameplay_keep_Skel_02F028, &gameplay_keep_Anim_02F0EC,
+ this->jointTable, this->morphTable, 7);
+ Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E658.s")
+ this->actor.colChkInfo.mass = this->unk_25C * 30.0f;
+ this->unk_244 = (u32)Rand_Next() >> 0x10;
+ this->unk_246 = (u32)Rand_Next() >> 0x10;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E810.s")
+ if (sp36 == ENFISH_0) {
+ this->actor.flags |= 0x10;
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 8.0f);
+ func_8091E810(this);
+ } else if (sp36 == ENFISH_1) {
+ func_8091F344(this);
+ } else {
+ func_8091E070(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E880.s")
+void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnFish* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E9A4.s")
+ Collider_DestroyJntSph(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EAF0.s")
+void func_8091DD48(EnFish* this) {
+ this->actor.shape.yOffset += (Math_SinS(this->unk_246) * 5.0f) + (Math_SinS(this->unk_244) * 10.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091ECF4.s")
+ if (this->actor.shape.yOffset < -200.0f) {
+ this->actor.shape.yOffset = -200.0f;
+ } else if (this->actor.shape.yOffset > 200.0f) {
+ this->actor.shape.yOffset = 200.0f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091ED70.s")
+s32 func_8091DDF4(EnFish* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f sp1C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EF30.s")
+ if (this->actor.xzDistToPlayer < 50.0f) {
+ sp1C.x = (Math_SinS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 30.0f) + player->actor.world.pos.x;
+ sp1C.y = player->actor.world.pos.y;
+ sp1C.z = (Math_CosS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 30.0f) + player->actor.world.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EFE8.s")
+ if (func_8091D630(&sp1C, &this->actor.world.pos) <= SQ(30.0f)) {
+ return true;
+ }
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F344.s")
+void func_8091DEE4(EnFish* this) {
+ static s16 D_8091FACC[] = { 85, 60, 45 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F3BC.s")
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+ this->unk_240 = Rand_S16Offset(5, D_8091FACC[this->unk_278]);
+ this->unk_248 = 0;
+ this->unk_26E = 400;
+ this->unk_272 = 400;
+ this->unk_268 = 0;
+ this->unk_26C = 0;
+ func_8091D660(this);
+ this->unk_24C = 0.0f;
+ this->unkFunc = func_8091DF68;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F5A4.s")
+void func_8091DF68(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F830.s")
+ func_8091DD48(this);
+ Math_SmoothStepToF(&thisx->speedXZ, 0.0f, 0.05f, 0.3f, 0.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Update.s")
+ if ((thisx->speedXZ * 1.4f) + 0.8f > 2.0f) {
+ this->skelAnime.playSpeed = 2.0f;
+ } else {
+ this->skelAnime.playSpeed = (thisx->speedXZ * 1.4f) + 0.8f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F994.s")
+ this->unk_270 >>= 1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Draw.s")
+ if (this->unk_240 <= 0) {
+ func_8091E070(this);
+ } else if (thisx == thisx->child) {
+ func_8091E5EC(this);
+ } else if ((thisx->xzDistToPlayer < 60.0f) || (this->unk_276 > 0)) {
+ func_8091E2E0(this);
+ }
+}
+
+void func_8091E070(EnFish* this) {
+ static s16 D_8091FAD4[] = { 20, 30, 40 };
+ s16 phi_a1;
+
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+
+ if ((Rand_Next() & 3) == 0) {
+ if (((Rand_Next() & 7) == 0) && (this->unk_278 != 0)) {
+ phi_a1 = 80;
+ } else {
+ phi_a1 = 45;
+ }
+ } else {
+ phi_a1 = D_8091FAD4[this->unk_278];
+ }
+ this->unk_240 = Rand_S16Offset(15, phi_a1);
+ this->unk_248 = 0;
+ this->unk_26E = 400;
+ this->unk_272 = 400;
+ this->unk_26C = 0;
+ func_8091D660(this);
+ this->unkFunc = func_8091E128;
+}
+
+void func_8091E128(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnFish* this = THIS;
+
+ func_8091DD48(this);
+ Math_SmoothStepToF(&thisx->speedXZ, 1.8f, 0.08f, 0.4f, 0.0f);
+
+ if ((func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(80.0f)) || (this->unk_240 < 4)) {
+ this->unk_270 = this->unk_264;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos);
+ this->unk_24C = 1.0f;
+ } else if ((thisx->child != NULL) && (thisx != thisx->child)) {
+ this->unk_270 = this->unk_264;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->child->world.pos);
+ this->unk_24C = 1.2f;
+ } else {
+ this->unk_270 >>= 2;
+ this->unk_24C = 0.0f;
+ }
+
+ if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) {
+ this->skelAnime.playSpeed = 4.0f;
+ } else {
+ this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f;
+ }
+
+ if (this->unk_240 <= 0) {
+ func_8091DEE4(this);
+ } else if (thisx == thisx->child) {
+ func_8091E5EC(this);
+ } else if ((thisx->xzDistToPlayer < 60.0f) || (this->unk_276 > 0)) {
+ func_8091E2E0(this);
+ }
+}
+
+void func_8091E2E0(EnFish* this) {
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+ this->unk_240 = Rand_S16Offset(10, 40);
+ this->unk_248 = 0;
+ this->unk_26E = 400;
+ this->unk_272 = 400;
+ this->unk_268 = 0;
+ this->unk_26C = 0;
+ func_8091D660(this);
+ this->unkFunc = func_8091E34C;
+}
+
+void func_8091E34C(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnFish* this = THIS;
+ s32 sp3C = thisx->xzDistToPlayer < 60.0f;
+ s32 sp38 = this->unk_276 > 0;
+ s32 pad;
+
+ func_8091DD48(this);
+ Math_SmoothStepToF(&thisx->speedXZ, 4.2f, 0.08f, 1.4f, 0.0f);
+
+ if (func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(160.0f)) {
+ this->unk_270 = this->unk_264;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos);
+ this->unk_24C = 0.8f;
+ } else if ((thisx->child != NULL) && (thisx != thisx->child)) {
+ this->unk_270 = this->unk_266;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->child->world.pos);
+ this->unk_24C = 1.0f;
+ } else if (sp3C) {
+ this->unk_26A = BINANG_ROT180(thisx->yawTowardsPlayer);
+ if ((globalCtx->state.frames & 0x10) == 0) {
+ if ((globalCtx->state.frames & 0x20) == 0) {
+ this->unk_26A += 0x2000;
+ }
+ } else if ((globalCtx->state.frames & 0x20) == 0) {
+ this->unk_26A -= 0x2000;
+ }
+ this->unk_270 = this->unk_266;
+ this->unk_24C = 1.2f;
+ } else if (sp38 != 0) {
+ if ((globalCtx->state.frames & 0x10) == 0) {
+ s16 temp = BINANG_SUB(thisx->shape.rot.y, this->unk_274);
+
+ if (temp < 0) {
+ this->unk_26A = BINANG_SUB(this->unk_274, 0x4000);
+ } else {
+ this->unk_26A = BINANG_ADD(this->unk_274, 0x4000);
+ }
+ } else {
+ this->unk_26A = BINANG_ROT180(this->unk_274);
+ }
+ this->unk_24C = 1.2f;
+ this->unk_270 = this->unk_266;
+ } else {
+ this->unk_270 >>= 2;
+ this->unk_24C = 0.0f;
+ }
+
+ if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) {
+ this->skelAnime.playSpeed = 4.0f;
+ } else {
+ this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f;
+ }
+
+ if ((this->unk_240 <= 0) || (!sp3C && (sp38 == 0))) {
+ func_8091DEE4(this);
+ } else if (thisx == thisx->child) {
+ func_8091E5EC(this);
+ }
+}
+
+void func_8091E5EC(EnFish* this) {
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+ this->unk_26E = 400;
+ this->unk_272 = 400;
+ this->unk_268 = 0;
+ this->unk_26C = 0;
+ func_8091D660(this);
+ this->unk_240 = Rand_S16Offset(10, 30);
+ this->unk_248 = 0;
+ this->unkFunc = func_8091E658;
+}
+
+void func_8091E658(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ Player* player = GET_PLAYER(globalCtx);
+ s32 pad;
+ Vec3f sp38;
+ s32 pad2;
+ s16 sp32;
+
+ func_8091DD48(this);
+ Math_SmoothStepToF(&thisx->speedXZ, 1.8f, 0.1f, 0.5f, 0.0f);
+
+ if (func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(80.0f)) {
+ this->unk_270 = this->unk_264;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos);
+ this->unk_24C = 1.0f;
+ } else {
+ if ((globalCtx->state.frames & 0x40) == 0) {
+ sp32 = BINANG_ADD(thisx->yawTowardsPlayer, 0x9000);
+ } else {
+ sp32 = BINANG_ADD(thisx->yawTowardsPlayer, 0x7000);
+ }
+
+ sp38.x = (Math_SinS(sp32) * 20.0f) + player->actor.world.pos.x;
+ sp38.y = player->actor.world.pos.y;
+ sp38.z = (Math_CosS(sp32) * 20.0f) + player->actor.world.pos.z;
+
+ this->unk_270 = this->unk_264;
+ this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &sp38);
+ this->unk_24C = 1.2f;
+ }
+
+ if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) {
+ this->skelAnime.playSpeed = 4.0f;
+ } else {
+ this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f;
+ }
+
+ if (this->unk_240 <= 0) {
+ func_8091DEE4(this);
+ }
+}
+
+void func_8091E810(EnFish* this) {
+ this->unk_270 = 0;
+ this->unk_26A = 0;
+ this->actor.gravity = -1.0f;
+ this->actor.minVelocityY = -10.0f;
+ this->actor.shape.yOffset = 0.0f;
+ func_8091D6C4(this);
+ this->unk_248 = 5;
+ this->unkFunc = func_8091E880;
+ this->unk_24C = 0.0f;
+ this->unk_240 = 300;
+}
+
+void func_8091E880(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+
+ Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.1f, 0.0f);
+ this->unk_26E = 0x43;
+ this->unk_272 = 0x43;
+ this->unk_268 = 0x4000;
+ this->unk_26C = -0x4000;
+ if (this->actor.bgCheckFlags & 1) {
+ this->unk_240 = 400;
+ func_8091E9A4(this);
+ } else if (this->actor.bgCheckFlags & 0x20) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_DIVE_INTO_WATER_L);
+ func_8091D840(thisx, globalCtx, 10, 15.0f);
+ if (func_8091DA14(this, globalCtx)) {
+ func_8091EF30(this);
+ } else {
+ func_8091ECF4(this);
+ }
+ } else if ((this->unk_240 <= 0) && (this->actor.params == ENFISH_0) &&
+ (this->actor.floorHeight < BGCHECK_Y_MIN + 10)) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_8091E9A4(EnFish* this) {
+ s32 pad[2];
+ s32 sp24;
+ f32 temp_f0;
+
+ this->actor.gravity = -1.0f;
+ this->actor.minVelocityY = -10.0f;
+
+ temp_f0 = Rand_ZeroOne();
+ if (temp_f0 < 0.1f) {
+ this->actor.velocity.y = (Rand_ZeroOne() * 3.0f) + 2.5f;
+ sp24 = true;
+ } else if (temp_f0 < 0.2f) {
+ this->actor.velocity.y = (Rand_ZeroOne() * 1.2f) + 0.2f;
+ sp24 = true;
+ } else {
+ this->actor.velocity.y = 0.0f;
+ if (Rand_ZeroOne() < 0.2f) {
+ sp24 = true;
+ } else {
+ sp24 = false;
+ }
+ }
+
+ this->actor.shape.yOffset = 300.0f;
+ func_8091D6C4(this);
+ this->unkFunc = func_8091EAF0;
+ this->unk_248 = 5;
+ this->unk_24C = 0.0f;
+ if (sp24 && (this->actor.draw != NULL)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP);
+ }
+}
+
+void func_8091EAF0(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ s32 sp40 = globalCtx->state.frames;
+ s16 phi_v1;
+
+ Math_SmoothStepToF(&this->actor.speedXZ, Rand_ZeroOne() * 0.2f, 0.1f, 0.1f, 0.0f);
+ phi_v1 = (s16)((((sp40 >> 5) & 2) | ((sp40 >> 2) & 1)) << 0xB) * 0.3f;
+ if (sp40 & 4) {
+ phi_v1 *= -1;
+ }
+ this->unk_268 = phi_v1;
+ this->unk_26E = 0xA6B;
+ this->unk_26C = 0x4000;
+ this->unk_272 = 0x29B;
+ this->unk_270 = ((Math_SinS(this->unk_244) * 1333.0f) + (Math_SinS(this->unk_246) * 667.0f)) * Rand_ZeroOne();
+
+ if (this->unk_270 >= 0) {
+ this->unk_26A = BINANG_ADD(this->actor.world.rot.y, 0x4000);
+ } else {
+ this->unk_26A = BINANG_SUB(this->actor.world.rot.y, 0x4000);
+ this->unk_270 = -this->unk_270;
+ }
+
+ if (this->unk_240 <= 0) {
+ Actor_MarkForDeath(&this->actor);
+ } else if (this->unk_240 <= 60) {
+ if (sp40 & 4) {
+ this->actor.draw = EnFish_Draw;
+ } else {
+ this->actor.draw = NULL;
+ }
+ } else if (this->actor.bgCheckFlags & 0x20) {
+ if (func_8091DA14(this, globalCtx)) {
+ func_8091EF30(this);
+ } else {
+ func_8091ECF4(this);
+ }
+ } else if (this->actor.bgCheckFlags & 1) {
+ func_8091E9A4(this);
+ }
+}
+
+void func_8091ECF4(EnFish* this) {
+ this->actor.home.pos = this->actor.world.pos;
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+ this->actor.shape.yOffset = 0.0f;
+ this->actor.flags |= 0x10;
+ this->unk_240 = 200;
+ func_8091D660(this);
+ this->unkFunc = func_8091ED70;
+ this->unk_248 = 5;
+ this->unk_24C = 0.0f;
+}
+
+void func_8091ED70(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ s32 pad;
+ s16 sp2E;
+
+ if (this->unk_240 >= 0xBF) {
+ func_8091D840(thisx, globalCtx, 2, 25.0f);
+ }
+
+ Math_SmoothStepToF(&thisx->speedXZ, 2.8f, 0.1f, 0.4f, 0.0f);
+
+ if ((thisx->bgCheckFlags & 8) || !(thisx->bgCheckFlags & 0x20)) {
+ sp2E = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos);
+ thisx->home.rot.y = Rand_S16Offset(-100, 100) + sp2E;
+ thisx->speedXZ *= 0.5f;
+ }
+
+ this->unk_268 = 0;
+ this->unk_26A = thisx->home.rot.y;
+ this->unk_26C = 0;
+ this->unk_26E = 1000;
+ this->unk_270 = 2000;
+ this->unk_272 = 0x29B;
+
+ if (thisx->bgCheckFlags & 1) {
+ Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 4.0f, 2.0f);
+ } else {
+ Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 10.0f, 2.0f);
+ }
+
+ if (this->unk_240 < 100) {
+ this->unk_25C *= 0.982f;
+ func_8091D728(this);
+ }
+
+ if ((thisx->speedXZ * 1.5f) + 1.0f > 4.8f) {
+ this->skelAnime.playSpeed = 4.8f;
+ } else {
+ this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 1.0f;
+ }
+
+ if (this->unk_240 <= 0) {
+ Actor_MarkForDeath(thisx);
+ }
+}
+
+void func_8091EF30(EnFish* this) {
+ this->actor.gravity = -2.0f;
+ this->actor.minVelocityY = -10.0f;
+ this->actor.shape.yOffset = 0.0f;
+ if (this->actor.velocity.y < -1.0f) {
+ this->actor.velocity.y = -1.0f;
+ }
+ this->actor.flags |= 0x10;
+ this->actor.home.pos.x = this->actor.world.pos.x;
+ this->actor.home.pos.y = this->actor.world.pos.y - 20.0f;
+ this->actor.home.pos.z = this->actor.world.pos.z;
+ func_8091D660(this);
+ this->unk_240 = 15;
+ this->unk_279 = 10;
+ this->unkFunc = func_8091EFE8;
+ this->unk_248 = 5;
+ this->unk_24C = 0.0f;
+}
+
+void func_8091EFE8(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ s32 temp_v0_2;
+ Actor* sp3C = func_8091D944(this, globalCtx);
+ f32 temp_f0;
+ f32 sp34;
+ f32 sp30;
+ s16 sp2E;
+
+ if (sp3C == 0) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if (this->unk_240 <= 0) {
+ this->unk_240 = Rand_S16Offset(5, 35);
+ }
+
+ if (this->unk_277 == 0) {
+ Math_SmoothStepToF(&this->actor.speedXZ, 2.8f, 0.1f, 0.4f, 0.0f);
+ if (this->unk_240 < 6) {
+ this->actor.speedXZ *= 0.75f;
+ }
+ }
+
+ if ((this->actor.bgCheckFlags & 8) && !(this->actor.bgCheckFlags & 0x20)) {
+ this->actor.speedXZ *= 0.5f;
+ }
+
+ if (!((u32)Rand_Next() >> 0x1B) || ((this->actor.bgCheckFlags & 8) && !((u32)Rand_Next() >> 0x1E)) ||
+ !(this->actor.bgCheckFlags & 0x20)) {
+ temp_f0 = Rand_ZeroOne();
+ sp34 = (1.0f - SQ(temp_f0)) * sp3C->home.rot.x;
+ sp30 = Rand_ZeroOne() * sp3C->home.rot.z;
+ sp2E = (u32)Rand_Next() >> 0x10;
+ this->actor.home.pos.x = (Math_SinS(sp2E) * sp34) + sp3C->world.pos.x;
+ this->actor.home.pos.y = sp3C->world.pos.y + sp30;
+ this->actor.home.pos.z = (Math_CosS(sp2E) * sp34) + sp3C->world.pos.z;
+ this->actor.home.rot.y =
+ Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos) + Rand_S16Offset(-100, 100);
+ }
+
+ this->unk_268 = Math_Vec3f_Pitch(&this->actor.world.pos, &this->actor.home.pos);
+ this->unk_26C = 0;
+ this->unk_26A = this->actor.home.rot.y;
+
+ temp_v0_2 = BINANG_SUB(this->unk_268, this->actor.shape.rot.x);
+ temp_v0_2 = ABS_ALT(temp_v0_2);
+
+ temp_v0_2 = temp_v0_2 / 11;
+ if (temp_v0_2 > 800) {
+ temp_v0_2 = 800;
+ } else if (temp_v0_2 < 100) {
+ temp_v0_2 = 100;
+ }
+
+ if (this->unk_279 > 0) {
+ this->unk_279--;
+ this->unk_26E = 1000;
+ } else {
+ this->unk_26E = temp_v0_2;
+ }
+
+ if (this->unk_240 < 10) {
+ this->unk_270 = 400;
+ } else {
+ this->unk_270 = 2000;
+ }
+
+ this->unk_272 = 0x29B;
+ if (fabsf(this->actor.world.pos.y - this->actor.home.pos.y) < 2.0f) {
+ this->actor.gravity = 0.0f;
+ } else if (this->actor.home.pos.y < this->actor.world.pos.y) {
+ this->actor.gravity = -0.15f;
+ } else {
+ this->actor.gravity = 0.15f;
+ }
+
+ this->actor.velocity.y *= 0.8f;
+ if ((this->actor.speedXZ * 1.5f) + 1.0f > 4.8f) {
+ this->skelAnime.playSpeed = 4.8f;
+ } else {
+ this->skelAnime.playSpeed = (this->actor.speedXZ * 1.5f) + 1.0f;
+ }
+}
+
+void func_8091F344(EnFish* this) {
+ this->actor.gravity = 0.0f;
+ this->actor.minVelocityY = 0.0f;
+ this->unk_240 = Rand_S16Offset(5, 35);
+ this->unk_248 = 1;
+ this->unk_268 = 0;
+ this->unk_26C = 0;
+ this->unk_26E = 1500;
+ this->unk_272 = 0;
+ func_8091D660(this);
+ this->unkFunc = func_8091F3BC;
+ this->unk_24C = 0.0f;
+}
+
+void func_8091F3BC(Actor* thisx, GlobalContext* globalCtx) {
+ static Vec3f D_8091FADC = { 0.0f, 0.04f, 0.09f };
+ static Vec3f D_8091FAE8 = { 0.5f, 0.1f, 0.15f };
+ EnFish* this = THIS;
+ s32 sp40 = globalCtx->gameplayFrames;
+ Vec3f* sp3C;
+ f32 phi_f0;
+ f32 temp_f2;
+
+ if ((this->actor.xzDistToPlayer < 60.0f) || ((sp40 & 0x1FF) < 20)) {
+ if (this->unk_240 < 12) {
+ sp3C = &D_8091FAE8;
+ } else {
+ sp3C = &D_8091FADC;
+ }
+ } else if (this->unk_240 < 4) {
+ sp3C = &D_8091FAE8;
+ } else {
+ sp3C = &D_8091FADC;
+ }
+
+ func_8091DD48(this);
+ Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 2.0f);
+ Math_SmoothStepToF(&this->actor.speedXZ, sp3C->x, sp3C->y, sp3C->z, 0.0f);
+ this->unk_24C = 0.0f;
+
+ if (func_8091D630(&this->actor.world.pos, &this->actor.home.pos) > SQ(15.0f)) {
+ this->unk_26A = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
+ this->unk_270 = 0x85;
+ phi_f0 = 0.4f;
+ } else if (this->unk_240 < 4) {
+ this->unk_26A = sp40 << 7;
+ this->unk_270 = 0x43;
+ phi_f0 = 0.4f;
+ } else {
+ this->unk_270 = 0;
+ phi_f0 = 0.0f;
+ }
+
+ temp_f2 = this->actor.speedXZ + 0.4f + phi_f0;
+ this->skelAnime.playSpeed = CLAMP(temp_f2, 0.5f, 1.6f);
+
+ if (this->unk_240 <= 0) {
+ this->unk_240 = Rand_S16Offset(5, 80);
+ }
+}
+
+void func_8091F5A4(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ Actor* temp_v0_2;
+ s16 temp_v0;
+ s16 temp_v0_4;
+ s32 temp_v1;
+ s32 phi_v1;
+ f32 phi_f0;
+
+ if (this->unk_240 > 0) {
+ this->unk_240--;
+ }
+
+ this->unk_244 += 0x111;
+ this->unk_246 += 0x500;
+
+ if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (thisx != this->actor.child)) {
+ this->actor.child = NULL;
+ }
+
+ if ((this->unkFunc == NULL) || (this->unkFunc(&this->actor, globalCtx), (this->actor.update != NULL))) {
+ if ((ABS_ALT(BINANG_SUB(this->unk_26A, this->actor.shape.rot.y)) > 0x3000) && (this->unk_270 > 1000)) {
+ this->skelAnime.playSpeed += this->unk_24C;
+ }
+ SkelAnime_Update(&this->skelAnime);
+ func_8091D7C4(this);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ if (this->unk_248 != 0) {
+ u32 temp = (globalCtx->sceneNum ^ SCENE_LABO) != 0;
+ phi_f0 = BREG(1) + 10.0f;
+
+ if (temp) {
+ phi_f0 = 6.0f;
+ }
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 17.5f, phi_f0, 0.0f, this->unk_248);
+ }
+
+ if ((this->actor.xzDistToPlayer < 70.0f) && (this->unkFunc != func_8091EFE8)) {
+ ColliderJntSphElement* element = &this->collider.elements[0];
+
+ element->dim.worldSphere.center.x = this->actor.world.pos.x;
+ element->dim.worldSphere.center.y = this->actor.world.pos.y;
+ element->dim.worldSphere.center.z = this->actor.world.pos.z;
+ element->dim.worldSphere.radius = this->unk_25C * 500.0f;
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+
+ Actor_SetHeight(&this->actor, this->actor.shape.yOffset * 0.01f);
+
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ this->actor.parent = NULL;
+ if (this->actor.params == ENFISH_0) {
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ func_8091D904(this);
+ }
+ } else if (func_8091DDF4(this, globalCtx)) {
+ func_800B8A1C(&this->actor, globalCtx, 0xBA, 80.0f, 25.0f);
+ }
+ }
+}
+
+void func_8091F830(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+
+ if (this->actor.params == ENFISH_1) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (thisx != this->actor.child)) {
+ this->actor.child = NULL;
+ }
+
+ if ((this->unkFunc == NULL) || (this->unkFunc(&this->actor, globalCtx), (this->actor.update != NULL))) {
+ func_8091D7C4(this);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+
+ if (this->unk_242 == 20) {
+ this->actor.draw = EnFish_Draw;
+ } else if (this->unk_242 == 0) {
+ this->unk_25C = this->unk_260;
+ func_8091D728(this);
+ } else if (this->unk_242 < 20) {
+ this->unk_25C += 0.1f * this->unk_260;
+ if (this->unk_260 < this->unk_25C) {
+ this->unk_25C = this->unk_260;
+ }
+ func_8091D728(this);
+ }
+ }
+}
+
+void EnFish_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+
+ if (this->unk_242 > 0) {
+ this->unk_242--;
+ func_8091F830(thisx, globalCtx);
+ } else {
+ func_8091F5A4(thisx, globalCtx);
+ }
+
+ if (this->unk_276 > 0) {
+ this->unk_276--;
+ }
+}
+
+void func_8091F994(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnFish* this = THIS;
+ Color_RGB8* colour = &D_8091FA94[this->unk_278];
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colour->r, colour->g, colour->b, 255);
+
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ NULL, NULL, NULL);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Fish/z_en_fish.h b/src/overlays/actors/ovl_En_Fish/z_en_fish.h
index 7d4a9f0cf..fd35ef626 100644
--- a/src/overlays/actors/ovl_En_Fish/z_en_fish.h
+++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.h
@@ -5,11 +5,47 @@
struct EnFish;
+typedef void (*EnFishUnkFunc)(Actor*, GlobalContext*);
+
+enum {
+ /* -1 */ ENFISH_MINUS1 = -1,
+ /* 0 */ ENFISH_0,
+ /* 1 */ ENFISH_1,
+ /* 2 */ ENFISH_2,
+};
+
typedef struct EnFish {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk144[0x133];
- /* 0x277 */ s8 unk_277;
- /* 0x278 */ char unk278[0x4];
+ /* 0x144 */ ColliderJntSph collider;
+ /* 0x164 */ ColliderJntSphElement colliderElements[1];
+ /* 0x1A4 */ SkelAnime skelAnime;
+ /* 0x1E8 */ Vec3s jointTable[7];
+ /* 0x212 */ Vec3s morphTable[7];
+ /* 0x23C */ EnFishUnkFunc unkFunc;
+ /* 0x240 */ s16 unk_240;
+ /* 0x242 */ s16 unk_242;
+ /* 0x244 */ s16 unk_244;
+ /* 0x246 */ s16 unk_246;
+ /* 0x248 */ s32 unk_248;
+ /* 0x24C */ f32 unk_24C;
+ /* 0x250 */ f32 unk_250;
+ /* 0x254 */ f32 unk_254;
+ /* 0x258 */ f32 unk_258;
+ /* 0x25C */ f32 unk_25C;
+ /* 0x260 */ f32 unk_260;
+ /* 0x264 */ s16 unk_264;
+ /* 0x266 */ s16 unk_266;
+ /* 0x268 */ s16 unk_268;
+ /* 0x26A */ s16 unk_26A;
+ /* 0x26C */ s16 unk_26C;
+ /* 0x26E */ s16 unk_26E;
+ /* 0x270 */ s16 unk_270;
+ /* 0x272 */ s16 unk_272;
+ /* 0x274 */ s16 unk_274;
+ /* 0x276 */ s8 unk_276;
+ /* 0x277 */ u8 unk_277;
+ /* 0x278 */ s8 unk_278;
+ /* 0x279 */ s8 unk_279;
} EnFish; // size = 0x27C
extern const ActorInit En_Fish_InitVars;
diff --git a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
index d1f93bdbc..54288e426 100644
--- a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
+++ b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
@@ -1,21 +1,204 @@
/*
* File: z_en_fishing.c
* Overlay: ovl_En_Fishing
- * Description: Fishing
+ * Description: Fishing Pond Elements (Owner, Fish, Props, Effects...)
*/
#include "z_en_fishing.h"
+#include "objects/object_fish/object_fish.h"
+#include "overlays/actors/ovl_En_Kanban/z_en_kanban.h"
#define FLAGS 0x00000010
#define THIS ((EnFishing*)thisx)
+#define WATER_SURFACE_Y(globalCtx) globalCtx->colCtx.colHeader->waterBoxes->minPos.y
+
void EnFishing_Init(Actor* thisx, GlobalContext* globalCtx);
void EnFishing_Destroy(Actor* thisx, GlobalContext* globalCtx);
-void EnFishing_Update(Actor* thisx, GlobalContext* globalCtx);
-void EnFishing_Draw(Actor* thisx, GlobalContext* globalCtx);
+void EnFishing_UpdateFish(Actor* thisx, GlobalContext* globalCtx);
+void EnFishing_DrawFish(Actor* thisx, GlobalContext* globalCtx);
+
+void EnFishing_UpdateOwner(Actor* thisx, GlobalContext* globalCtx);
+void EnFishing_DrawOwner(Actor* thisx, GlobalContext* globalCtx);
+
+typedef struct {
+ /* 0x00 */ u8 unk_00;
+ /* 0x02 */ Vec3s pos;
+ /* 0x08 */ u8 unk_08;
+ /* 0x0C */ f32 unk_0C;
+} FishingFishInit; // size = 0x10
+
+#define EFFECT_COUNT 130
+
+typedef enum {
+ /* 0x00 */ FS_EFF_NONE,
+ /* 0x01 */ FS_EFF_RIPPLE,
+ /* 0x02 */ FS_EFF_DUST_SPLASH,
+ /* 0x03 */ FS_EFF_WATER_DUST,
+ /* 0x04 */ FS_EFF_BUBBLE,
+ /* 0x05 */ FS_EFF_RAIN_DROP,
+ /* 0x06 */ FS_EFF_OWNER_HAT,
+ /* 0x07 */ FS_EFF_RAIN_RIPPLE,
+ /* 0x08 */ FS_EFF_RAIN_SPLASH
+} FishingEffectType;
+
+typedef struct {
+ /* 0x00 */ Vec3f pos;
+ /* 0x0C */ Vec3f vel;
+ /* 0x18 */ Vec3f accel;
+ /* 0x24 */ u8 type;
+ /* 0x25 */ u8 timer;
+ /* 0x26 */ UNK_TYPE1 unk_26[0x04];
+ /* 0x2A */ s16 alpha;
+ /* 0x2C */ s16 unk_2C;
+ /* 0x2E */ s16 unk_2E;
+ /* 0x30 */ f32 unk_30;
+ /* 0x34 */ f32 unk_34;
+ /* 0x38 */ f32 unk_38;
+ /* 0x3C */ f32 unk_3C;
+} FishingEffect; // size = 0x40
+
+#define POND_PROP_COUNT 140
+
+typedef enum {
+ /* 0x00 */ FS_PROP_NONE,
+ /* 0x01 */ FS_PROP_REED,
+ /* 0x02 */ FS_PROP_LILY_PAD,
+ /* 0x03 */ FS_PROP_ROCK,
+ /* 0x04 */ FS_PROP_WOOD_POST,
+ /* 0x23 */ FS_PROP_INIT_STOP = 0x23
+} FishingPropType;
+
+typedef struct {
+ /* 0x00 */ u8 type;
+ /* 0x02 */ Vec3s pos;
+} FishingPropInit; // size = 0x08
+
+typedef struct {
+ /* 0x00 */ Vec3f pos;
+ /* 0x0C */ f32 rotX;
+ /* 0x10 */ f32 rotY;
+ /* 0x14 */ f32 reedAngle;
+ /* 0x18 */ Vec3f projectedPos;
+ /* 0x24 */ f32 scale;
+ /* 0x28 */ s16 lilyPadAngle;
+ /* 0x2C */ f32 lilyPadOffset;
+ /* 0x30 */ u8 type;
+ /* 0x32 */ s16 timer;
+ /* 0x34 */ u8 shouldDraw;
+ /* 0x38 */ f32 drawDistance;
+} FishingProp; // size = 0x3C
+
+typedef enum {
+ /* 0x00 */ FS_GROUP_FISH_NONE,
+ /* 0x01 */ FS_GROUP_FISH_NORMAL
+} FishingGroupFishType;
+
+#define GROUP_FISH_COUNT 60
+
+typedef struct {
+ /* 0x00 */ u8 type;
+ /* 0x02 */ s16 timer;
+ /* 0x04 */ Vec3f pos;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ Vec3f projectedPos;
+ /* 0x28 */ f32 unk_28;
+ /* 0x2C */ f32 unk_2C;
+ /* 0x30 */ f32 unk_30;
+ /* 0x34 */ f32 unk_34;
+ /* 0x38 */ f32 unk_38;
+ /* 0x3C */ s16 unk_3C;
+ /* 0x3E */ s16 unk_3E;
+ /* 0x40 */ s16 unk_40;
+ /* 0x42 */ s16 unk_42;
+ /* 0x44 */ u8 shouldDraw;
+} FishingGroupFish; // size = 0x48
+
+#define LINE_SEG_COUNT 200
+#define SINKING_LURE_SEG_COUNT 20
+
+static f32 D_809101B0;
+static f32 D_809101B4;
+static s16 D_809101B8;
+static f32 D_809101BC;
+static f32 D_809101C0;
+static f32 D_809101C4;
+static f32 D_809101C8;
+static s16 D_809101CC;
+static f32 D_809101D0;
+static Vec3f sRodTipPos;
+static Vec3f sReelLinePos[LINE_SEG_COUNT];
+static Vec3f sReelLineRot[LINE_SEG_COUNT];
+static Vec3f sReelLineUnk[LINE_SEG_COUNT];
+static Vec3f sLureHookRefPos[2];
+static f32 sLureHookRotY[2];
+static u8 D_80911E28;
+static Vec3f sSinkingLurePos[SINKING_LURE_SEG_COUNT];
+static s16 D_80911F20;
+static f32 sProjectedW;
+static Vec3f sCameraEye;
+static Vec3f sCameraAt;
+static s16 sCameraId;
+static f32 D_80911F48;
+static f32 D_80911F4C;
+static f32 D_80911F50;
+static Vec3f sSinkingLureBasePos;
+static f32 D_80911F64;
+static s32 sRandSeed0;
+static s32 sRandSeed1;
+static s32 sRandSeed2;
+static FishingProp sPondProps[POND_PROP_COUNT];
+static FishingGroupFish sGroupFishes[GROUP_FISH_COUNT];
+static f32 sFishGroupAngle1;
+static f32 sFishGroupAngle2;
+static f32 sFishGroupAngle3;
+static FishingEffect sFishingEffects[EFFECT_COUNT];
+static Vec3f sStreamSoundProjectedPos;
+static EnFishing* sFishingMain;
+static u8 D_809171C8;
+static u8 sLinkAge;
+static u8 D_809171CA;
+static u8 D_809171CB;
+static f32 D_809171CC;
+static u8 D_809171D0;
+static u8 D_809171D1;
+static u8 D_809171D2;
+static s16 D_809171D4;
+static u8 D_809171D6;
+static u16 D_809171D8;
+static u16 D_809171DA;
+static s8 D_809171DC;
+static Vec3f sOwnerHeadPos;
+static Vec3s sEffOwnerHatRot;
+static u8 D_809171F2;
+static s16 D_809171F4;
+static s16 D_809171F6;
+static EnFishing* sFishingHookedFish;
+static s16 D_809171FC;
+static s16 D_809171FE;
+static s16 D_80917200;
+static s16 D_80917202;
+static s16 D_80917204;
+static u8 D_80917206;
+static Vec3f sLurePos;
+static Vec3f D_80917218;
+static Vec3f sLureRot;
+static Vec3f D_80917238;
+static Vec3f D_80917248;
+static f32 D_80917254;
+static f32 D_80917258;
+static f32 D_8091725C;
+static f32 D_80917260;
+static s8 D_80917264;
+static s16 D_80917266;
+static u8 D_80917268;
+static f32 D_8091726C;
+static u8 D_80917270;
+static s16 D_80917272;
+static u8 D_80917274;
+static Vec3f D_80917278;
-#if 0
const ActorInit En_Fishing_InitVars = {
ACTOR_EN_FISHING,
ACTORCAT_NPC,
@@ -24,181 +207,5503 @@ const ActorInit En_Fishing_InitVars = {
sizeof(EnFishing),
(ActorFunc)EnFishing_Init,
(ActorFunc)EnFishing_Destroy,
- (ActorFunc)EnFishing_Update,
- (ActorFunc)EnFishing_Draw,
+ (ActorFunc)EnFishing_UpdateFish,
+ (ActorFunc)EnFishing_DrawFish,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[12] = {
-static ColliderJntSphElementInit D_8090CD58[12] = {
+static f32 D_8090CCD0 = 0.0f;
+static u8 D_8090CCD4 = 0;
+static f32 D_8090CCD8 = 0.0f;
+static Vec3f D_8090CCDC = { 0.0f, 0.0f, 0.0f };
+static f32 D_8090CCE8 = 0.0f;
+static u8 sSinkingLureLocation = 0;
+static f32 D_8090CCF0 = 0.0f;
+static u8 D_8090CCF4 = true;
+static u16 D_8090CCF8 = 0;
+static u8 D_8090CCFC = 0;
+static s32 D_8090CD00 = 0;
+static s16 D_8090CD04 = 0;
+static u8 D_8090CD08 = 0;
+static u8 D_8090CD0C = 0;
+static u8 D_8090CD10 = 0;
+static s16 D_8090CD14 = 0;
+static Vec3f sFishMouthOffset = { 500.0f, 500.0f, 0.0f };
+static u8 D_8090CD24 = 0;
+static f32 D_8090CD28 = 0;
+static f32 D_8090CD2C = 0;
+static f32 D_8090CD30 = 0.0f;
+static f32 D_8090CD34 = 0.0f;
+static f32 D_8090CD38 = 0.0f;
+static f32 D_8090CD3C = 0.0f;
+static f32 D_8090CD40 = 0.0f;
+static s16 D_8090CD44 = 0;
+static s16 D_8090CD48 = 0;
+static u8 D_8090CD4C = 0;
+static u8 D_8090CD50 = 0;
+static u8 D_8090CD54 = 0;
+
+static ColliderJntSphElementInit sJntSphElementsInit[12] = {
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 30 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_8090CF08 = {
- { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 12, D_8090CD58, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE | AT_TYPE_ENEMY,
+ AC_NONE | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 12,
+ sJntSphElementsInit,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8090D4D0[] = {
+static u8 D_8090CF18 = 0;
+static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
+static Vec3f D_8090CF28 = { 0.0f, 0.0f, 2000.0f }; // Unused
+
+void EnFishing_SetColliderElement(s32 index, ColliderJntSph* collider, Vec3f* pos, f32 scale) {
+ collider->elements[index].dim.worldSphere.center.x = pos->x;
+ collider->elements[index].dim.worldSphere.center.y = pos->y;
+ collider->elements[index].dim.worldSphere.center.z = pos->z;
+ collider->elements[index].dim.worldSphere.radius =
+ collider->elements[index].dim.modelSphere.radius * collider->elements[index].dim.scale * scale * 1.6f;
+}
+
+void EnFishing_SeedRand(s32 seed0, s32 seed1, s32 seed2) {
+ sRandSeed0 = seed0;
+ sRandSeed1 = seed1;
+ sRandSeed2 = seed2;
+}
+
+f32 EnFishing_RandZeroOne(void) {
+ f32 rand;
+
+ // Wichmann-Hill algorithm
+ sRandSeed0 = (sRandSeed0 * 171) % 30269;
+ sRandSeed1 = (sRandSeed1 * 172) % 30307;
+ sRandSeed2 = (sRandSeed2 * 170) % 30323;
+
+ rand = (sRandSeed0 / 30269.0f) + (sRandSeed1 / 30307.0f) + (sRandSeed2 / 30323.0f);
+ while (rand >= 1.0f) {
+ rand -= 1.0f;
+ }
+
+ return fabsf(rand);
+}
+
+s16 EnFishing_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step) {
+ s16 stepSize;
+ s16 diff;
+
+ diff = target - *pValue;
+ stepSize = diff / scale;
+
+ if (stepSize > step) {
+ stepSize = step;
+ }
+
+ if (stepSize < -step) {
+ stepSize = -step;
+ }
+
+ *pValue += stepSize;
+
+ return stepSize;
+}
+
+void EnFishing_SpawnRipple(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 arg3, f32 arg4, s16 arg5,
+ s16 countLimit) {
+ s16 i;
+
+ if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) {
+ return;
+ }
+
+ for (i = 0; i < countLimit; i++) {
+ if (effect->type == FS_EFF_NONE) {
+ effect->type = FS_EFF_RIPPLE;
+ effect->pos = *pos;
+ effect->vel = sZeroVec;
+ effect->accel = sZeroVec;
+ effect->unk_30 = arg3 * 0.0025f;
+ effect->unk_34 = arg4 * 0.0025f;
+
+ if (arg3 > 300.0f) {
+ effect->alpha = 0;
+ effect->unk_2E = arg5;
+ effect->unk_2C = 0;
+ effect->unk_38 = (effect->unk_34 - effect->unk_30) * 0.05f;
+ } else {
+ effect->alpha = arg5;
+ effect->unk_2C = 1;
+ effect->unk_38 = (effect->unk_34 - effect->unk_30) * 0.1f;
+ }
+ break;
+ }
+
+ effect++;
+ }
+}
+
+void EnFishing_SpawnDustSplash(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, Vec3f* vel, f32 scale) {
+ s16 i;
+ Vec3f accel = { 0.0f, -1.0f, 0.0f };
+
+ if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) {
+ return;
+ }
+
+ for (i = 0; i < 100; i++) {
+ if ((effect->type == FS_EFF_NONE) || (effect->type == FS_EFF_RAIN_DROP) ||
+ (effect->type == FS_EFF_RAIN_RIPPLE) || (effect->type == FS_EFF_RAIN_SPLASH)) {
+ effect->type = FS_EFF_DUST_SPLASH;
+ effect->pos = *pos;
+ effect->vel = *vel;
+ effect->accel = accel;
+ effect->alpha = 100 + Rand_ZeroFloat(100.0f);
+ effect->unk_30 = scale;
+ break;
+ }
+
+ effect++;
+ }
+}
+
+void EnFishing_SpawnWaterDust(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 scale) {
+ s16 i;
+ Vec3f accel = { 0.0f, 0.05f, 0.0f };
+
+ if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) {
+ return;
+ }
+
+ for (i = 0; i < 90; i++) {
+ if (effect->type == FS_EFF_NONE) {
+ effect->type = FS_EFF_WATER_DUST;
+ effect->pos = *pos;
+ effect->vel = sZeroVec;
+ effect->accel = accel;
+ effect->alpha = 255;
+ effect->timer = Rand_ZeroFloat(100.0f);
+ effect->unk_30 = scale;
+ effect->unk_34 = 2.0f * scale;
+ break;
+ }
+
+ effect++;
+ }
+}
+
+void EnFishing_SpawnBubble(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 scale, u8 arg4) {
+ s16 i;
+ Vec3f vel = { 0.0f, 1.0f, 0.0f };
+
+ if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) {
+ return;
+ }
+
+ for (i = 0; i < 90; i++) {
+ if (effect->type == FS_EFF_NONE) {
+ effect->type = FS_EFF_BUBBLE;
+ effect->pos = *pos;
+ effect->vel = vel;
+ effect->accel = sZeroVec;
+ effect->timer = Rand_ZeroFloat(100.0f);
+ effect->unk_30 = scale;
+ effect->unk_2C = arg4;
+ break;
+ }
+
+ effect++;
+ }
+}
+
+void EnFishing_SpawnRainDrop(FishingEffect* effect, Vec3f* pos, Vec3f* rot) {
+ s16 i;
+ Vec3f velSrc;
+
+ velSrc.x = 0.0f;
+ velSrc.y = 0.0f;
+ velSrc.z = 300.0f;
+
+ effect += 30;
+
+ for (i = 30; i < EFFECT_COUNT; i++) {
+ if (effect->type == FS_EFF_NONE) {
+ effect->type = FS_EFF_RAIN_DROP;
+ effect->pos = *pos;
+ effect->accel = sZeroVec;
+ effect->unk_34 = rot->x;
+ effect->unk_38 = rot->y;
+ effect->unk_3C = rot->z;
+ Matrix_InsertYRotation_f(rot->y, MTXMODE_NEW);
+ Matrix_RotateStateAroundXAxis(rot->x);
+ Matrix_MultiplyVector3fByState(&velSrc, &effect->vel);
+ break;
+ }
+
+ effect++;
+ }
+}
+
+static FishingPropInit sPondPropInits[POND_PROP_COUNT + 1] = {
+ { FS_PROP_ROCK, { 529, -53, -498 } },
+ { FS_PROP_ROCK, { 461, -66, -480 } },
+ { FS_PROP_ROCK, { 398, -73, -474 } },
+ { FS_PROP_ROCK, { -226, -52, -691 } },
+ { FS_PROP_ROCK, { -300, -41, -710 } },
+ { FS_PROP_ROCK, { -333, -50, -643 } },
+ { FS_PROP_ROCK, { -387, -46, -632 } },
+ { FS_PROP_ROCK, { -484, -43, -596 } },
+ { FS_PROP_ROCK, { -409, -57, -560 } },
+ { FS_PROP_WOOD_POST, { 444, -87, -322 } },
+ { FS_PROP_WOOD_POST, { 447, -91, -274 } },
+ { FS_PROP_WOOD_POST, { 395, -109, -189 } },
+ { FS_PROP_REED, { 617, -29, 646 } },
+ { FS_PROP_REED, { 698, -26, 584 } },
+ { FS_PROP_REED, { 711, -29, 501 } },
+ { FS_PROP_REED, { 757, -28, 457 } },
+ { FS_PROP_REED, { 812, -29, 341 } },
+ { FS_PROP_REED, { 856, -30, 235 } },
+ { FS_PROP_REED, { 847, -31, 83 } },
+ { FS_PROP_REED, { 900, -26, 119 } },
+ { FS_PROP_LILY_PAD, { 861, -22, 137 } },
+ { FS_PROP_LILY_PAD, { 836, -22, 150 } },
+ { FS_PROP_LILY_PAD, { 829, -22, 200 } },
+ { FS_PROP_LILY_PAD, { 788, -22, 232 } },
+ { FS_PROP_LILY_PAD, { 803, -22, 319 } },
+ { FS_PROP_LILY_PAD, { 756, -22, 348 } },
+ { FS_PROP_LILY_PAD, { 731, -22, 377 } },
+ { FS_PROP_LILY_PAD, { 700, -22, 392 } },
+ { FS_PROP_LILY_PAD, { 706, -22, 351 } },
+ { FS_PROP_LILY_PAD, { 677, -22, 286 } },
+ { FS_PROP_LILY_PAD, { 691, -22, 250 } },
+ { FS_PROP_LILY_PAD, { 744, -22, 290 } },
+ { FS_PROP_LILY_PAD, { 766, -22, 201 } },
+ { FS_PROP_LILY_PAD, { 781, -22, 128 } },
+ { FS_PROP_LILY_PAD, { 817, -22, 46 } },
+ { FS_PROP_LILY_PAD, { 857, -22, -50 } },
+ { FS_PROP_LILY_PAD, { 724, -22, 110 } },
+ { FS_PROP_LILY_PAD, { 723, -22, 145 } },
+ { FS_PROP_LILY_PAD, { 728, -22, 202 } },
+ { FS_PROP_LILY_PAD, { 721, -22, 237 } },
+ { FS_PROP_LILY_PAD, { 698, -22, 312 } },
+ { FS_PROP_LILY_PAD, { 660, -22, 349 } },
+ { FS_PROP_LILY_PAD, { 662, -22, 388 } },
+ { FS_PROP_LILY_PAD, { 667, -22, 432 } },
+ { FS_PROP_LILY_PAD, { 732, -22, 429 } },
+ { FS_PROP_LILY_PAD, { 606, -22, 366 } },
+ { FS_PROP_LILY_PAD, { 604, -22, 286 } },
+ { FS_PROP_LILY_PAD, { 620, -22, 217 } },
+ { FS_PROP_LILY_PAD, { 663, -22, 159 } },
+ { FS_PROP_LILY_PAD, { 682, -22, 73 } },
+ { FS_PROP_LILY_PAD, { 777, -22, 83 } },
+ { FS_PROP_LILY_PAD, { 766, -22, 158 } },
+ { FS_PROP_REED, { 1073, 0, -876 } },
+ { FS_PROP_REED, { 970, 0, -853 } },
+ { FS_PROP_REED, { 896, 0, -886 } },
+ { FS_PROP_REED, { 646, -27, -651 } },
+ { FS_PROP_REED, { 597, -29, -657 } },
+ { FS_PROP_REED, { 547, -32, -651 } },
+ { FS_PROP_REED, { 690, -29, -546 } },
+ { FS_PROP_REED, { 720, -29, -490 } },
+ { FS_PROP_REED, { -756, -30, -409 } },
+ { FS_PROP_REED, { -688, -34, -458 } },
+ { FS_PROP_REED, { -613, -34, -581 } },
+ { FS_PROP_LILY_PAD, { -593, -22, -479 } },
+ { FS_PROP_LILY_PAD, { -602, -22, -421 } },
+ { FS_PROP_LILY_PAD, { -664, -22, -371 } },
+ { FS_PROP_LILY_PAD, { -708, -22, -316 } },
+ { FS_PROP_LILY_PAD, { -718, -22, -237 } },
+ { FS_PROP_REED, { -807, -36, -183 } },
+ { FS_PROP_REED, { -856, -29, -259 } },
+ { FS_PROP_LILY_PAD, { -814, -22, -317 } },
+ { FS_PROP_LILY_PAD, { -759, -22, -384 } },
+ { FS_PROP_LILY_PAD, { -718, -22, -441 } },
+ { FS_PROP_LILY_PAD, { -474, -22, -567 } },
+ { FS_PROP_LILY_PAD, { -519, -22, -517 } },
+ { FS_PROP_LILY_PAD, { -539, -22, -487 } },
+ { FS_PROP_LILY_PAD, { -575, -22, -442 } },
+ { FS_PROP_LILY_PAD, { -594, -22, -525 } },
+ { FS_PROP_LILY_PAD, { -669, -22, -514 } },
+ { FS_PROP_LILY_PAD, { -653, -22, -456 } },
+ { FS_PROP_REED, { -663, -28, -606 } },
+ { FS_PROP_REED, { -708, -26, -567 } },
+ { FS_PROP_REED, { -739, -27, -506 } },
+ { FS_PROP_REED, { -752, -28, -464 } },
+ { FS_PROP_REED, { -709, -29, -513 } },
+ { FS_PROP_LILY_PAD, { -544, -22, -436 } },
+ { FS_PROP_LILY_PAD, { -559, -22, -397 } },
+ { FS_PROP_LILY_PAD, { -616, -22, -353 } },
+ { FS_PROP_LILY_PAD, { -712, -22, -368 } },
+ { FS_PROP_LILY_PAD, { -678, -22, -403 } },
+ { FS_PROP_LILY_PAD, { -664, -22, -273 } },
+ { FS_PROP_LILY_PAD, { -630, -22, -276 } },
+ { FS_PROP_LILY_PAD, { -579, -22, -311 } },
+ { FS_PROP_LILY_PAD, { -588, -22, -351 } },
+ { FS_PROP_LILY_PAD, { -555, -22, -534 } },
+ { FS_PROP_LILY_PAD, { -547, -22, -567 } },
+ { FS_PROP_LILY_PAD, { -592, -22, -571 } },
+ { FS_PROP_LILY_PAD, { -541, -22, -610 } },
+ { FS_PROP_LILY_PAD, { -476, -22, -629 } },
+ { FS_PROP_LILY_PAD, { -439, -22, -598 } },
+ { FS_PROP_LILY_PAD, { -412, -22, -550 } },
+ { FS_PROP_LILY_PAD, { -411, -22, -606 } },
+ { FS_PROP_LILY_PAD, { -370, -22, -634 } },
+ { FS_PROP_LILY_PAD, { -352, -22, -662 } },
+ { FS_PROP_LILY_PAD, { -413, -22, -641 } },
+ { FS_PROP_LILY_PAD, { -488, -22, -666 } },
+ { FS_PROP_LILY_PAD, { -578, -22, -656 } },
+ { FS_PROP_LILY_PAD, { -560, -22, -640 } },
+ { FS_PROP_LILY_PAD, { -531, -22, -654 } },
+ { FS_PROP_LILY_PAD, { -451, -22, -669 } },
+ { FS_PROP_LILY_PAD, { -439, -22, -699 } },
+ { FS_PROP_LILY_PAD, { -482, -22, -719 } },
+ { FS_PROP_LILY_PAD, { -524, -22, -720 } },
+ { FS_PROP_LILY_PAD, { -569, -22, -714 } },
+ { FS_PROP_REED, { -520, -27, -727 } },
+ { FS_PROP_REED, { -572, -28, -686 } },
+ { FS_PROP_REED, { -588, -32, -631 } },
+ { FS_PROP_REED, { -622, -34, -571 } },
+ { FS_PROP_REED, { -628, -36, -510 } },
+ { FS_PROP_REED, { -655, -36, -466 } },
+ { FS_PROP_REED, { -655, -41, -393 } },
+ { FS_PROP_REED, { -661, -47, -328 } },
+ { FS_PROP_REED, { -723, -40, -287 } },
+ { FS_PROP_REED, { -756, -33, -349 } },
+ { FS_PROP_REED, { -755, -43, -210 } },
+ { FS_PROP_LILY_PAD, { -770, -22, -281 } },
+ { FS_PROP_LILY_PAD, { -750, -22, -313 } },
+ { FS_PROP_LILY_PAD, { -736, -22, -341 } },
+ { FS_PROP_LILY_PAD, { -620, -22, -418 } },
+ { FS_PROP_LILY_PAD, { -601, -22, -371 } },
+ { FS_PROP_LILY_PAD, { -635, -22, -383 } },
+ { FS_PROP_LILY_PAD, { -627, -22, -311 } },
+ { FS_PROP_LILY_PAD, { -665, -22, -327 } },
+ { FS_PROP_LILY_PAD, { -524, -22, -537 } },
+ { FS_PROP_LILY_PAD, { -514, -22, -579 } },
+ { FS_PROP_LILY_PAD, { -512, -22, -623 } },
+ { FS_PROP_LILY_PAD, { -576, -22, -582 } },
+ { FS_PROP_LILY_PAD, { -600, -22, -608 } },
+ { FS_PROP_LILY_PAD, { -657, -22, -531 } },
+ { FS_PROP_LILY_PAD, { -641, -22, -547 } },
+ { FS_PROP_INIT_STOP, { 0 } },
+};
+
+void EnFishing_InitPondProps(EnFishing* this, GlobalContext* globalCtx) {
+ FishingProp* prop = &sPondProps[0];
+ Vec3f colliderPos;
+ s16 i;
+
+ EnFishing_SeedRand(1, 29100, 9786);
+
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (sPondPropInits[i].type == FS_PROP_INIT_STOP) {
+ break;
+ }
+
+ prop->type = sPondPropInits[i].type;
+ prop->pos.x = sPondPropInits[i].pos.x;
+ prop->pos.y = sPondPropInits[i].pos.y;
+ prop->pos.z = sPondPropInits[i].pos.z;
+ prop->rotX = 0.0f;
+ prop->reedAngle = 0.0f;
+
+ prop->timer = Rand_ZeroFloat(100.0f);
+ prop->drawDistance = 800.0f;
+
+ if (prop->type == FS_PROP_REED) {
+ prop->scale = (EnFishing_RandZeroOne() * 0.25f) + 0.75f;
+ prop->reedAngle = Rand_ZeroFloat(2 * M_PI);
+ if (sLinkAge == 1) {
+ prop->scale *= 0.6f;
+ }
+ prop->drawDistance = 1200.0f;
+ } else if (prop->type == FS_PROP_WOOD_POST) {
+ prop->scale = 0.08f;
+ prop->drawDistance = 1200.0f;
+ colliderPos = prop->pos;
+ colliderPos.y += 50.0f;
+ EnFishing_SetColliderElement(i, &sFishingMain->collider, &colliderPos, prop->scale * 3.5f);
+ } else if (prop->type == FS_PROP_LILY_PAD) {
+ prop->scale = (EnFishing_RandZeroOne() * 0.3f) + 0.5f;
+ prop->rotY = Rand_ZeroFloat(2 * M_PI);
+ if (sLinkAge == 1) {
+ if ((i % 4) != 0) {
+ prop->scale *= 0.6f;
+ } else {
+ prop->type = FS_PROP_NONE;
+ }
+ }
+ } else {
+ prop->scale = (EnFishing_RandZeroOne() * 0.1f) + 0.3f;
+ prop->rotY = Rand_ZeroFloat(2 * M_PI);
+ prop->drawDistance = 1000.0f;
+ EnFishing_SetColliderElement(i, &sFishingMain->collider, &prop->pos, prop->scale);
+ }
+
+ prop++;
+ }
+}
+
+static FishingFishInit sFishInits[] = {
+ { 0, { 666, -45, 354 }, 38, 0.1f }, { 0, { 681, -45, 240 }, 36, 0.1f }, { 0, { 670, -45, 90 }, 41, 0.05f },
+ { 0, { 615, -45, -450 }, 35, 0.2f }, { 0, { 500, -45, -420 }, 39, 0.1f }, { 0, { 420, -45, -550 }, 44, 0.05f },
+ { 0, { -264, -45, -640 }, 40, 0.1f }, { 0, { -470, -45, -540 }, 34, 0.2f }, { 0, { -557, -45, -430 }, 54, 0.01f },
+ { 0, { -260, -60, -330 }, 47, 0.05f }, { 0, { -500, -60, 330 }, 42, 0.06f }, { 0, { 428, -40, -283 }, 33, 0.2f },
+ { 0, { 409, -70, -230 }, 57, 0.0f }, { 0, { 450, -67, -300 }, 63, 0.0f }, { 0, { -136, -65, -196 }, 71, 0.0f },
+ { 1, { -561, -35, -547 }, 45, 0.0f }, { 1, { 667, -35, 317 }, 43, 0.0f },
+};
+
+static InitChainEntry sInitChain[] = {
ICHAIN_U8(targetMode, 5, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 0, ICHAIN_STOP),
};
+void EnFishing_Init(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnFishing* this = THIS;
+ u16 fishCount;
+
+ Actor_ProcessInitChain(thisx, sInitChain);
+ ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f);
+
+ sLinkAge = gSaveContext.save.linkAge;
+
+ if (thisx->params < 100) {
+ s16 i;
+ FishingGroupFish* fish;
+
+ D_809171C8 = 0;
+ sFishingMain = this;
+ Collider_InitJntSph(globalCtx, &sFishingMain->collider);
+ Collider_SetJntSph(globalCtx, &sFishingMain->collider, thisx, &sJntSphInit, sFishingMain->colliderElements);
+
+ thisx->params = 1;
+
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingOwnerSkel, &gFishingOwnerAnim, NULL, NULL, 0);
+ Animation_MorphToLoop(&this->skelAnime, &gFishingOwnerAnim, 0.0f);
+
+ thisx->update = EnFishing_UpdateOwner;
+ thisx->draw = EnFishing_DrawOwner;
+
+ thisx->shape.rot.y = -0x6000;
+ thisx->world.pos.x = 160.0f;
+ thisx->world.pos.y = -2.0f;
+ thisx->world.pos.z = 1208.0f;
+
+ Actor_SetScale(thisx, 0.011f);
+
+ thisx->focus.pos = thisx->world.pos;
+ thisx->focus.pos.y += 75.0f;
+ thisx->flags |= 9;
+
+ if (sLinkAge != 1) {
+ // HIGH_SCORE(HS_FISHING) from OoT
+ if (gSaveContext.save.roomInf[127][2] & 0x1000) {
+ D_8090CD08 = 0;
+ } else {
+ D_8090CD08 = 1;
+ }
+ } else {
+ D_8090CD08 = 2;
+ }
+
+ D_8090CD04 = 20;
+ globalCtx->specialEffects = sFishingEffects;
+ REG(15) = 1; // gTimeIncrement in OoT
+ D_809171FC = 0;
+ D_809171F6 = 10;
+
+ Audio_QueueSeqCmd(0x100100FF);
+
+ if (sLinkAge == 1) {
+ if (gSaveContext.save.roomInf[127][2] & 0x7F) {
+ D_809171CC = gSaveContext.save.roomInf[127][2] & 0x7F;
+ } else {
+ D_809171CC = 40.0f;
+ }
+ } else if (gSaveContext.save.roomInf[127][2] & 0x7F000000) {
+ D_809171CC = (gSaveContext.save.roomInf[127][2] & 0x7F000000) >> 0x18;
+ } else {
+ D_809171CC = 45.0f;
+ }
+
+ D_809171D1 = (gSaveContext.save.roomInf[127][2] & 0xFF0000) >> 0x10;
+ if ((D_809171D1 & 7) == 7) {
+ globalCtx->roomCtx.unk7A[0] = 90;
+ D_809171CA = 1;
+ } else {
+ globalCtx->roomCtx.unk7A[0] = 40;
+ D_809171CA = 0;
+ }
+
+ if ((D_809171D1 & 7) == 6) {
+ D_809171CB = 100;
+ } else {
+ D_809171CB = 0;
+ }
+
+ for (i = 0; i < EFFECT_COUNT; i++) {
+ sFishingEffects[i].type = FS_EFF_NONE;
+ }
+
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ sPondProps[i].type = FS_PROP_NONE;
+ }
+
+ sFishGroupAngle1 = 0.7f;
+ sFishGroupAngle2 = 2.3f;
+ sFishGroupAngle3 = 4.6f;
+
+ for (i = 0; i < GROUP_FISH_COUNT; i++) {
+ fish = &sGroupFishes[i];
+
+ fish->type = FS_GROUP_FISH_NORMAL;
+
+ if (i <= 20) {
+ fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle1) * 720.0f;
+ fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle1) * 720.0f;
+ } else if (i <= 40) {
+ fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle2) * 720.0f;
+ fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle2) * 720.0f;
+ } else {
+ fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle3) * 720.0f;
+ fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle3) * 720.0f;
+ }
+
+ fish->unk_10.y = fish->pos.y = -35.0f;
+
+ fish->timer = Rand_ZeroFloat(100.0f);
+
+ fish->unk_3C = 0;
+ fish->unk_3E = 0;
+ fish->unk_40 = 0;
+
+ if (sLinkAge != 1) {
+ if (((i >= 15) && (i < 20)) || ((i >= 35) && (i < 40)) || ((i >= 55) && (i < 60))) {
+ fish->type = FS_GROUP_FISH_NONE;
+ }
+ }
+ }
+
+ EnFishing_InitPondProps(this, globalCtx);
+ Actor_SpawnAsChild(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_EN_KANBAN, 53.0f, -17.0f, 982.0f, 0, 0, 0,
+ ENKANBAN_FISHING);
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_FISHING, 0.0f, 0.0f, 0.0f, 0, 0, 0, 200);
+
+ if ((D_809171D1 & 3) == 3) {
+ if (sLinkAge != 1) {
+ fishCount = 16;
+ } else {
+ fishCount = 17;
+ }
+ } else {
+ fishCount = 15;
+ }
+
+ for (i = 0; i < fishCount; i++) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_FISHING, sFishInits[i].pos.x, sFishInits[i].pos.y,
+ sFishInits[i].pos.z, 0, Rand_ZeroFloat(0x10000), 0, 100 + i);
+ }
+
+ return;
+ }
+
+ thisx->bgCheckFlags |= 0x800; // Added in MM
+
+ if ((thisx->params < 115) || (thisx->params == 200)) {
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, NULL, NULL, 0);
+ Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f);
+ } else {
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingLoachSkel, &gFishingLoachAnim, NULL, NULL, 0);
+ Animation_MorphToLoop(&this->skelAnime, &gFishingLoachAnim, 0.0f);
+ }
+
+ SkelAnime_Update(&this->skelAnime);
+
+ if (thisx->params == 200) {
+ this->unk_150 = 100;
+ func_800BC154(globalCtx, &globalCtx->actorCtx, thisx, ACTORCAT_PROP);
+ thisx->targetMode = 0;
+ thisx->flags |= 9;
+ this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
+ } else {
+ this->unk_150 = 10;
+ this->unk_152 = 10;
+
+ this->unk_148 = sFishInits[thisx->params - 100].unk_00;
+ this->unk_1A0 = sFishInits[thisx->params - 100].unk_0C;
+ this->unk_1A4 = sFishInits[thisx->params - 100].unk_08;
+
+ this->unk_1A4 += Rand_ZeroFloat(4.99999f);
+
+ if ((this->unk_1A4 >= 65.0f) && (Rand_ZeroOne() < 0.05f)) {
+ this->unk_1A4 += Rand_ZeroFloat(7.99999f);
+ }
+
+ if (sLinkAge == 1) {
+ this->unk_1A4 *= 0.73f;
+ }
+ }
+}
+
+void EnFishing_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnFishing* this = THIS;
+
+ SkelAnime_Free(&this->skelAnime, globalCtx);
+
+ if (thisx->params == 200) {
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
+ } else if (thisx->params == 1) {
+ Collider_DestroyJntSph(globalCtx, &this->collider);
+ }
+}
+
+void EnFishing_UpdateEffects(FishingEffect* effect, GlobalContext* globalCtx) {
+ f32 rippleY;
+ s16 i;
+
+ for (i = 0; i < EFFECT_COUNT; i++) {
+ if (effect->type) {
+ effect->timer++;
+ effect->pos.x += effect->vel.x;
+ effect->pos.y += effect->vel.y;
+ effect->pos.z += effect->vel.z;
+ effect->vel.y += effect->accel.y;
+
+ if (effect->type == FS_EFF_RIPPLE) {
+ Math_ApproachF(&effect->unk_30, effect->unk_34, 0.2f, effect->unk_38);
+
+ if (effect->unk_2C == 0) {
+ effect->alpha += 20;
+
+ if (effect->alpha >= effect->unk_2E) {
+ effect->alpha = effect->unk_2E;
+ effect->unk_2C++;
+ }
+ } else {
+ effect->alpha -= 8;
+
+ if (effect->alpha <= 0) {
+ effect->type = FS_EFF_NONE;
+ }
+ }
+ } else if (effect->type == FS_EFF_WATER_DUST) {
+ Math_ApproachF(&effect->unk_30, effect->unk_34, 0.1f, 0.1f);
+ effect->alpha -= 10;
+
+ if (effect->pos.y > (WATER_SURFACE_Y(globalCtx) - 5.0f)) {
+ effect->accel.y = 0.0f;
+ effect->vel.y = 0.0f;
+ effect->alpha -= 5;
+ }
+
+ if (effect->alpha <= 0) {
+ effect->type = FS_EFF_NONE;
+ }
+ } else if (effect->type == FS_EFF_BUBBLE) {
+ if (effect->unk_2C == 0) {
+ rippleY = WATER_SURFACE_Y(globalCtx);
+ } else {
+ rippleY = 69.0f;
+ }
+
+ if (effect->pos.y >= rippleY) {
+ effect->type = FS_EFF_NONE;
+
+ if (Rand_ZeroOne() < 0.3f) {
+ Vec3f pos = effect->pos;
+ pos.y = rippleY;
+ EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 20.0f, 60.0f, 150, 90);
+ }
+ }
+ } else if (effect->type == FS_EFF_DUST_SPLASH) {
+ if (effect->vel.y < -20.0f) {
+ effect->vel.y = -20.0f;
+ effect->accel.y = 0.0f;
+ }
+
+ if (effect->pos.y <= WATER_SURFACE_Y(globalCtx)) {
+ effect->type = FS_EFF_NONE;
+ if (Rand_ZeroOne() < 0.5f) {
+ Vec3f pos = effect->pos;
+ pos.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 40.0f, 110.0f, 150, 90);
+ }
+ }
+ } else if (effect->type == FS_EFF_RAIN_DROP) {
+ if (effect->pos.y < WATER_SURFACE_Y(globalCtx)) {
+ f32 sqDistXZ = SQ(effect->pos.x) + SQ(effect->pos.z);
+
+ if (sqDistXZ > SQ(920.0f)) {
+ effect->pos.y = WATER_SURFACE_Y(globalCtx) + ((sqrtf(sqDistXZ) - 920.0f) * 0.11f);
+ effect->timer = 2;
+ effect->type = FS_EFF_RAIN_SPLASH;
+ effect->unk_30 = (KREG(18) + 30) * 0.001f;
+ } else {
+ effect->pos.y = WATER_SURFACE_Y(globalCtx) + 3.0f;
+ effect->timer = 0;
+ if (Rand_ZeroOne() < 0.75f) {
+ effect->type = FS_EFF_RAIN_RIPPLE;
+ effect->vel = sZeroVec;
+ effect->unk_30 = 30 * 0.001f;
+ } else {
+ effect->type = FS_EFF_NONE;
+ }
+ }
+
+ effect->vel = sZeroVec;
+ }
+ } else if (effect->type >= FS_EFF_RAIN_RIPPLE) {
+ effect->unk_30 += (KREG(18) + 30) * 0.001f;
+
+ if (effect->timer >= 6) {
+ effect->type = FS_EFF_NONE;
+ }
+ } else if (effect->type == FS_EFF_OWNER_HAT) {
+ f32 sqDistXZ;
+ f32 bottomY;
+
+ effect->unk_30 = 0.010000001f;
+
+ Math_ApproachS(&sEffOwnerHatRot.y, 0, 20, 100);
+ Math_ApproachS(&sEffOwnerHatRot.x, 0, 20, 100);
+ Math_ApproachS(&sEffOwnerHatRot.z, -0x4000, 20, 100);
+
+ sqDistXZ = SQ(effect->pos.x) + SQ(effect->pos.z);
+ bottomY = WATER_SURFACE_Y(globalCtx) + ((sqrtf(sqDistXZ) - 920.0f) * 0.147f);
+
+ if (effect->pos.y > (bottomY - 10.0f)) {
+ effect->pos.y -= 0.1f;
+ }
+
+ if ((effect->timer % 16) == 0) {
+ Vec3f pos = effect->pos;
+ pos.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 30.0f, 300.0f, 150, 90);
+ }
+
+ if (effect->unk_2C >= 0) {
+ effect->unk_2C++;
+ }
+
+ if (effect->unk_2C == 30) {
+ func_801518B0(globalCtx, 0x40B3, NULL);
+ }
+
+ if ((effect->unk_2C >= 100) && (func_80152498(&globalCtx->msgCtx) == 5)) {
+ if (func_80147624(globalCtx) || !func_80152498(&globalCtx->msgCtx)) {
+ func_801477B4(globalCtx);
+ Rupees_ChangeBy(-50);
+ effect->unk_2C = -1;
+ }
+ }
+ }
+ }
+
+ effect++;
+ }
+}
+
+void EnFishing_DrawEffects(FishingEffect* effect, GlobalContext* globalCtx) {
+ u8 flag = 0;
+ f32 rotY;
+ s16 i;
+ s32 pad;
+ FishingEffect* firstEffect = effect;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_StatePush();
+
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ for (i = 0; i < 100; i++) {
+ if (effect->type == FS_EFF_RIPPLE) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRippleSetupDL);
+ gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0);
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, effect->alpha);
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_Scale(effect->unk_30, 1.0f, effect->unk_30, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRippleVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect;
+ flag = 0;
+ for (i = 0; i < 100; i++) {
+ if (effect->type == FS_EFF_DUST_SPLASH) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingDustSplashSetupDL);
+ gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 200, 0);
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 180, 180, 180, effect->alpha);
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingDustSplashVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect;
+ flag = 0;
+ for (i = 0; i < 100; i++) {
+ if (effect->type == FS_EFF_WATER_DUST) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingWaterDustSetupDL);
+ gDPSetEnvColor(POLY_OPA_DISP++, 40, 90, 80, 128);
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 40, 90, 80, effect->alpha);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, effect->timer + (i * 3),
+ (effect->timer + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32));
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingWaterDustVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect;
+ flag = 0;
+ for (i = 0; i < 100; i++) {
+ if (effect->type == FS_EFF_BUBBLE) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingBubbleSetupDL);
+ gDPSetEnvColor(POLY_XLU_DISP++, 150, 150, 150, 0);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255);
+ flag++;
+ }
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingBubbleVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect + 30;
+ flag = 0;
+ for (i = 30; i < EFFECT_COUNT; i++) {
+ if (effect->type == FS_EFF_RAIN_DROP) {
+ if (flag == 0) {
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14);
+ gDPSetCombineMode(POLY_XLU_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 30);
+ flag++;
+ }
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(effect->unk_38, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(effect->unk_34);
+ Matrix_InsertZRotation_f(effect->unk_3C, MTXMODE_APPLY);
+ Matrix_Scale(0.002f, 1.0f, 0.1f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRainDropVtxDL);
+ }
+ effect++;
+ }
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ effect = firstEffect + 30;
+ flag = 0;
+ for (i = 30; i < EFFECT_COUNT; i++) {
+ if (effect->type == FS_EFF_RAIN_RIPPLE) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRippleSetupDL);
+ gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 130);
+ flag++;
+ }
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_Scale(effect->unk_30, 1.0f, effect->unk_30, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRippleVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect + 30;
+ flag = 0;
+ for (i = 30; i < EFFECT_COUNT; i++) {
+ if (effect->type == FS_EFF_RAIN_SPLASH) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRainSplashSetupDL);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, KREG(19) + 80);
+ flag++;
+ }
+
+ if (Rand_ZeroOne() < 0.5f) {
+ rotY = 0.0f;
+ } else {
+ rotY = M_PI;
+ }
+
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_InsertYRotation_f(rotY, MTXMODE_APPLY);
+ Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingRainSplashVtxDL);
+ }
+ effect++;
+ }
+
+ effect = firstEffect;
+ if (effect->type == FS_EFF_OWNER_HAT) {
+ Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f((sEffOwnerHatRot.y * M_PI) / 32768, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis((sEffOwnerHatRot.x * M_PI) / 32768);
+ Matrix_InsertZRotation_f((sEffOwnerHatRot.z * M_PI) / 32768, MTXMODE_APPLY);
+ Matrix_Scale(effect->unk_30, effect->unk_30, effect->unk_30, MTXMODE_APPLY);
+ Matrix_InsertTranslation(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(M_PI / 2);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL);
+ }
+
+ Matrix_StatePop();
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnFishing_DrawStreamSplash(GlobalContext* globalCtx) {
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x09,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames * 1,
+ globalCtx->gameplayFrames * 8, 32, 64, 1, -globalCtx->gameplayFrames * 2, 0, 16, 16));
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 50);
+
+ Matrix_InsertTranslation(670.0f, -24.0f, -600.0f, MTXMODE_NEW);
+ Matrix_Scale(0.02f, 1.0f, 0.02f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingStreamSplashDL);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+s32 func_808FEF70(Vec3f* vec) {
+ if (((vec->x >= 110.0f) && (vec->x <= 150.0f) && (vec->z <= 1400.0f) && (vec->z >= 1160.0f)) ||
+ ((vec->x >= 110.0f) && (vec->x <= 210.0f) && (vec->z <= 1200.0f) && (vec->z >= 1160.0f))) {
+ if (vec->y <= 42.0f) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void EnFishing_UpdateLine(GlobalContext* globalCtx, Vec3f* basePos, Vec3f* pos, Vec3f* rot, Vec3f* unk) {
+ s32 i;
+ s32 k;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ f32 spD8;
+ s32 temp_s2;
+ s32 pad;
+ f32 temp_f20;
+ Vec3f posSrc = { 0.0f, 0.0f, 0.0f };
+ Vec3f posStep;
+ f32 phi_f12;
+ Vec3f spA4;
+ Vec3f sp98;
+ f32 sp94;
+ f32 sp90;
+ f32 sp8C;
+ f32 sqDistXZ;
+ f32 temp_f18;
+
+ if (D_8090CD24 != 0) {
+ spA4 = *basePos;
+ sp98 = pos[LINE_SEG_COUNT - 1];
+
+ sp94 = sp98.x - spA4.x;
+ sp90 = sp98.y - spA4.y;
+ sp8C = sp98.z - spA4.z;
+
+ temp_f20 = sqrtf(SQ(sp94) + SQ(sp90) + SQ(sp8C)) * 0.97f;
+ if (temp_f20 > 1000.0f) {
+ temp_f20 = 1000.0f;
+ }
+
+ D_809101C0 = 200.0f - (temp_f20 * 200.0f * 0.001f);
+ }
+
+ temp_s2 = D_809101C0;
+ posSrc.z = 5.0f;
+
+ for (i = 0; i < LINE_SEG_COUNT; i++) {
+ if (i <= temp_s2) {
+ pos[i] = *basePos;
+ } else if (D_8090CD24 != 0) {
+ temp_f20 = (f32)(i - temp_s2) / (f32)(LINE_SEG_COUNT - temp_s2 + 1);
+ Math_ApproachF(&pos[i].x, (sp94 * temp_f20) + spA4.x, 1.0f, 20.0f);
+ Math_ApproachF(&pos[i].y, (sp90 * temp_f20) + spA4.y, 1.0f, 20.0f);
+ Math_ApproachF(&pos[i].z, (sp8C * temp_f20) + spA4.z, 1.0f, 20.0f);
+ }
+ }
+
+ for (i = temp_s2 + 1, k = 0; i < LINE_SEG_COUNT; i++, k++) {
+ temp_f18 = 2.0f * D_809101C4;
+
+ dx = (pos + i)->x - (pos + i - 1)->x;
+ spD8 = (pos + i)->y;
+
+ sqDistXZ = SQ((pos + i)->x) + SQ((pos + i)->z);
+
+ if (sqDistXZ > SQ(920.0f)) {
+ phi_f12 = ((sqrtf(sqDistXZ) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx);
+ } else {
+ phi_f12 = WATER_SURFACE_Y(globalCtx);
+ }
+
+ if (D_80917206 == 2) {
+ f32 phi_f2;
+
+ if (spD8 < phi_f12) {
+ phi_f12 = ((sqrtf(sqDistXZ) - 920.0f) * 0.147f) + WATER_SURFACE_Y(globalCtx);
+ if (spD8 > phi_f12) {
+ u8 temp;
+
+ phi_f2 = (spD8 - phi_f12) * 0.05f;
+
+ if (phi_f2 > 0.29999998f) {
+ phi_f2 = 0.29999998f;
+ }
+ if (i >= 100) {
+ phi_f2 *= (i - 100) * 0.02f;
+ spD8 -= phi_f2;
+ }
+ }
+ } else {
+ spD8 -= temp_f18;
+ }
+ } else if (i > LINE_SEG_COUNT - 10) {
+ if (spD8 > phi_f12) {
+ f32 phi_f2 = (spD8 - phi_f12) * 0.2f;
+
+ phi_f2 = CLAMP_MAX(phi_f2, temp_f18);
+ spD8 -= phi_f2;
+ }
+ } else {
+ if (spD8 > phi_f12) {
+ spD8 -= temp_f18;
+ }
+ }
+
+ if (func_808FEF70(&pos[i])) {
+ spD8 = 42.0f;
+ }
+
+ dy = spD8 - (pos + i - 1)->y;
+ dz = (pos + i)->z - (pos + i - 1)->z;
+
+ ry = Math_Acot2F(dz, dx);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -Math_Acot2F(dist, dy);
+
+ (rot + i - 1)->y = ry;
+ (rot + i - 1)->x = rx;
+
+ Matrix_InsertYRotation_f(ry, MTXMODE_NEW);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_MultiplyVector3fByState(&posSrc, &posStep);
+
+ (pos + i)->x = (pos + i - 1)->x + posStep.x;
+ (pos + i)->y = (pos + i - 1)->y + posStep.y;
+ (pos + i)->z = (pos + i - 1)->z + posStep.z;
+ }
+}
+
+void EnFishing_UpdateLinePos(Vec3f* pos) {
+ s32 i;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ Vec3f posSrc = { 0.0f, 0.0f, 0.0f };
+ Vec3f posStep;
+ s32 min = D_809101C0;
+
+ posSrc.z = 5.0f;
+
+ for (i = LINE_SEG_COUNT - 2; i > min; i--) {
+ dx = (pos + i)->x - (pos + i + 1)->x;
+ dy = (pos + i)->y - (pos + i + 1)->y;
+ dz = (pos + i)->z - (pos + i + 1)->z;
+
+ ry = Math_Acot2F(dz, dx);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -Math_Acot2F(dist, dy);
+
+ Matrix_InsertYRotation_f(ry, MTXMODE_NEW);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_MultiplyVector3fByState(&posSrc, &posStep);
+
+ (pos + i)->x = (pos + i + 1)->x + posStep.x;
+ (pos + i)->y = (pos + i + 1)->y + posStep.y;
+ (pos + i)->z = (pos + i + 1)->z + posStep.z;
+ }
+}
+
+void EnFishing_DrawLureHook(GlobalContext* globalCtx, Vec3f* pos, Vec3f* refPos, u8 hookIndex) {
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ f32 offsetY;
+ Vec3f posSrc = { 0.0f, 0.0f, 1.0f };
+ Vec3f posStep;
+ Player* player = GET_PLAYER(globalCtx);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_StatePush();
+
+ if ((D_8090CD14 == 3) && ((pos->y > WATER_SURFACE_Y(globalCtx)) || ((D_8090CD0C != 0) && hookIndex))) {
+ offsetY = 0.0f;
+ } else if (pos->y < WATER_SURFACE_Y(globalCtx)) {
+ offsetY = -1.0f;
+ } else {
+ offsetY = -3.0f;
+ }
+
+ dx = refPos->x - pos->x;
+ dy = refPos->y - pos->y + offsetY;
+ dz = refPos->z - pos->z;
+
+ ry = Math_Acot2F(dz, dx);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -Math_Acot2F(dist, dy);
+
+ Matrix_InsertYRotation_f(ry, MTXMODE_NEW);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_MultiplyVector3fByState(&posSrc, &posStep);
+
+ refPos->x = pos->x + posStep.x;
+ refPos->y = pos->y + posStep.y;
+ refPos->z = pos->z + posStep.z;
+
+ Matrix_InsertTranslation(pos->x, pos->y, pos->z, MTXMODE_NEW);
+
+ if ((player->actor.speedXZ == 0.0f) && (D_809101B4 == 0.0f)) {
+ Math_ApproachF(&sLureHookRotY[hookIndex], ry, 0.1f, 0.3f);
+ } else {
+ sLureHookRotY[hookIndex] = ry;
+ }
+
+ Matrix_InsertYRotation_f(sLureHookRotY[hookIndex], MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_Scale(0.0039999997f, 0.0039999997f, 0.005f, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(M_PI, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingLureHookDL);
+
+ Matrix_InsertZRotation_f(M_PI / 2, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingLureHookDL);
+
+ if ((hookIndex == 1) && (D_8090CD0C != 0)) {
+ Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY);
+ Matrix_InsertTranslation(250.0f, 0.0f, -1400.0f, MTXMODE_APPLY);
+ Matrix_StatePush();
+
+ if (D_8090CD10 != 0) {
+ FishingEffect* effect = globalCtx->specialEffects;
+ MtxF mf;
+
+ Matrix_MultiplyVector3fByState(&sZeroVec, &effect->pos);
+ Matrix_CopyCurrentState(&mf);
+ func_8018219C(&mf, &sEffOwnerHatRot, 0);
+
+ D_8090CD10 = 0;
+ D_8090CD0C = 0;
+
+ effect->type = FS_EFF_OWNER_HAT;
+ effect->unk_2C = 0;
+ effect->vel = sZeroVec;
+ effect->accel = sZeroVec;
+ }
+
+ Matrix_StatePop();
+ Matrix_InsertTranslation(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(M_PI / 2);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL);
+ }
+
+ Matrix_StatePop();
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnFishing_UpdateSinkingLure(GlobalContext* globalCtx) {
+ s32 i;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ f32 offsetY;
+ Vec3f posSrc = { 0.0f, 0.0f, 0.0f };
+ Vec3f posStep;
+ Vec3f sp94;
+ Vec3f sp88;
+ f32 offsetX;
+ f32 offsetZ;
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f* pos;
+ s32 pad;
+
+ posSrc.z = 0.85f;
+
+ sSinkingLurePos[0] = sLurePos;
+
+ if (D_8090CD54 != 0) {
+ offsetY = -1.0f;
+ } else if (sLurePos.y < WATER_SURFACE_Y(globalCtx)) {
+ offsetY = 0.5f;
+ } else {
+ offsetY = -5.0f;
+ }
+
+ if (D_8090CD14 == 5) {
+ Matrix_InsertYRotation_f(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW);
+ sp94.x = 5.0f;
+ sp94.y = 0.0f;
+ sp94.z = 3.0f;
+ Matrix_MultiplyVector3fByState(&sp94, &sp88);
+ }
+
+ for (i = 1; i < SINKING_LURE_SEG_COUNT; i++) {
+ pos = sSinkingLurePos;
+
+ if ((i < 10) && (D_8090CD14 == 5)) {
+ offsetX = (10 - i) * sp88.x * 0.1f;
+ offsetZ = (10 - i) * sp88.z * 0.1f;
+ } else {
+ offsetX = offsetZ = 0.0f;
+ }
+
+ dx = (pos + i)->x - (pos + i - 1)->x + offsetX;
+ dy = (pos + i)->y - (pos + i - 1)->y + offsetY;
+ dz = (pos + i)->z - (pos + i - 1)->z + offsetZ;
+
+ ry = Math_Acot2F(dz, dx);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -Math_Acot2F(dist, dy);
+
+ Matrix_InsertYRotation_f(ry, MTXMODE_NEW);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_MultiplyVector3fByState(&posSrc, &posStep);
+
+ (pos + i)->x = (pos + i - 1)->x + posStep.x;
+ (pos + i)->y = (pos + i - 1)->y + posStep.y;
+ (pos + i)->z = (pos + i - 1)->z + posStep.z;
+ }
+}
+
+static f32 sSinkingLureSizes[] = {
+ 1.0f, 1.5f, 1.8f, 2.0f, 1.8f, 1.6f, 1.4f, 1.2f, 1.0f, 1.0f,
+ 0.9f, 0.85f, 0.8f, 0.7f, 0.8f, 1.0f, 1.2f, 1.1f, 1.0f, 0.8f,
+};
+
+void EnFishing_DrawSinkingLure(GlobalContext* globalCtx) {
+ s16 i;
+ f32 scale;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ EnFishing_UpdateSinkingLure(globalCtx);
+
+ if (sLurePos.y < WATER_SURFACE_Y(globalCtx)) {
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingSinkingLureSegmentSetupDL);
+
+ for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) {
+ if ((i + D_80911F20) < SINKING_LURE_SEG_COUNT) {
+ Matrix_InsertTranslation(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW);
+ scale = sSinkingLureSizes[i + D_80911F20] * 0.04f;
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingSinkingLureSegmentVtxDL);
+ }
+ }
+ } else {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPDisplayList(POLY_XLU_DISP++, gFishingSinkingLureSegmentSetupDL);
+
+ for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) {
+ if ((i + D_80911F20) < SINKING_LURE_SEG_COUNT) {
+ Matrix_InsertTranslation(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW);
+ scale = sSinkingLureSizes[i + D_80911F20] * 0.04f;
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingSinkingLureSegmentVtxDL);
+ }
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnFishing_DrawLureAndLine(GlobalContext* globalCtx, Vec3f* linePos, Vec3f* lineRot) {
+ Vec3f posSrc;
+ Vec3f posStep;
+ Vec3f hookPos[2];
+ s32 i;
+ s32 spB4 = D_809101C0;
+ s32 pad;
+ Player* player = GET_PLAYER(globalCtx);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ Matrix_StatePush();
+
+ if (D_8090CD54 != 0) {
+ Vec3f posTemp = sLurePos;
+
+ sLurePos = sSinkingLureBasePos;
+ EnFishing_DrawSinkingLure(globalCtx);
+ sLurePos = posTemp;
+ }
+
+ if ((D_8090CD14 == 4) || (D_8090CD14 == 5)) {
+ sLurePos = sFishingHookedFish->fishMouthPos;
+
+ if ((D_8090CD14 == 5) && (D_80917206 == 2)) {
+ Matrix_InsertYRotation_f(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW);
+ posSrc.x = 2.0f;
+ posSrc.y = 0.0f;
+ posSrc.z = 0.0f;
+ Matrix_MultiplyVector3fByState(&posSrc, &posStep);
+ sLurePos.x += posStep.x;
+ sLurePos.z += posStep.z;
+ }
+ } else if (D_8090CD14 == 0) {
+ sLurePos = sReelLinePos[LINE_SEG_COUNT - 1];
+ sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI;
+
+ if ((player->actor.speedXZ == 0.0f) && (D_80917200 == 0)) {
+ Math_ApproachF(&sLureRot.y, sReelLineRot[LINE_SEG_COUNT - 2].y, 0.1f, 0.2f);
+ } else {
+ sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y;
+ }
+ }
+
+ if (D_80917206 != 2) {
+ Matrix_InsertTranslation(sLurePos.x, sLurePos.y, sLurePos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(sLureRot.y + D_80917254, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(sLureRot.x);
+ Matrix_Scale(0.0039999997f, 0.0039999997f, 0.0039999997f, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, D_80917258, MTXMODE_APPLY);
+ Matrix_InsertZRotation_f(M_PI / 2, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(M_PI / 2, MTXMODE_APPLY);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingLureFloatDL);
+
+ posSrc.x = -850.0f;
+ posSrc.y = 0.0f;
+ posSrc.z = 0.0f;
+ Matrix_MultiplyVector3fByState(&posSrc, &D_80917218);
+
+ posSrc.x = 500.0f;
+ posSrc.z = -300.0f;
+ Matrix_MultiplyVector3fByState(&posSrc, &hookPos[0]);
+ EnFishing_DrawLureHook(globalCtx, &hookPos[0], &sLureHookRefPos[0], 0);
+
+ posSrc.x = 2100.0f;
+ posSrc.z = -50.0f;
+ Matrix_MultiplyVector3fByState(&posSrc, &hookPos[1]);
+ EnFishing_DrawLureHook(globalCtx, &hookPos[1], &sLureHookRefPos[1], 1);
+ }
+
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14);
+
+ gDPSetCombineMode(POLY_XLU_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 55);
+
+ if ((D_8090CD14 == 4) && ((D_80917274 != 0) || (D_80917206 != 2))) {
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+
+ dx = sLurePos.x - sRodTipPos.x;
+ dy = sLurePos.y - sRodTipPos.y;
+ dz = sLurePos.z - sRodTipPos.z;
+
+ ry = func_80086B30(dx, dz);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -func_80086B30(dy, dist);
+
+ dist = sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) * 0.001f;
+
+ Matrix_InsertTranslation(sRodTipPos.x, sRodTipPos.y, sRodTipPos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(ry, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_Scale(D_809101C8, 1.0f, dist, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL);
+ } else {
+ for (i = spB4; i < LINE_SEG_COUNT - 1; i++) {
+ if ((i == LINE_SEG_COUNT - 3) && (D_80917206 == 0) && (D_8090CD14 == 3)) {
+ f32 rx;
+ f32 ry;
+ f32 dist;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+
+ dx = D_80917218.x - (linePos + i)->x;
+ dy = D_80917218.y - (linePos + i)->y;
+ dz = D_80917218.z - (linePos + i)->z;
+
+ ry = func_80086B30(dx, dz);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ rx = -func_80086B30(dy, dist);
+
+ dist = sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) * 0.001f;
+
+ Matrix_InsertTranslation((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(ry, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(rx);
+ Matrix_Scale(D_809101C8, 1.0f, dist, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL);
+ break;
+ }
+
+ Matrix_InsertTranslation((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f((lineRot + i)->y, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis((lineRot + i)->x);
+ Matrix_Scale(D_809101C8, 1.0f, 0.005f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL);
+ }
+ }
+
+ Matrix_StatePop();
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+static f32 sRodScales[22] = {
+ 1.0f, 1.0f, 1.0f, 0.9625f, 0.925f, 0.8875f, 0.85f, 0.8125f,
+ 0.775f, 0.73749995f, 0.7f, 0.6625f, 0.625f, 0.5875f, 0.54999995f, 0.5125f,
+ 0.47499996f, 0.4375f, 0.39999998f, 0.36249995f, 0.325f, 0.28749996f,
+};
+
+static f32 sRodBendRatios[22] = {
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.06f, 0.12f, 0.18f, 0.24f, 0.30f, 0.36f,
+ 0.42f, 0.48f, 0.54f, 0.60f, 0.60f, 0.5142f, 0.4285f, 0.3428f, 0.2571f, 0.1714f, 0.0857f,
+};
+
+static Vec3f sRodTipOffset = { 0.0f, 0.0f, 0.0f };
+
+void EnFishing_DrawRod(GlobalContext* globalCtx) {
+ s16 i;
+ f32 spC8;
+ f32 spC4;
+ f32 spC0;
+ Input* input = CONTROLLER1(globalCtx);
+ Player* player = GET_PLAYER(globalCtx);
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if (D_80911E28 != 0) {
+ D_80911E28--;
+
+ Math_ApproachF(&D_8090CD40, 35.0f, 1.0f, 100.0f);
+ Math_ApproachF(&D_8090CD3C, -0.8f, 1.0f, 0.4f);
+ Math_ApproachS(&player->actor.shape.rot.x, -4000, 2, 15000);
+ } else {
+ s16 target = 0;
+
+ if ((D_8090CD14 == 4) && (D_80917274 != 0)) {
+ target = Math_SinS(D_809171FE * 25600) * 1500.0f;
+ } else {
+ Math_ApproachZeroF(&D_8090CD40, 0.1f, 10.0f);
+ Math_ApproachZeroF(&D_8090CD3C, 1.0f, 0.05f);
+ }
+
+ Math_ApproachS(&player->actor.shape.rot.x, target, 5, 1000);
+ }
+
+ if ((D_8090CD14 == 3) || (D_8090CD14 == 4)) {
+ if ((input->rel.stick_x == 0) && (D_8090CD44 != 0)) {
+ D_8090CD30 = 0.0f;
+ }
+ if ((input->rel.stick_y == 0) && (D_8090CD48 != 0)) {
+ D_8090CD34 = 0.0f;
+ }
+
+ spC8 = player->unk_B08[1];
+ Math_SmoothStepToF(&player->unk_B08[1], input->rel.stick_y * 0.02f, 0.3f, 5.0f, 0.0f);
+ spC8 = player->unk_B08[1] - spC8;
+
+ spC4 = player->unk_B08[0];
+ Math_SmoothStepToF(&player->unk_B08[0], input->rel.stick_x * 0.02f, 0.3f, 5.0f, 0.0f);
+ spC4 = player->unk_B08[0] - spC4;
+
+ if (player->unk_B08[0] > 1.0f) {
+ player->unk_B08[0] = 1.0f;
+ }
+ if (player->unk_B08[1] > 1.0f) {
+ player->unk_B08[1] = 1.0f;
+ }
+ if (player->unk_B08[0] < -1.0f) {
+ player->unk_B08[0] = -1.0f;
+ }
+ if (player->unk_B08[1] < -1.0f) {
+ player->unk_B08[1] = -1.0f;
+ }
+
+ Math_ApproachF(&D_8090CD28, spC4 * 70.0f * -0.01f, 1.0f, D_8090CD30);
+ Math_ApproachF(&D_8090CD30, 1.0f, 1.0f, 0.1f);
+ Math_ApproachF(&D_8090CD2C, spC8 * 70.0f * 0.01f, 1.0f, D_8090CD34);
+ Math_ApproachF(&D_8090CD34, 1.0f, 1.0f, 0.1f);
+ Math_ApproachZeroF(&D_8090CD38, 1.0f, 0.05f);
+ } else {
+ Math_ApproachZeroF(&player->unk_B08[1], 1.0f, 0.1f);
+ Math_ApproachZeroF(&player->unk_B08[0], 1.0f, 0.1f);
+ Math_ApproachF(&D_8090CD2C, (Math_SinS(D_809171FE * 3000) * 0.025f) + -0.03f, 1.0f, 0.05f);
+ Math_ApproachZeroF(&D_8090CD28, 1.0f, 0.05f);
+
+ if ((D_80917204 >= 19) && (D_80917204 <= 24)) {
+ Math_ApproachF(&D_8090CD38, 0.8f, 1.0f, 0.2f);
+ } else {
+ Math_ApproachF(&D_8090CD38, 0.0f, 1.0f, 0.4f);
+ }
+ }
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingRodSetupDL);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 155, 0, 255);
+
+ Matrix_InsertMatrix(&player->mf_CC4, MTXMODE_NEW);
+
+ if (sLinkAge != 1) {
+ Matrix_InsertTranslation(0.0f, 400.0f, 0.0f, MTXMODE_APPLY);
+ } else {
+ Matrix_InsertTranslation(0.0f, 230.0f, 0.0f, MTXMODE_APPLY);
+ }
+
+ if (D_8090CD14 == 5) {
+ Matrix_InsertYRotation_f(1.7592919f, MTXMODE_APPLY);
+ } else {
+ Matrix_InsertYRotation_f(1.288053f, MTXMODE_APPLY);
+ }
+
+ Matrix_RotateStateAroundXAxis(-0.6283185f);
+ Matrix_InsertZRotation_f((player->unk_B08[0] * 0.5f) + 0.4712389f, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis((D_8090CD40 + 20.0f) * 0.01f * M_PI);
+ Matrix_Scale(0.70000005f, 0.70000005f, 0.70000005f, MTXMODE_APPLY);
+
+ spC0 = (D_8090CD3C * (((player->unk_B08[1] - 1.0f) * -0.25f) + 0.5f)) + (D_8090CD2C + D_8090CD38);
+
+ Matrix_InsertTranslation(0.0f, 0.0f, -1300.0f, MTXMODE_APPLY);
+
+ for (i = 0; i < 22; i++) {
+ Matrix_InsertYRotation_f(sRodBendRatios[i] * D_8090CD28 * 0.5f, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(sRodBendRatios[i] * spC0 * 0.5f);
+
+ Matrix_StatePush();
+ Matrix_Scale(sRodScales[i], sRodScales[i], 0.52f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ if (i < 5) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentBlackTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD);
+ } else if ((i < 8) || ((i % 2) == 0)) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentWhiteTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD);
+ } else {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentStripTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD);
+ }
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingRodSegmentDL);
+
+ Matrix_StatePop();
+ Matrix_InsertTranslation(0.0f, 0.0f, 500.0f, MTXMODE_APPLY);
+
+ if (i == 21) {
+ Matrix_MultiplyVector3fByState(&sRodTipOffset, &sRodTipPos);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+static Vec3f D_8090D614 = { 0.0f, 0.0f, 0.0f };
+
+#ifdef NON_MATCHING
+// Stack memes, the pad on line ~2410 makes stack too big, but needed for ordering
+void EnFishing_UpdateLure(EnFishing* this, GlobalContext* globalCtx) {
+ f32 spE4;
+ f32 spE0;
+ s16 phi_v0;
+ s16 spDC;
+ f32 spD8;
+ f32 spD4;
+ f32 spD0;
+ f32 phi_f16;
+ f32 spC8;
+ s16 i;
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ Vec3f spA8;
+ Vec3f sp9C;
+ Vec3f sp90;
+ Input* input = CONTROLLER1(globalCtx);
+ // Vec3f sp80;
+
+ f32 phi_f0;
+ // f32 sp70;
+ // Vec3f sp64;
+ // Vec3f sp58;
+ // s32 pad;
+
+ D_809171FE++;
+
+ if (D_80917200 != 0) {
+ D_80917200--;
+ }
+
+ if (D_80917202 != 0) {
+ D_80917202--;
+ }
+
+ if (D_80917204 != 0) {
+ D_80917204--;
+ }
+
+ if (D_80917272 != 0) {
+ D_80917272--;
+ }
+
+ if (D_809101CC != 0) {
+ D_809101CC--;
+ }
+
+ if (D_8090CD24 != 0) {
+ D_8090CD24--;
+ }
+
+ if (D_809171F4 != 0) {
+ D_809171F4--;
+ }
+
+ if (D_80917264 != 0) {
+ D_80917264--;
+ }
+
+ if (D_809171FC == 1) {
+ D_809171FC = 2;
+ D_809171D8 = 0;
+ D_809171D6 = 0;
+ D_80917206 = 0;
+
+ // Age and high score check removed in MM
+ sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f;
+
+ D_809101C4 = 520.0f;
+ D_809101C0 = 195.0f;
+
+ D_8090CD14 = 0;
+ D_80917206 = 0;
+ D_809171FE = 0;
+ D_80917200 = 0;
+ D_80917202 = 0;
+ D_80917204 = 0;
+ D_80917270 = 0;
+ D_80917264 = 0;
+ D_809101CC = 0;
+
+ D_80917254 = D_809101D0 = D_80917258 = 0.0f;
+
+ D_80917278 = zeroVec;
+
+ for (i = 0; i < LINE_SEG_COUNT; i++) {
+ sReelLinePos[i] = zeroVec;
+ sReelLineRot[i] = zeroVec;
+ sReelLineUnk[i] = zeroVec;
+ }
+ }
+
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sLurePos, &D_8090D614, &sProjectedW);
+
+ if (D_8090CD14 == 0) {
+ Math_ApproachF(&D_80917258, -800.0f, 1.0f, 20.0f);
+ } else {
+ Math_ApproachF(&D_80917258, 300.0f, 1.0f, 20.0f);
+ }
+
+ switch (D_8090CD14) {
+ case 0:
+ D_80911F20 = 0;
+
+ Math_ApproachF(&D_809101C0, 195.0f, 1.0f, 1.0f);
+
+ if (player->stateFlags1 & 0x8000000) {
+ D_80917204 = 0;
+ player->unk_B28 = 0;
+ }
+
+ if (D_80917204 == 0) {
+ if ((D_80917200 == 0) && (player->unk_B28 == 1)) {
+ D_80917204 = 37;
+ func_801477B4(globalCtx);
+ }
+ } else {
+ sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI;
+ sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y;
+
+ if (D_80917204 == 18) {
+ D_8090CD14 = 1;
+ sLurePos = sRodTipPos;
+ Matrix_InsertYRotation_f(BINANG_TO_RAD(player->actor.shape.rot.y), MTXMODE_NEW);
+ sp90.x = 0.0f;
+ sp90.y = 0.0f;
+ sp90.z = 25.0f;
+ Matrix_MultiplyVector3fByState(&sp90, &D_80917238);
+ D_80917238.y = 15.0f;
+ D_80917248.x = D_80917248.z = 0.0f;
+ D_80917248.y = -1.0f;
+ D_809101C4 = 0.0f;
+ D_80917202 = 5;
+ D_8091726C = 0.5f;
+ D_80917268 = Rand_ZeroFloat(1.9f);
+ sFishMouthOffset.y = 500.0f;
+ func_8019F1C0(&D_8090D614, NA_SE_IT_SWORD_SWING_HARD);
+ }
+ }
+ break;
+
+ case 1:
+ spE0 = sLurePos.y;
+
+ sLurePos.x += D_80917238.x;
+ sLurePos.y += D_80917238.y;
+ sLurePos.z += D_80917238.z;
+
+ D_80917238.x += D_80917248.x;
+ D_80917238.y += D_80917248.y;
+ D_80917238.z += D_80917248.z;
+
+ if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_8090CD0C != 0)) {
+ D_80917238.x *= 0.9f;
+ D_80917238.z *= 0.9f;
+ if (D_8090CD0C == 0) {
+ play_sound(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG);
+ }
+ }
+
+ spD8 = sLurePos.x - sRodTipPos.x;
+ spD4 = sLurePos.y - sRodTipPos.y;
+ spD0 = sLurePos.z - sRodTipPos.z;
+
+ if (D_80917202 != 0) {
+ sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI;
+ sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y;
+ } else {
+ sLureRot.x = 0.0f;
+ sLureRot.y = Math_Acot2F(spD0, spD8) + M_PI;
+ }
+
+ phi_f16 = sqrtf(SQ(spD8) + SQ(spD4) + SQ(spD0));
+ if (phi_f16 > 1000.0f) {
+ phi_f16 = 1000.0f;
+ }
+ D_809101C0 = 200.0f - (phi_f16 * 200.0f * 0.001f);
+
+ spC8 = SQ(sLurePos.x) + SQ(sLurePos.z);
+ if (spC8 > SQ(920.0f)) {
+ f32 temp;
+
+ if ((sLurePos.y > 160.0f) || (sLurePos.x < 80.0f) || (sLurePos.x > 180.0f) || (sLurePos.z > 1350.0f) ||
+ (sLurePos.z < 1100.0f) || (sLurePos.y < 45.0f)) {
+ Vec3f sp80 = this->actor.world.pos;
+
+ this->actor.prevPos = this->actor.world.pos = sLurePos;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 30.0f, 0x43);
+ this->actor.world.pos = sp80;
+
+ if (this->actor.bgCheckFlags & 0x10) {
+ D_80917238.y = -0.5f;
+ }
+ if (this->actor.bgCheckFlags & 8) {
+ if (D_80917238.y > 0.0f) {
+ D_80917238.y = 0.0f;
+ }
+ D_80917238.x = D_80917238.z = 0.0f;
+ }
+ } else {
+ if (func_808FEF70(&sLurePos)) {
+ D_8090CD14 = 3;
+ D_809101D0 = 0.0f;
+ }
+ }
+
+ temp = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx);
+ // spE4 = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx);
+ if (sLurePos.y <= temp) {
+ sLurePos.y = temp;
+ D_80917238.x = D_80917238.y = D_80917238.z = 0.0f;
+ D_8090CD14 = 3;
+ D_809101D0 = 0.0;
+ } else {
+ Math_ApproachF(&D_809101C4, 0.0f, 1.0f, 0.05f);
+ func_8019F1C0(&D_8090D614,
+ NA_SE_EN_WIZ_UNARI - SFX_FLAG); // changed from NA_SE_EN_FANTOM_FLOAT in OoT
+ }
+ } else {
+ f32 sp7C = WATER_SURFACE_Y(globalCtx);
+ f32 sp78;
+ // spE4 = WATER_SURFACE_Y(globalCtx);
+
+ if (sLurePos.y <= sp7C) {
+ D_8090CD14 = 2;
+ D_809101D0 = 0.0f;
+ D_80917238.x = D_80917238.z = 0.0f;
+
+ if (D_80917206 == 2) {
+ D_809171F2 = 0;
+ } else {
+ D_809171F2 = 10;
+ }
+
+ if ((sLurePos.y <= sp7C) && (sp7C < spE0) && (sp7C == WATER_SURFACE_Y(globalCtx))) {
+ D_80917264 = 10;
+ func_8019F1C0(&D_8090D614, NA_SE_EV_BOMB_DROP_WATER);
+ D_80917248.y = 0.0f;
+ D_80917238.y *= 0.2f;
+
+ for (i = 0; i < 50; i++) {
+ sp7C = Rand_ZeroFloat(1.5f) + 0.5f;
+ sp78 = Rand_ZeroFloat(6.28f);
+
+ sp9C.x = __sinf(sp78) * sp7C;
+ sp9C.z = __cosf(sp78) * sp7C;
+ sp9C.y = Rand_ZeroFloat(3.0f) + 3.0f;
+
+ spA8 = sLurePos;
+ spA8.x += (sp9C.x * 3.0f);
+ spA8.y = WATER_SURFACE_Y(globalCtx);
+ spA8.z += (sp9C.z * 3.0f);
+ EnFishing_SpawnDustSplash(NULL, globalCtx->specialEffects, &spA8, &sp9C,
+ Rand_ZeroFloat(0.02f) + 0.025f);
+ }
+
+ spA8 = sLurePos;
+ spA8.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &spA8, 100.0f, 800.0f, 150, 90);
+ }
+ } else {
+ Math_ApproachZeroF(&D_809101C4, 1.0f, 0.05f);
+ func_8019F1C0(&D_8090D614,
+ NA_SE_EN_WIZ_UNARI - SFX_FLAG); // changed from NA_SE_EN_FANTOM_FLOAT in OoT
+ }
+ }
+
+ sReelLinePos[LINE_SEG_COUNT - 1].x = sLurePos.x;
+ sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y;
+ sReelLinePos[LINE_SEG_COUNT - 1].z = sLurePos.z;
+
+ D_809101BC = 1.0f;
+ D_8091725C = 0.5f;
+ break;
+
+ case 2:
+ if (sLurePos.y <= WATER_SURFACE_Y(globalCtx)) {
+ sLurePos.y += D_80917238.y;
+
+ Math_ApproachZeroF(&D_80917238.y, 1.0f, 1.0f);
+
+ if (D_80917206 != 2) {
+ Math_ApproachF(&sLurePos.y, WATER_SURFACE_Y(globalCtx), 0.5f, 1.0f);
+ }
+ }
+
+ Math_ApproachF(&D_809101C4, 2.0f, 1.0f, 0.1f);
+
+ if (D_809171F2 == 0) {
+ D_8090CD14 = 3;
+ } else {
+ D_809171F2--;
+ }
+ break;
+
+ case 3: {
+ f32 sp70;
+
+ D_80911F20 = 0;
+
+ if ((D_8090CD0C != 0) && ((SQ(sLurePos.x) + SQ(sLurePos.z)) < SQ(500.0f))) {
+ D_8090CD10 = 1;
+ }
+
+ player->unk_B28 = 2;
+
+ if (D_809101B4 < 3.0f) {
+ spD0 = D_8091725C * Math_SinS(D_809171FE * 0x1060);
+ Math_ApproachF(&sLureRot.x, -0.5235988f + spD0, 0.3f, D_80917260);
+ Math_ApproachF(&D_80917260, 0.5f, 1.0f, 0.02f);
+ Math_ApproachZeroF(&D_8091725C, 1.0f, 0.02f);
+ } else {
+ D_80917260 = 0.0f;
+ }
+
+ spDC = 0x4000;
+ spE4 = WATER_SURFACE_Y(globalCtx);
+
+ spC8 = SQ(sLurePos.x) + SQ(sLurePos.z);
+ if (spC8 < SQ(920.0f)) {
+ if (sLurePos.y <= (spE4 + 4.0f)) {
+ sp70 = 0.0f;
+
+ if (D_809101CC == 0) {
+ if (fabsf(input->rel.stick_x) > 30.0f) {
+ sp70 = fabsf((input->rel.stick_x - D_8090CD44) * (1.0f / 60.0f));
+ } else if (fabsf(input->rel.stick_y) > 30.0f) {
+ sp70 = fabsf((input->rel.stick_y - D_8090CD48) * (1.0f / 60.0f));
+ }
+ }
+
+ if (sp70 > 1.0f) {
+ sp70 = 1.0f;
+ }
+ if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ sp70 = 0.5f;
+ }
+
+ if (D_8090CD0C != 0) {
+ if (sp70 > 0.3f) {
+ sp70 = 0.3f;
+ }
+ }
+
+ if ((sp70 > 0.2f) && (D_809101B4 < 4.0f)) {
+ D_809101CC = 5;
+
+ if (sp70 > 0.8f) {
+ D_80917270 = 2;
+ } else {
+ D_80917270 = 1;
+ }
+
+ sp90.x = player->actor.world.pos.x - sLurePos.x;
+ sp90.z = player->actor.world.pos.z - sLurePos.z;
+ sp90.y = Math_Acot2F(sp90.z, sp90.x);
+
+ D_809101B0 = (sp70 * D_809101BC) + sp90.y;
+ D_809101BC *= -1.0f;
+ D_809101B4 = fabsf(sp70) * 6.0f;
+ sLureRot.x = 0.0f;
+ D_8091725C = 0.5f;
+ D_809101C0 += (fabsf(sp70) * 7.5f);
+
+ func_8019FAD8(&D_8090D614, NA_SE_EV_LURE_MOVE_W, (sp70 * 1.999f * 0.25f) + 0.75f);
+
+ if (D_80917206 == 2) {
+ D_80917278.y = 5.0f * sp70;
+ sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y;
+ sLurePos.y += D_80917278.y;
+ }
+ } else if (CHECK_BTN_ALL(input->cur.button, BTN_A)) {
+ s32 pad;
+
+ spDC = 0x500;
+ D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI;
+ sLureRot.x = 0.0f;
+ D_8091725C = 0.5f;
+ if (D_80917206 == 2) {
+ D_80917278.y = 0.2f;
+ sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y;
+ sLurePos.y += D_80917278.y;
+ }
+ }
+ } else {
+ if (D_809101C0 > 150.0f) {
+ sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI;
+ D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI;
+ D_809101C0 += 2.0f;
+ }
+ }
+ } else {
+ spE4 = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx);
+ if (sLurePos.y <= spE4) {
+ sLurePos.y = spE4;
+ spDC = 0x500;
+ D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI;
+ sLureRot.x = 0.0f;
+ if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ D_809101C0 += 6.0f;
+ func_8019F1C0(&D_8090D614, NA_SE_PL_WALK_SAND);
+ }
+ } else {
+ if (D_809101C0 > 150.0f) {
+ sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI;
+ D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI;
+ D_809101C0 += 2.0f;
+ }
+ }
+ }
+
+ Math_ApproachZeroF(&D_809101B4, 1.0f, 0.3f);
+ Math_ApproachS(&D_809101B8, (D_809101B0 * 32768.0f) / M_PI, 3, spDC);
+
+ sLureRot.y = (D_809101B8 / 32768.0f) * M_PI;
+
+ sp90.x = 0.0f;
+ sp90.y = 0.0f;
+ sp90.z = D_809101B4;
+
+ Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW);
+
+ if (D_80917206 == 2) {
+ Vec3f sp64;
+
+ Matrix_MultiplyVector3fByState(&sp90, &sp64);
+ D_80917278.x = sp64.x;
+ D_80917278.z = sp64.z;
+ phi_f0 = 10.0f;
+ } else {
+ Matrix_MultiplyVector3fByState(&sp90, &D_80917278);
+ phi_f0 = 0.0f;
+ }
+
+ D_80917254 = 0.0f;
+
+ if ((D_80917206 == 1) && CHECK_BTN_ALL(input->cur.button, BTN_A)) {
+ D_80917278.y = -2.0f;
+
+ if (D_809171FE & 1) {
+ D_80917254 = 0.5f;
+ } else {
+ D_80917254 = -0.5f;
+ }
+ } else if (sReelLinePos[LINE_SEG_COUNT - 1].y < (WATER_SURFACE_Y(globalCtx) + phi_f0)) {
+ if (D_80917206 == 2) {
+ Vec3f sp58 = this->actor.world.pos;
+ this->actor.prevPos = this->actor.world.pos = sLurePos;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 30.0f, 0x44);
+ this->actor.world.pos = sp58;
+
+ D_80917278.y += -0.5f;
+ if (D_80917278.y < -1.0f) {
+ D_80917278.y = -1.0f;
+ }
+
+ if (sLurePos.y < (this->actor.floorHeight + 5.0f)) {
+ sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y = this->actor.floorHeight + 5.0f;
+ D_80917278.y = 0.0f;
+ } else {
+ D_80917270 = 1;
+ }
+ } else {
+ D_80917278.y = fabsf(sReelLinePos[LINE_SEG_COUNT - 1].y - WATER_SURFACE_Y(globalCtx)) * 0.2f;
+ if (D_80917278.y > 1.5f) {
+ D_80917278.y = 1.5f;
+ }
+ }
+ }
+
+ sReelLinePos[LINE_SEG_COUNT - 1].x += D_80917278.x;
+ sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y;
+ sReelLinePos[LINE_SEG_COUNT - 1].z += D_80917278.z;
+
+ if (sReelLinePos[LINE_SEG_COUNT - 1].y > (spE4 + 6.0f)) {
+ sReelLinePos[LINE_SEG_COUNT - 1].y -= 5.0f;
+ }
+
+ D_80917238.x = D_80917238.y = D_80917238.z = D_80917248.y = 0.0f;
+
+ if (CHECK_BTN_ALL(input->cur.button, BTN_A)) {
+ if (CHECK_BTN_ALL(input->cur.button, BTN_R)) {
+ D_809101C0 += 1.5f;
+ play_sound(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG);
+ Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 2.0f);
+ } else {
+ D_809101C0 += D_8091726C;
+ play_sound(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG);
+ Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 0.2f);
+ }
+
+ if (sReelLinePos[LINE_SEG_COUNT - 1].y > (WATER_SURFACE_Y(globalCtx) + 4.0f)) {
+ Math_ApproachF(&D_809101C4, 3.0f, 1.0f, 0.2f);
+ } else {
+ Math_ApproachF(&D_809101C4, 1.0f, 1.0f, 0.2f);
+ }
+ } else {
+ Math_ApproachF(&D_809101C4, 2.0f, 1.0f, 0.2f);
+ }
+
+ Math_ApproachF(&sLurePos.x, sReelLinePos[LINE_SEG_COUNT - 1].x, 1.0f, D_809101D0);
+ Math_ApproachF(&sLurePos.y, sReelLinePos[LINE_SEG_COUNT - 1].y, 1.0f, D_809101D0);
+ Math_ApproachF(&sLurePos.z, sReelLinePos[LINE_SEG_COUNT - 1].z, 1.0f, D_809101D0);
+
+ if (D_809101B4 > 1.0f) {
+ Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 1.0f);
+ }
+
+ Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 0.1f);
+
+ if (D_809101C0 >= 195.0f) {
+ D_809101C0 = 195.0f;
+ D_8090CD14 = 0;
+ D_809101C4 = 520.0f;
+ D_8090CD4C = 3;
+ }
+
+ if ((sLurePos.y <= (WATER_SURFACE_Y(globalCtx) + 4.0f)) &&
+ (sLurePos.y >= (WATER_SURFACE_Y(globalCtx) - 4.0f))) {
+ phi_v0 = 63;
+ if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_809101B4 > 1.0f)) {
+ phi_v0 = 1;
+ }
+
+ if ((D_809171FE & phi_v0) == 0) {
+ spA8 = sLurePos;
+ spA8.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &spA8, 30.0f, 300.0f, 150, 90);
+ }
+ }
+ break;
+ }
+
+ case 4:
+ if (this->unk_14F != 0) {
+ this->unk_14F--;
+ D_809101C0 += D_8091726C;
+ }
+
+ if (CHECK_BTN_ALL(input->cur.button, BTN_A)) {
+ if ((SQ(sLurePos.x) + SQ(sLurePos.z)) > SQ(920.0f)) {
+ D_809101C0 += 1.0f;
+ } else {
+ D_809101C0 += D_8091726C;
+ }
+ play_sound(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG);
+ }
+
+ if ((D_809171FE & 0x1F) == 0) {
+ if ((D_80917274 != 0) || (D_80917206 != 2)) {
+ D_8090CD24 = 5;
+ }
+ }
+
+ Math_ApproachF(&D_809101C4, 0.0f, 1.0f, 0.2f);
+ break;
+
+ case 5:
+ D_809101C8 = 0.0005000001f;
+ sReelLinePos[LINE_SEG_COUNT - 1].x = sLurePos.x;
+ sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y;
+ sReelLinePos[LINE_SEG_COUNT - 1].z = sLurePos.z;
+ D_809101C4 = 2.0f;
+ break;
+ }
+}
+#else
+static Vec3f D_8090D620 = { 0.0f, 0.0f, 0.0f };
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateLure.s")
#endif
-extern ColliderJntSphElementInit D_8090CD58[12];
-extern ColliderJntSphInit D_8090CF08;
-extern InitChainEntry D_8090D4D0[];
+s32 func_809033F0(EnFishing* this, GlobalContext* globalCtx, u8 ignorePosCheck) {
+ s16 i;
+ s16 count;
+ f32 scale;
+ Vec3f pos;
+ Vec3f vel;
+ f32 speedXZ;
+ f32 angle;
-extern UNK_TYPE D_0600007C;
-extern UNK_TYPE D_06003230;
-extern UNK_TYPE D_0600453C;
-extern UNK_TYPE D_060074C8;
-extern UNK_TYPE D_06008678;
-extern UNK_TYPE D_0600B950;
-extern UNK_TYPE D_0600C220;
-extern UNK_TYPE D_060113D0;
-extern UNK_TYPE D_06012160;
-extern UNK_TYPE D_060121F0;
-extern UNK_TYPE D_06014030;
-extern UNK_TYPE D_060153D0;
+ if ((this->actor.world.pos.y < (WATER_SURFACE_Y(globalCtx) - 10.0f)) && !ignorePosCheck) {
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC6C0.s")
+ // Necessary to match
+ if (this->unk_1A4) {}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC770.s")
+ if (this->unk_1A4 >= 40.0f) {
+ count = 40;
+ scale = 1.2f;
+ } else {
+ count = 30;
+ scale = 1.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC790.s")
+ for (i = 0; i < count; i++) {
+ speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale;
+ angle = Rand_ZeroFloat(6.28f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC8B8.s")
+ vel.x = __sinf(angle) * speedXZ;
+ vel.z = __cosf(angle) * speedXZ;
+ vel.y = (Rand_ZeroFloat(3.0f) + 3.0f) * scale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC964.s")
+ pos = this->actor.world.pos;
+ pos.x += vel.x * 3.0f;
+ pos.y = WATER_SURFACE_Y(globalCtx);
+ pos.z += vel.z * 3.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCABC.s")
+ EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel,
+ (Rand_ZeroFloat(0.02f) + 0.025f) * scale);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCC0C.s")
+ pos = this->actor.world.pos;
+ pos.y = WATER_SURFACE_Y(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCDBC.s")
+ EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &pos, 100.0f, 800.0f, 150, 90);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCF60.s")
+ this->unk_149 = 30;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FD054.s")
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Init.s")
+void func_809036BC(EnFishing* this, GlobalContext* globalCtx) {
+ s16 count;
+ s16 i;
+ f32 scale;
+ Vec3f pos;
+ Vec3f vel;
+ f32 speedXZ;
+ f32 angle;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Destroy.s")
+ // Necessary to match
+ if (this->unk_1A4) {}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FDCDC.s")
+ if (this->unk_1A4 >= 45.0f) {
+ count = 30;
+ scale = 0.5f;
+ } else {
+ count = 20;
+ scale = 0.3f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FE3F8.s")
+ for (i = 0; i < count; i++) {
+ speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale;
+ angle = Rand_ZeroFloat(6.28f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEE1C.s")
+ vel.x = __sinf(angle) * speedXZ;
+ vel.z = __cosf(angle) * speedXZ;
+ vel.y = Rand_ZeroFloat(2.0f) + 2.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEF70.s")
+ pos = this->actor.world.pos;
+ pos.x += (vel.x * 3.0f);
+ pos.y += (vel.y * 3.0f);
+ pos.z += (vel.z * 3.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF064.s")
+ EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel,
+ (Rand_ZeroFloat(0.02f) + 0.025f) * scale);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF5E0.s")
+void func_809038A4(EnFishing* this, Input* input) {
+ Vec3f sp34;
+ Vec3f sp28;
+ f32 sp24;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF750.s")
+ sp34.x = sLurePos.x - this->actor.world.pos.x;
+ sp34.y = sLurePos.y - this->actor.world.pos.y;
+ sp34.z = sLurePos.z - this->actor.world.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFC44.s")
+ sp24 = SQ(sp34.x) + SQ(sp34.y) + SQ(sp34.z);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFF3C.s")
+ if ((D_8090CD14 == 3) && (this->unk_19A == 0) && (D_8090CD0C == 0)) {
+ Matrix_InsertYRotation_f((-this->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&sp34, &sp28);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900228.s")
+ if ((sp28.z > 0.0f) || (this->unk_1A4 < 40.0f)) {
+ if ((this->unk_150 == 7) && (sp24 < SQ(200.0f))) {
+ this->unk_150 = 4;
+ this->unk_1AC = sLurePos;
+ this->unk_1A8 = 28672.0f;
+ this->unk_180 = 5.0f;
+ } else {
+ if ((CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_809101B4 > 1.0f)) && (sp24 < SQ(120.0f))) {
+ this->unk_150 = 2;
+ this->unk_156 = 0;
+ this->unk_172[0] = 0;
+ this->unk_172[2] = Rand_ZeroFloat(100.0f) + 100.0f;
+ this->unk_1A0 = sFishInits[this->actor.params - 100].unk_0C;
+ this->unk_1A8 = 0.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900A04.s")
+ if ((this->unk_172[1] == 0) && (sp24 < SQ(70.0f))) {
+ this->unk_150 = 2;
+ this->unk_156 = 0;
+ this->unk_172[0] = 0;
+ this->unk_172[2] = Rand_ZeroFloat(100.0f) + 100.0f;
+ this->unk_1A0 = sFishInits[this->actor.params - 100].unk_0C;
+ this->unk_1A8 = 0.0f;
+ }
+ }
+ }
+ } else if ((D_8090CD14 == 4) && (D_80917274 != 0) && (sp24 < SQ(100.0f)) && (this->unk_150 >= 10)) {
+ this->unk_152 = 0;
+ this->unk_150 = 1;
+ this->unk_19C = 1000;
+ this->unk_19A = 100;
+ this->unk_172[1] = 50;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80901480.s")
+ if ((D_80917206 != 2) && (D_80917264 != 0) && (this->unk_1A4 > 60.0f) && (sp24 < SQ(30.0f)) &&
+ (this->unk_150 >= 10)) {
+ this->unk_152 = 0;
+ this->unk_150 = 1;
+ this->unk_19C = 1000;
+ this->unk_19A = 100;
+ this->unk_172[1] = 50;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809033F0.s")
+void func_80903C60(EnFishing* this, u8 arg1) {
+ u16 sfxId;
+ u8 temp;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809036BC.s")
+ if (this->unk_148 == 0) {
+ temp = this->unk_1A4;
+ } else {
+ temp = 2.0f * this->unk_1A4;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809038A4.s")
+ if (arg1 == 0) {
+ if (temp >= 50) {
+ sfxId = NA_SE_EV_DIVE_INTO_WATER;
+ } else if (temp >= 40) {
+ sfxId = NA_SE_EV_BOMB_DROP_WATER;
+ } else {
+ sfxId = NA_SE_EV_BOMB_DROP_WATER;
+ }
+ } else {
+ if (temp >= 50) {
+ sfxId = NA_SE_EV_JUMP_OUT_WATER;
+ } else if (temp >= 40) {
+ sfxId = NA_SE_EV_OUT_OF_WATER;
+ } else {
+ sfxId = NA_SE_EV_OUT_OF_WATER;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903C60.s")
+ Audio_PlayActorSound2(&this->actor, sfxId);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903E20.s")
+void EnFishing_HandleAquariumDialog(EnFishing* this, GlobalContext* globalCtx) {
+ if (sLinkAge == 1) {
+ if (gSaveContext.save.roomInf[127][2] & 0x7F) {
+ if (gSaveContext.save.roomInf[127][2] & 0x80) {
+ this->actor.textId = 0x40B1;
+ } else {
+ this->actor.textId = 0x4089;
+ }
+ } else {
+ this->actor.textId = 0x40AE;
+ }
+ } else if (gSaveContext.save.roomInf[127][2] & 0x7F000000) {
+ if (gSaveContext.save.roomInf[127][2] & 0x80000000) {
+ this->actor.textId = 0x40B1;
+ } else {
+ this->actor.textId = 0x4089;
+ }
+ } else {
+ this->actor.textId = 0x40AE;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Update.s")
+ if (this->unk_1CB == 0) {
+ if (this->unk_1CC == 0) {
+ this->actor.flags |= 1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908554.s")
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ D_8090CCF8 = D_809171CC;
+ this->unk_1CB = 1;
+ } else {
+ func_800B863C(&this->actor, globalCtx);
+ }
+ } else {
+ this->unk_1CC--;
+ this->actor.flags &= ~1;
+ }
+ } else if (func_800B867C(&this->actor, globalCtx)) {
+ this->unk_1CB = 0;
+ this->unk_1CC = 20;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908674.s")
+#ifdef NON_MATCHING
+// D_80917266 in case 5 around the large branching
+void EnFishing_UpdateFish(Actor* thisx, GlobalContext* globalCtx2) {
+ s16 i;
+ s16 sp134 = 10;
+ f32 sp130;
+ f32 sp12C;
+ f32 sp128;
+ f32 sp124;
+ f32 multiplier;
+ f32 sp11C;
+ f32 sp118;
+ Vec3f sp10C;
+ Vec3f sp100;
+ s16 spFE;
+ s16 spFC;
+ s16 spFA;
+ s16 phi_v0;
+ s16 spF6;
+ s16 spF4;
+ s16 spF2;
+ s16 spF0;
+ s16 spEE;
+ EnFishing* this = THIS;
+ GlobalContext* globalCtx = globalCtx2;
+ Player* player = GET_PLAYER(globalCtx);
+ Input* input = CONTROLLER1(globalCtx);
+ f32 spD8;
+ f32 phi_f0;
+ f32 phi_f2;
+ Vec3f spC4;
+ Vec3f spB8;
+ u8 phi_v0_2;
+ f32 temp_f0;
+ f32 temp;
+ s32 pad;
+ f32 spA4;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809086B4.s")
+ this->actor.uncullZoneForward = 700.0f;
+ this->actor.uncullZoneScale = 50.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908734.s")
+ if (this->unk_148 == 0) {
+ sp118 = (player->actor.speedXZ * 0.15f) + 0.25f;
+ } else {
+ sp118 = (player->actor.speedXZ * 0.3f) + 0.25f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Draw.s")
+ if ((D_80917200 != 0) || (sCameraId != MAIN_CAM) ||
+ ((player->actor.world.pos.z > 1150.0f) && (this->unk_150 != 100))) {
+ this->actor.flags &= ~1;
+ } else {
+ this->actor.flags |= 1;
+ if (D_8090CD14 != 0) {
+ if (D_80917202 == 0) {
+ this->actor.focus.pos = sLurePos;
+ } else if (D_80917202 == 1) {
+ D_8090CD4C = 1;
+ D_80911F50 = 0.0f;
+ D_809171DC = 2;
+ }
+ }
+ this->actor.focus.pos = this->actor.world.pos;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809089B8.s")
+ this->unk_154++;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908A64.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_172); i++) {
+ if (this->unk_172[i] != 0) {
+ this->unk_172[i]--;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908B4C.s")
+ if (this->unk_19C != 0) {
+ this->unk_19C--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908E08.s")
+ if (this->unk_19A != 0) {
+ this->unk_19A--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909234.s")
+ if (this->unk_198 != 0) {
+ this->unk_198--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909AD0.s")
+ if (this->unk_149 != 0) {
+ this->unk_149--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909CC0.s")
+ Math_ApproachF(&this->unk_190, this->unk_188, 1.0f, 0.2f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090AB6C.s")
+ if (this->unk_150 == 6) {
+ Math_ApproachF(&this->unk_194, this->unk_18C, 0.2f, 200.0f);
+ } else {
+ phi_f0 = 1.0f;
+ phi_f2 = 1.0f;
+ if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) {
+ phi_f0 = 1.5f;
+ phi_f2 = 3.0f;
+ }
+ Math_ApproachF(&this->unk_194, this->unk_18C * phi_f0, 1.0f, 500.0f * phi_f2);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C884.s")
+ Math_ApproachS(&this->unk_168, 0, 5, 500);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C8BC.s")
+ if (this->unk_148 == 0) {
+ Actor_SetScale(&this->actor, this->unk_1A4 * 15.0f * 0.00001f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C96C.s")
+ this->unk_184 += this->unk_190;
+
+ temp = __cosf(this->unk_184);
+ this->unk_164 = this->unk_166 + (temp * this->unk_194);
+
+ temp = __cosf(this->unk_184 + -1.2f);
+ this->unk_16E = this->unk_166 + (temp * this->unk_194 * 1.6f);
+ } else {
+ Actor_SetScale(&this->actor, this->unk_1A4 * 65.0f * 0.000001f);
+
+ this->actor.scale.x = this->actor.scale.z * 1.1f;
+ this->actor.scale.y = this->actor.scale.z * 1.1f;
+
+ this->unk_184 += this->unk_190 * 0.8f;
+
+ for (i = 0; i < 3; i++) {
+ temp = __cosf(this->unk_184 + (i * 2.1f));
+ this->unk_1C4[i] = this->unk_166 + (temp * this->unk_194 * 2.0f);
+ }
+
+ temp = __cosf(this->unk_184 + 0.4f);
+ this->unk_164 = (this->unk_194 * temp * 2.0f) * 0.6f;
+ }
+
+ sp130 = this->unk_1AC.x - this->actor.world.pos.x;
+ sp12C = this->unk_1AC.y - this->actor.world.pos.y;
+ sp128 = this->unk_1AC.z - this->actor.world.pos.z;
+
+ spFC = Math_FAtan2F(sp128, sp130);
+ sp124 = sqrtf(SQ(sp130) + SQ(sp128));
+
+ spFE = Math_FAtan2F(sp124, sp12C);
+ sp124 = sqrtf(SQ(sp130) + SQ(sp128) + SQ(sp12C));
+
+ if ((this->unk_198 != 0) && (this->unk_150 != 2) && (this->unk_150 != 3) && (this->unk_150 != 4)) {
+ if (this->unk_154 & 0x40) {
+ spFC += 0x4000;
+ } else {
+ spFC -= 0x4000;
+ }
+ if ((this->unk_154 + 0x20) & 0x40) {
+ spFE += 0x2000;
+ } else {
+ spFE -= 0x2000;
+ }
+ }
+
+ switch (this->unk_150) {
+ case 100:
+ EnFishing_HandleAquariumDialog(this, globalCtx);
+
+ this->actor.uncullZoneForward = 500.0f;
+ this->actor.uncullZoneScale = 300.0f;
+
+ Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y + 20.0f,
+ this->actor.world.pos.z - 50.0f, 255, 255, 255, 255);
+
+ this->unk_1A4 = D_809171CC;
+ sp100.y = Math_SinS(globalCtx->gameplayFrames * 300);
+ sp100.z = Math_SinS(globalCtx->gameplayFrames * 230) * 2.0f;
+ this->actor.world.pos.x = 130.0f;
+ this->actor.world.pos.y = 55.0f + sp100.y;
+ this->actor.world.pos.z = 1300.0f + sp100.z;
+ this->actor.shape.rot.y = -0x8000;
+
+ if ((this->actor.projectedPos.z < 200.0f) && (this->actor.projectedPos.z > 0.0f)) {
+ spC4.x = randPlusMinusPoint5Scaled(5.0f) + 130.0f;
+ spC4.y = 40.0f;
+ spC4.z = randPlusMinusPoint5Scaled(5.0f) + 1280.0f;
+ EnFishing_SpawnBubble(NULL, globalCtx->specialEffects, &spC4, Rand_ZeroFloat(0.02f) + 0.03f, 1);
+ }
+
+ Math_ApproachS(&this->unk_16A, (Math_SinS(this->unk_154 * 0x800) * 2500.0f) + 2500.0f, 2, 0x7D0);
+ Math_ApproachS(&this->unk_16C, Math_SinS(this->unk_154 * 0xA00) * 1500.0f, 2, 0x7D0);
+
+ this->unk_188 = 0.3f;
+ this->unk_18C = 333.33334f;
+ return;
+
+ case 10:
+ this->unk_1AC = this->actor.home.pos;
+
+ Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 0.5f);
+ Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f);
+
+ if (sp124 < 40.0f) {
+ this->unk_150 = 11;
+ this->unk_188 = 0.4f;
+ this->unk_18C = 500.0f;
+ }
+
+ func_809038A4(this, input);
+
+ if (this->actor.xzDistToPlayer < (250.0f * sp118)) {
+ this->unk_152 = this->unk_150 = 0;
+ this->unk_19C = 1000;
+ this->unk_19A = 200;
+ this->unk_172[1] = 50;
+ }
+ break;
+
+ case 11:
+ this->unk_1AC = this->actor.home.pos;
+
+ Math_ApproachF(&this->actor.speedXZ, 0.0f, 1.0f, 0.05f);
+ Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f);
+
+ if (sp124 >= 40.0f) {
+ this->unk_150 = 10;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ }
+ func_809038A4(this, input);
+
+ if (this->actor.xzDistToPlayer < (250.0f * sp118)) {
+ this->unk_152 = this->unk_150 = 0;
+ this->unk_19C = 1000;
+ this->unk_19A = 200;
+ this->unk_172[1] = 50;
+ }
+
+ if (!func_80152498(&globalCtx->msgCtx)) {
+ if ((gSaveContext.save.time >= 0xC000) && (gSaveContext.save.time <= 0xC01B)) {
+ this->unk_150 = 7;
+ this->unk_172[3] = Rand_ZeroFloat(150.0f) + 200.0f;
+ }
+ if ((gSaveContext.save.time >= 0x3AAA) && (gSaveContext.save.time <= 0x3AC5)) {
+ this->unk_150 = 7;
+ this->unk_172[3] = Rand_ZeroFloat(150.0f) + 200.0f;
+ }
+ }
+ break;
+
+ case 0:
+ Math_ApproachF(&this->actor.speedXZ, 1.0f, 1.0f, 0.05f);
+ Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f);
+
+ if (this->unk_172[0] == 0) {
+ if (this->unk_19C == 0) {
+ this->unk_150 = this->unk_152 = 10;
+ } else {
+ this->unk_150 = 1;
+ this->unk_172[0] = Rand_ZeroFloat(30.0f) + 10.0f;
+ this->unk_1AC.x = randPlusMinusPoint5Scaled(300.0f);
+ this->unk_1AC.y = (WATER_SURFACE_Y(globalCtx) - 50.0f) - Rand_ZeroFloat(50.0f);
+ this->unk_1AC.z = randPlusMinusPoint5Scaled(300.0f);
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ }
+ }
+
+ if (D_80917206 == 2) {
+ func_809038A4(this, input);
+ } else {
+ this->actor.flags &= ~1;
+ }
+ break;
+
+ case 1:
+ if (this->unk_148 == 1) {
+ this->unk_150 = -1;
+ this->unk_19C = 20000;
+ this->unk_19A = 20000;
+ this->unk_1AC.x = 0.0f;
+ this->unk_1AC.y = -140.0f;
+ this->unk_1AC.z = 0.0f;
+ } else {
+ Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f);
+
+ if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) {
+ Math_ApproachF(&this->unk_1A8, 8192.0f, 1.0f, 768.0f);
+ Math_ApproachF(&this->actor.speedXZ, 4.2f, 1.0f, 0.75);
+ this->unk_188 = 1.2f;
+ this->unk_18C = 4000.0f;
+ this->unk_172[0] = 20;
+ } else {
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ Math_ApproachF(&this->actor.speedXZ, 1.5f, 1.0f, 0.1f);
+ }
+
+ if ((this->unk_172[0] == 0) || (sp124 < 50.0f)) {
+ this->unk_150 = 0;
+ this->unk_172[0] = Rand_ZeroFloat(30.0f) + 3.0f;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 500.0f;
+ }
+
+ if (D_80917206 == 2) {
+ func_809038A4(this, input);
+ } else {
+ this->actor.flags &= ~1;
+ }
+ }
+ break;
+
+ case -1:
+ Math_ApproachS(&this->unk_15E, 0, 0x14, 0x20);
+
+ if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) {
+ Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.75);
+ this->unk_188 = 1.0f;
+ this->unk_172[0] = 20;
+ this->unk_18C = 4000.0f;
+ Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f);
+
+ if ((globalCtx->gameplayFrames % 32) == 0) {
+ this->unk_1AC.x = randPlusMinusPoint5Scaled(600.0f);
+ this->unk_1AC.z = randPlusMinusPoint5Scaled(600.0f);
+ this->unk_1AC.y = -120.0f;
+ }
+ } else if (sp124 > 50.0f) {
+ this->unk_188 = 0.8f;
+ this->unk_18C = 1500.0f;
+ Math_ApproachF(&this->actor.speedXZ, 1.0f, 1.0f, 0.1f);
+ Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f);
+ } else {
+ this->unk_188 = 0.4f;
+ this->unk_18C = 500.0f;
+ Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.02f);
+ Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f);
+ }
+
+ if (this->unk_19C == 0) {
+ this->unk_150 = 10;
+ this->unk_152 = 10;
+ } else if (((this->unk_19C & 0x7FF) == 0) && (this->unk_19C < 15000)) {
+ this->unk_150 = -2;
+ this->actor.world.rot.x = this->actor.shape.rot.x = 0;
+ this->unk_1AC.y = WATER_SURFACE_Y(globalCtx) + 10.0f;
+ this->unk_1AC.x = Rand_ZeroFloat(50.0f);
+ this->unk_1AC.z = Rand_ZeroFloat(50.0f);
+ }
+
+ this->actor.flags &= ~1;
+ break;
+
+ case -2:
+ if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) {
+ this->unk_150 = -1;
+ this->unk_1AC.y = -120.0f;
+ } else {
+ this->unk_188 = 0.6f;
+ this->unk_18C = 1000.0f;
+
+ Math_ApproachS(&this->unk_15E, -0x1000, 0x14, 0x100);
+
+ if (this->actor.world.pos.y < (WATER_SURFACE_Y(globalCtx) - 20.0f)) {
+ Math_ApproachF(&this->actor.speedXZ, 0.5f, 1.0f, 0.1f);
+ } else {
+ Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.01f);
+
+ if ((this->actor.speedXZ == 0.0f) ||
+ (this->actor.world.pos.y > (WATER_SURFACE_Y(globalCtx) - 5.0f))) {
+ this->unk_1AC.x = Rand_ZeroFloat(300.0f);
+ this->unk_1AC.z = Rand_ZeroFloat(300.0f);
+ this->unk_1AC.y = this->actor.floorHeight + 10.0f;
+ this->unk_150 = -25;
+ this->unk_1A8 = 0.0f;
+
+ spB8 = this->fishMouthPos;
+ spB8.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &spB8, 10.0f,
+ 300.0f, 150, 90);
+ EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &spB8, 30.0f,
+ 400.0f, 150, 90);
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_PL_CATCH_BOOMERANG);
+ break;
+ }
+ }
+
+ Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f);
+ this->actor.flags &= ~1;
+ }
+ break;
+
+ case -25:
+ if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) {
+ this->unk_150 = -1;
+ this->unk_1AC.y = -120.0f;
+ } else {
+ Math_ApproachS(&this->unk_15E, 0x1000, 0x14, 0x6A);
+
+ if (sp124 > 40.0f) {
+ this->unk_188 = 0.7f;
+ this->unk_18C = 1200.0f;
+ Math_ApproachF(&this->actor.speedXZ, 0.5f, 1.0f, 0.01f);
+ Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f);
+ } else {
+ this->unk_150 = -1;
+ }
+ }
+ break;
+
+ case 2:
+ if ((this->actor.params + D_80917268) & 1) {
+ sp10C.x = 10.0f;
+ } else {
+ sp10C.x = -10.0f;
+ }
+ sp10C.y = 0.0f;
+ sp10C.z = 0.0f;
+ Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&sp10C, &sp100);
+
+ this->unk_1AC.x = sLurePos.x + sp100.x;
+ this->unk_1AC.z = sLurePos.z + sp100.z;
+
+ if (D_80917206 == 2) {
+ this->unk_1AC.y = sLurePos.y;
+ } else if (this->unk_148 == 0) {
+ this->unk_1AC.y = sLurePos.y - 15.0f;
+ } else {
+ this->unk_1AC.y = sLurePos.y - 5.0f;
+ }
+
+ if (this->unk_1AC.y <= this->actor.floorHeight) {
+ this->unk_1AC.y = this->actor.floorHeight + 3.0f;
+ }
+
+ if ((D_80917206 != 2) && (this->unk_1AC.y < this->actor.world.pos.y)) {
+ Math_ApproachF(&this->actor.world.pos.y, this->unk_1AC.y, 0.1f,
+ (this->actor.world.pos.y - this->unk_1AC.y) * 0.1f);
+ }
+
+ Math_ApproachF(&this->unk_1A8, 8192.0f, 1.0f, 384.0f);
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ this->unk_1A0 += 0.005f;
+ }
+
+ if (D_80917270 != 0) {
+ if (D_80917270 == 1) {
+ this->unk_1A0 += 0.01f;
+ } else {
+ this->unk_1A0 += 0.05f;
+ }
+ D_80917270 = 0;
+ }
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->unk_1A0 += 0.008f;
+ }
+
+ if (sp124 < ((this->unk_1A4 * 0.5f) + 20.0f)) {
+ if (this->unk_156 == 0) {
+ this->unk_188 = 1.0f;
+ this->unk_18C = 500.0f;
+ this->unk_172[0] = Rand_ZeroFloat(10.0f) + 2.0f;
+ }
+ Math_ApproachF(&this->actor.speedXZ, -0.2f, 1.0f, 0.1f);
+ this->unk_156 = 1;
+ } else {
+ if (this->unk_156 != 0) {
+ this->unk_188 = 1.0f;
+ this->unk_1A8 = 0.0f;
+ this->unk_18C = 3000.0f;
+ }
+ Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.15f);
+ this->unk_156 = 0;
+ }
+
+ if (this->unk_1A4 >= 60.0f) {
+ multiplier = 0.3f;
+ } else if (this->unk_1A4 >= 45.0f) {
+ multiplier = 0.6f;
+ } else {
+ multiplier = 1.0f;
+ }
+
+ if ((gSaveContext.save.time >= 0xB555) && (gSaveContext.save.time <= 0xCAAA)) {
+ multiplier *= 1.75f;
+ } else if ((gSaveContext.save.time >= 0x3555) && (gSaveContext.save.time <= 0x4AAA)) {
+ multiplier *= 1.5f;
+ } else if (D_809171CA != 0) {
+ multiplier *= 1.5f;
+ } else if ((u8)D_8090CCD0 != 0) {
+ multiplier *= 3.0f;
+ }
+
+ sp11C = 0.03f * multiplier;
+ if (D_80917206 == 2) {
+ sp11C *= 5.0f;
+ }
+
+ if (((this->unk_172[0] == 1) || (Rand_ZeroOne() < sp11C)) &&
+ (Rand_ZeroOne() < (this->unk_1A0 * multiplier))) {
+ if (this->unk_148 == 0) {
+ this->unk_150 = 3;
+ this->unk_188 = 1.2f;
+ this->unk_18C = 5000.0f;
+ this->unk_172[0] = Rand_ZeroFloat(10.0f);
+ } else {
+ this->unk_150 = -3;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 3000.0f;
+ this->unk_172[0] = 40;
+ }
+ if (D_80917206 == 2) {
+ this->unk_180 = Rand_ZeroFloat(1.5f) + 3.0f;
+ } else {
+ this->unk_180 = Rand_ZeroFloat(1.5f) + 4.5f;
+ }
+ }
+
+ if ((D_8090CD14 != 3) || (this->unk_172[2] == 0) ||
+ (sqrtf(SQ(this->actor.world.pos.x) + SQ(this->actor.world.pos.z)) > 800.0f)) {
+ this->unk_150 = this->unk_152;
+ this->unk_172[1] = Rand_ZeroFloat(30.0f) + 50.0f;
+ this->unk_172[0] = Rand_ZeroFloat(10.0f) + 5.0f;
+ this->unk_188 = 1.0f;
+ this->unk_1A8 = 0.0f;
+ this->unk_18C = 2000.0f;
+ }
+
+ if (this->actor.xzDistToPlayer < (100.0f * sp118)) {
+ this->unk_152 = this->unk_150 = 0;
+ this->unk_19C = 1000;
+ this->unk_19A = 200;
+ this->unk_172[1] = 50;
+ }
+ break;
+
+ case 3:
+ this->unk_149 = 6;
+ sp134 = 2;
+
+ if (((s16)player->actor.world.pos.x + D_80917268) & 1) {
+ sp10C.x = 30.0f;
+ } else {
+ sp10C.x = -30.0f;
+ }
+ sp10C.y = 0.0f;
+ sp10C.z = 30.0f;
+
+ Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&sp10C, &sp100);
+
+ this->unk_1AC.x = sLurePos.x + sp100.x;
+ this->unk_1AC.z = sLurePos.z + sp100.z;
+ this->unk_1AC.y = sLurePos.y - 10.0f;
+ this->unk_1A8 = 4096.0f;
+ Math_ApproachF(&this->actor.speedXZ, this->unk_180 * 0.8f, 1.0f, 1.0f);
+
+ if ((D_8090CD14 != 3) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) ||
+ (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) {
+ this->unk_150 = this->unk_152;
+ this->unk_172[0] = 0;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ } else if ((this->unk_172[0] == 0) || (sp124 < 30.0f)) {
+ this->unk_150 = 4;
+ this->unk_1AC = sLurePos;
+ this->unk_1A8 = 16384.0f;
+ this->unk_188 = 1.2f;
+ this->unk_18C = 5000.0f;
+ this->unk_172[0] = 20;
+ }
+ break;
+
+ case 4:
+ Math_ApproachF(&this->unk_1A8, 16384.0f, 1.0f, 4096.0f);
+ Math_ApproachS(&this->unk_168, 0x4E20, 4, 0x1388);
+
+ this->unk_149 = 50;
+ sp134 = 2;
+ this->unk_1AC = sLurePos;
+ Math_ApproachF(&this->actor.speedXZ, this->unk_180, 1.0f, 1.0f);
+
+ if ((D_8090CD14 != 3) || (this->unk_172[0] == 0) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) ||
+ (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) {
+
+ this->unk_172[0] = 0;
+ this->unk_150 = this->unk_152;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ } else if (sp124 < 10.0f) {
+ if (func_809033F0(this, globalCtx, false)) {
+ func_80903C60(this, 0);
+ }
+
+ this->unk_150 = 5;
+ this->unk_188 = 1.2f;
+ this->unk_18C = 5000.0f;
+ this->unk_172[1] = 150;
+ this->unk_172[0] = 0;
+ this->unk_172[2] = 0;
+ this->unk_172[3] = 120;
+
+ D_8090CD14 = 4;
+ sFishingHookedFish = this;
+ sFishMouthOffset.y = 500.0f - Rand_ZeroFloat(400.0f);
+
+ if (D_80917206 == 2) {
+ if (this->unk_1A4 > 70.0f) {
+ phi_v0 = Rand_ZeroFloat(20.0f) + 10.0f;
+ } else if (this->unk_1A4 > 60.0f) {
+ phi_v0 = Rand_ZeroFloat(30.0f) + 20.0f;
+ } else if (this->unk_1A4 > 50.0f) {
+ phi_v0 = Rand_ZeroFloat(30.0f) + 30.0f;
+ } else {
+ phi_v0 = Rand_ZeroFloat(40.0f) + 40.0f;
+ }
+ D_80917272 = phi_v0;
+ D_809171F4 = phi_v0;
+ func_8013EC44(0.0f, 60, phi_v0 * 3, 10);
+ } else {
+ if (this->unk_1A4 > 70.0f) {
+ phi_v0 = Rand_ZeroFloat(5.0f) + 10.0f;
+ } else if (this->unk_1A4 > 60.0f) {
+ phi_v0 = Rand_ZeroFloat(5.0f) + 15.0f;
+ } else if (this->unk_1A4 > 50.0f) {
+ phi_v0 = Rand_ZeroFloat(5.0f) + 17.0f;
+ } else {
+ phi_v0 = Rand_ZeroFloat(5.0f) + 25.0f;
+ }
+ D_80917272 = phi_v0;
+ D_809171F4 = phi_v0;
+ func_8013EC44(0.0f, 180, phi_v0 * 3, 10);
+ }
+
+ D_80917274 = 0;
+ D_80917266 = 100;
+ D_809171D4 = 0;
+ }
+ break;
+
+ case -3:
+ this->unk_149 = 50;
+ this->unk_1AC = sLurePos;
+ Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 1.0f);
+
+ if ((D_8090CD14 != 3) || (this->unk_172[0] == 0) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) ||
+ (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) {
+
+ this->unk_172[0] = 0;
+ this->unk_188 = 1.0f;
+ this->unk_150 = this->unk_152;
+ this->unk_18C = 2000.0f;
+ } else if (sp124 < 10.0f) {
+ if (sLurePos.y > (WATER_SURFACE_Y(globalCtx) - 10.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_JUMP_OUT_WATER);
+ play_sound(NA_SE_PL_CATCH_BOOMERANG);
+ }
+
+ func_809033F0(this, globalCtx, false);
+ this->unk_150 = 5;
+ this->unk_188 = 1.2f;
+ this->unk_18C = 5000.0f;
+ this->unk_172[1] = 150;
+ this->unk_172[0] = 0;
+ this->unk_172[2] = 0;
+ this->unk_172[3] = 120;
+
+ D_8090CD14 = 4;
+ sFishingHookedFish = this;
+
+ if (D_80917206 == 2) {
+ D_80917272 = 30;
+ D_809171F4 = 100;
+ func_8013EC44(0.0f, 60, 90, 10);
+ } else {
+ D_80917272 = 30;
+ D_809171F4 = 40;
+ func_8013EC44(0.0f, 180, 90, 10);
+ }
+
+ D_80917274 = 0;
+ D_80917266 = 100;
+ D_809171D4 = 0;
+ }
+ break;
+
+ case 5:
+ this->actor.uncullZoneForward = 1200.0f;
+ this->actor.uncullZoneScale = 200.0f;
+
+ D_809171D4++;
+
+ Math_ApproachS(&this->unk_168, 0x2AF8, 4, 0xBB8);
+ sFishingHookedFish = this;
+ Math_ApproachS(&player->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 5, 0x500);
+
+ if (D_80917274 == 0) {
+ if ((D_80911F20 < 20) && ((D_809171FE & 3) == 0)) {
+ D_80911F20++;
+ }
+ }
+
+ if ((D_80917272 != 0) && (D_80917274 == 0)) {
+ if (((input->rel.stick_y < -50) && (D_8090CD48 > -40)) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ if (input->rel.stick_y < -50) {
+ temp_f0 = 40.0f - ((this->unk_1A4 - 30.0f) * 1.333333f);
+ if (temp_f0 > 0.0f) {
+ this->unk_14A = temp_f0;
+ this->unk_14C = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ this->unk_14E = 1;
+ }
+ }
+
+ this->unk_190 = 1.7f;
+ this->unk_194 = 7000.0f;
+ D_80917274 = 1;
+ Audio_QueueSeqCmd(0x881A); // Changed from 0x81A in OoT
+ D_809171F6 = 0;
+
+ if (this->unk_148 == 1) {
+ spA4 = (this->unk_1A4 * 3.0f) + 120.0f;
+ } else {
+ spA4 = (2.0f * this->unk_1A4) + 120.0f;
+ }
+ if (spA4 > 255.0f) {
+ spA4 = 255.0f;
+ }
+
+ func_8013EC44(0.0f, spA4, 120, 5);
+ D_809171F4 = 40;
+ D_80911E28 = 10;
+ play_sound(NA_SE_IT_FISHING_HIT);
+ }
+ }
+
+ if (this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) {
+ if (this->unk_172[1] > 30) {
+ phi_v0_2 = 7;
+ } else {
+ phi_v0_2 = 0xF;
+ }
+
+ if (((this->unk_154 & phi_v0_2) == 0) && (Rand_ZeroOne() < 0.75f) && (D_809171F4 == 0)) {
+ if (this->unk_1A4 >= 70.0f) {
+ spA4 = 255.0f;
+ } else if (this->unk_1A4 >= 60.0f) {
+ spA4 = 230.0f;
+ } else if (this->unk_1A4 >= 50.0f) {
+ spA4 = 200.0f;
+ } else if (this->unk_1A4 >= 40.0f) {
+ spA4 = 170.0f;
+ } else {
+ spA4 = 140.0f;
+ }
+
+ if (phi_v0_2 == 0xF) {
+ spA4 *= 3.0f / 4.0f;
+ }
+
+ func_8013EC44(0.0f, spA4, Rand_ZeroFloat(5.0f) + 10.0f, 5);
+ }
+
+ if (this->unk_172[1] > 30) {
+ if (this->unk_172[0] == 0) {
+ u16 spA2;
+
+ sp10C.x = 0.0f;
+ sp10C.y = 0.0f;
+ sp10C.z = 200.0f;
+
+ for (spA2 = 0; spA2 < 100; spA2++) {
+
+ Matrix_InsertYRotation_f(randPlusMinusPoint5Scaled(2.3561945f) +
+ (((this->actor.yawTowardsPlayer + 0x8000) / 32768.0f) * M_PI),
+ MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&sp10C, &sp100);
+
+ this->unk_1AC.x = this->actor.world.pos.x + sp100.x;
+ this->unk_1AC.z = this->actor.world.pos.z + sp100.z;
+
+ if ((SQ(this->unk_1AC.x) + SQ(this->unk_1AC.z)) < SQ(750.0f)) {
+ break;
+ }
+ }
+
+ if ((Rand_ZeroOne() < 0.1f) && (this->unk_172[3] == 0)) {
+ u8 phi_a1;
+
+ if (this->unk_1A4 >= 60.0f) {
+ phi_a1 = 255;
+ } else if (this->unk_1A4 >= 50.0f) {
+ phi_a1 = 200;
+ } else {
+ phi_a1 = 180;
+ }
+ func_8013EC44(0.0f, phi_a1, 90, 2);
+ this->unk_172[0] = 20;
+ this->unk_172[1] = 100;
+ this->unk_172[2] = 20;
+ this->unk_172[3] = 100;
+ this->unk_1AC.y = 300.0f;
+ D_809171F4 = 0x28;
+ D_80917266 = Rand_ZeroFloat(30.0f) + 20.0f;
+ } else {
+ this->unk_172[0] = Rand_ZeroFloat(10.0f) + 3.0f;
+ this->unk_172[2] = 0;
+ this->unk_1AC.y = -70.0f - Rand_ZeroFloat(150.0f);
+ }
+ }
+
+ if (this->unk_172[2] != 0) {
+ D_8091726C = 0.0f;
+ this->unk_188 = 1.6f;
+ this->unk_18C = 6000.0f;
+ Math_ApproachF(&this->actor.speedXZ, 7.5f, 1.0f, 1.0f);
+ Math_ApproachS(&this->unk_168, 0x4E20, 2, 0xFA0);
+ } else {
+ if ((D_80917274 == 0) && (D_80917206 == 2)) {
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.2f);
+ } else {
+ this->unk_188 = 1.4f;
+ this->unk_18C = 5000.0f;
+ Math_ApproachF(&this->actor.speedXZ, 5.0f, 1.0f, 0.5f);
+ }
+
+ if (this->unk_148 == 0) {
+ D_8091726C = 1.0f - (this->unk_1A4 * 0.00899f);
+ } else {
+ D_8091726C = 1.0f - (this->unk_1A4 * 0.00899f * 1.4f);
+ }
+ }
+ } else {
+ if (((this->unk_172[1] & 0xF) == 0) && CHECK_BTN_ALL(input->cur.button, BTN_A) &&
+ (!(this->unk_1A4 >= 60.0f) || (D_809171D4 >= 2000))) {
+ this->unk_14A = Rand_ZeroFloat(30.0f) + 15.0f;
+ this->unk_14C = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ }
+
+ this->unk_188 = 1.0f;
+ this->unk_18C = 4500.0f;
+
+ if (this->unk_148 == 0) {
+ D_8091726C = 1.3f - (this->unk_1A4 * 0.00899f);
+ } else {
+ D_8091726C = 1.3f - (this->unk_1A4 * 0.00899f * 1.4f);
+ }
+
+ Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 0.5f);
+
+ if (this->unk_172[1] == 0) {
+ this->unk_14A = 0;
+
+ if (D_809171D4 < 2000) {
+ this->unk_172[1] = Rand_ZeroFloat(50.0f) + 50.0f;
+ } else if (D_809171D4 < 3000) {
+ this->unk_172[1] = Rand_ZeroFloat(20.0f) + 30.0f;
+ } else {
+ this->unk_172[1] = Rand_ZeroFloat(10.0f) + 25.0f;
+ }
+ }
+ }
+ }
+
+ if (D_809171C8 != 0) {
+ D_8091726C = 0.0f;
+ }
+
+ if (D_80917274 || (D_80917206 != 2)) {
+ if (this->actor.speedXZ < 3.0f) {
+ if (D_809171FE & 8) {
+ sp100.x = -0.8f;
+ } else {
+ sp100.x = -0.75f;
+ }
+ } else if (D_809171FE & 4) {
+ sp100.x = -0.9f;
+ } else {
+ sp100.x = -0.85f;
+ }
+
+ Math_ApproachF(&D_8090CD40, 35.0f, 0.1f, 3.5f);
+ Math_ApproachF(&D_8090CD3C, sp100.x, 0.3f, 0.1f);
+ }
+
+ sReelLinePos[LINE_SEG_COUNT - 1] = this->fishMouthPos;
+ sp10C.x = sReelLinePos[LINE_SEG_COUNT - 1].x - sReelLinePos[LINE_SEG_COUNT - 2].x;
+ sp10C.y = sReelLinePos[LINE_SEG_COUNT - 1].y - sReelLinePos[LINE_SEG_COUNT - 2].y;
+ sp10C.z = sReelLinePos[LINE_SEG_COUNT - 1].z - sReelLinePos[LINE_SEG_COUNT - 2].z;
+
+ if ((SQ(sp10C.x) + SQ(sp10C.y) + SQ(sp10C.z)) > SQ(20.0f)) {
+ Math_ApproachF(&this->actor.world.pos.x, sReelLinePos[LINE_SEG_COUNT - 2].x, 0.2f,
+ 2.0f * (this->actor.speedXZ * 1.5f));
+ Math_ApproachF(&this->actor.world.pos.y, sReelLinePos[LINE_SEG_COUNT - 2].y, 0.2f,
+ 2.0f * (this->actor.speedXZ * 1.5f) * 5.0f * 0.1f);
+ Math_ApproachF(&this->actor.world.pos.z, sReelLinePos[LINE_SEG_COUNT - 2].z, 0.2f,
+ 2.0f * (this->actor.speedXZ * 1.5f));
+ }
+
+ if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (input->rel.stick_y < -30)) {
+ if (D_80917266 < 100) {
+ D_80917266++;
+ }
+ } else {
+ if (D_80917266 != 0) {
+ D_80917266--;
+ }
+ }
+
+ if ((D_8090CD14 < 3) || ((D_809171C8 != 0) && (D_809171D4 > 50)) || (D_809171D4 >= 6000) ||
+ ((D_80917272 == 0) && (D_80917274 == 0)) || (D_80917266 == 0) ||
+ (((D_809171FE & 0x7F) == 0) && (Rand_ZeroOne() < 0.05f) && (D_80917206 != 2))) {
+ // Assignment of OoT's D_80B7A67C here removed in MM
+
+ if ((D_80917272 == 0) && (D_80917274 == 0)) {
+ // Assignment of OoT's D_80B7E086 here removed in MM
+ if (((sLinkAge == 1) && (gSaveContext.save.roomInf[127][2] & 0x400)) ||
+ ((sLinkAge != 1) && (gSaveContext.save.roomInf[127][2] & 0x800))) {
+ // Assignment of OoT's D_80B7A67C here removed in MM, this is now an empty branch
+ }
+ } else {
+ // Assignment of OoT's D_80B7E086 here removed in MM
+ func_8013EC44(0.0f, 1, 3, 1);
+ Audio_QueueSeqCmd(0x100A00FF);
+ }
+
+ this->unk_150 = this->unk_152 = 0;
+ this->unk_19C = 10000;
+ this->unk_19A = 500;
+ this->unk_172[1] = 50;
+ this->unk_172[0] = 0;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 3000.0f;
+
+ if (D_8090CD14 == 4) {
+ D_8090CD14 = 3;
+ }
+
+ D_809171F6 = 50;
+ D_8091726C = 0.5f;
+ this->unk_14A = 0;
+ } else if (this->actor.xzDistToPlayer < 50.0f) {
+ this->unk_150 = 6;
+ this->unk_172[0] = 100;
+ player->unk_B28 = 3;
+ func_8013EC44(0.0f, 1, 3, 1);
+ D_809171D8++;
+ func_800EA0D4(globalCtx, &globalCtx->csCtx);
+ D_8090CD4C = 100;
+ D_80911F48 = 45.0f;
+ D_8090CD14 = 5;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 500.0f;
+ this->unk_194 = 5000.0f;
+
+ if (this->actor.world.pos.y <= WATER_SURFACE_Y(globalCtx)) {
+ func_80903C60(this, 1);
+ func_809033F0(this, globalCtx, true);
+ }
+ goto case_6;
+ }
+ break;
+
+ case_6:
+ case 6:
+ Math_ApproachS(&this->unk_168, 0x2AF8, 2, 0xFA0);
+ Math_ApproachF(&D_80911F48, 15.0f, 0.05f, 0.75f);
+
+ sp10C.x = D_80911F48;
+ if (sLinkAge != 1) {
+ sp10C.y = 30.0f;
+ sp10C.z = 55.0f;
+ } else {
+ sp10C.y = 10.0f;
+ sp10C.z = 50.0f;
+ }
+ Matrix_InsertYRotation_f((player->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&sp10C, &sCameraEye);
+
+ sCameraEye.x += player->actor.world.pos.x;
+ sCameraEye.y += player->actor.world.pos.y;
+ sCameraEye.z += player->actor.world.pos.z;
+
+ sCameraAt = player->actor.world.pos;
+ if (sLinkAge != 1) {
+ sCameraAt.y += 40.0f;
+ } else {
+ sCameraAt.y += 25.0f;
+ }
+
+ if (this->unk_172[0] == 90) {
+ Audio_QueueSeqCmd(0x8924); // changed from 0x924 in OoT
+ D_8090CCFC = 40;
+
+ if (this->unk_148 == 0) {
+ D_8090CCF8 = this->unk_1A4;
+
+ if (D_8090CCF8 >= 75) {
+ D_809171DA = 0x409F;
+ } else if (D_8090CCF8 >= 50) {
+ D_809171DA = 0x4091;
+ } else {
+ D_809171DA = 0x4083;
+ }
+ } else {
+ D_8090CCF8 = 2.0f * this->unk_1A4;
+ D_809171DA = 0x4099;
+ }
+
+ this->unk_1CD = 0;
+ }
+
+ this->unk_158 = -0x4000;
+ this->actor.shape.rot.y = player->actor.shape.rot.y + 0x5000;
+ this->actor.shape.rot.x = this->actor.shape.rot.z = this->unk_15A = this->unk_15C = this->unk_166 = 0;
+
+ sp10C.x = 4.0f;
+ sp10C.y = -10.0f;
+ sp10C.z = 5.0f;
+ Matrix_MultiplyVector3fByState(&sp10C, &sp100);
+ Math_ApproachF(&this->actor.world.pos.x, player->bodyPartsPos[15].x + sp100.x, 1.0f, 6.0f);
+ Math_ApproachF(&this->actor.world.pos.y, player->bodyPartsPos[15].y + sp100.y, 1.0f, 6.0f);
+ Math_ApproachF(&this->actor.world.pos.z, player->bodyPartsPos[15].z + sp100.z, 1.0f, 6.0f);
+
+ D_809101C0 = 188.0f;
+
+ if (this->unk_172[0] <= 50) {
+ switch (this->unk_1CD) {
+ case 0:
+ if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) {
+ if (func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ if (D_8090CCF0 == 0.0f) {
+ D_8090CCF0 = this->unk_1A4;
+ D_809171D0 = this->unk_148;
+ D_809171D2 = D_80917206;
+ Actor_MarkForDeath(&this->actor);
+ } else if ((this->unk_148 == 0) && (D_809171D0 == 0) &&
+ ((s16)this->unk_1A4 < (s16)D_8090CCF0)) {
+ this->unk_1CD = 1;
+ this->unk_172[0] = 0x3C;
+ func_801518B0(globalCtx, 0x4098, NULL);
+ } else {
+ f32 temp1 = D_8090CCF0;
+ s16 temp2 = D_809171D0;
+ D_8090CCF0 = this->unk_1A4;
+ D_809171D0 = this->unk_148;
+ D_809171D2 = D_80917206;
+ this->unk_1A4 = temp1;
+ this->unk_148 = temp2;
+ }
+ }
+ if (this->unk_1CD == 0) {
+ D_8090CD14 = 0;
+ }
+ }
+ }
+ break;
+ case 1:
+ if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) {
+ if (func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ if (globalCtx->msgCtx.choiceIndex != 0) {
+ f32 temp1 = D_8090CCF0;
+ s16 temp2 = D_809171D0;
+ D_8090CCF0 = this->unk_1A4;
+ D_809171D2 = D_80917206;
+ this->unk_1A4 = temp1;
+ this->unk_148 = temp2;
+ }
+ D_8090CD14 = 0;
+ }
+ }
+ break;
+ }
+ }
+
+ if (D_8090CD14 == 0) {
+ if (this->actor.update != NULL) {
+ this->unk_150 = this->unk_152 = 0;
+ this->unk_19C = 10000;
+ this->unk_19A = 500;
+ this->unk_172[1] = 50;
+ this->unk_172[0] = 0;
+ this->unk_188 = 1.0f;
+ this->unk_18C = 2000.0f;
+ SkelAnime_Free(&this->skelAnime, globalCtx);
+
+ if (this->unk_148 == 0) {
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, 0, 0, 0);
+ Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f);
+ } else {
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingLoachSkel, &gFishingLoachAnim, 0, 0,
+ 0);
+ Animation_MorphToLoop(&this->skelAnime, &gFishingLoachAnim, 0.0f);
+ }
+ }
+
+ D_809101C4 = 520.0f;
+ D_809101C0 = 195.0f;
+ Audio_QueueSeqCmd(0x100A00FF);
+ D_809171F6 = 20;
+ D_8090CD4C = 3;
+ }
+ break;
+
+ case 7:
+ this->unk_149 = 50;
+ sp134 = 5;
+ this->unk_1A8 = 12288.0f;
+
+ if (this->actor.params < 104) {
+ this->unk_1AC = sGroupFishes[this->actor.params - 100].pos;
+ D_8090CF18 = 1;
+ } else if (this->actor.params < 108) {
+ this->unk_1AC = sGroupFishes[this->actor.params - 100 + 16].pos;
+ D_8090CF18 = 2;
+ } else {
+ this->unk_1AC = sGroupFishes[this->actor.params - 100 + 32].pos;
+ D_8090CF18 = 3;
+ }
+
+ Math_ApproachF(&this->actor.speedXZ, 5.0f, 1.0f, 1.0f);
+
+ if (sp124 < 20.0f) {
+ Math_ApproachS(&this->unk_168, 0x4E20, 2, 0xFA0);
+
+ if ((this->unk_172[2] == 0) && func_809033F0(this, globalCtx, false)) {
+ func_80903C60(this, Rand_ZeroFloat(1.99f));
+ this->unk_172[2] = Rand_ZeroFloat(20.0f) + 20.0f;
+ }
+ }
+
+ if (this->unk_172[3] == 0) {
+ this->unk_150 = 10;
+ this->unk_152 = 10;
+ } else {
+ func_809038A4(this, input);
+ if (this->actor.xzDistToPlayer < (100.0f * sp118)) {
+ this->unk_152 = this->unk_150 = 0;
+ this->unk_19C = 500;
+ this->unk_19A = 200;
+ this->unk_172[1] = 50;
+ }
+ }
+ break;
+ }
+
+ Math_ApproachS(&this->unk_16A, (Math_SinS(this->unk_154 * 0x1000) * 5000.0f) + 5000.0f, 2, 0x7D0);
+
+ if (this->unk_150 != 6) {
+ if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) {
+ this->unk_188 = 1.5f;
+ this->unk_18C = 5000.0f;
+
+ Math_ApproachS(&this->unk_166, 0, 5, 0x7D0);
+
+ spF4 = spF0 = spFA = 3;
+ spF2 = spEE = 0x2000;
+
+ this->unk_172[2] = 0;
+ this->unk_17C -= 1.0f;
+ } else {
+ Math_ApproachZeroF(&this->unk_17C, 1.0f, 2.0f);
+ if ((this->unk_150 != -1) && (this->unk_150 != -2) && (this->unk_150 != -25)) {
+ this->unk_15E = 0;
+ }
+
+ this->unk_160 = this->unk_162 = 0;
+ spF4 = spF0 = spFA = 4;
+ spF2 = spEE = 0x2000;
+
+ spF6 = EnFishing_SmoothStepToS(&this->actor.world.rot.y, spFC, sp134, this->unk_1A8) * 3.0f;
+ Math_ApproachS(&this->actor.world.rot.x, spFE, sp134, this->unk_1A8 * 0.5f);
+
+ if (spF6 > 0x1F40) {
+ spF6 = 0x1F40;
+ } else if (spF6 < -0x1F40) {
+ spF6 = -0x1F40;
+ }
+
+ if (this->actor.speedXZ >= 3.2f) {
+ Math_ApproachS(&this->unk_166, spF6, 2, 0x4E20);
+ } else {
+ Math_ApproachS(&this->unk_166, spF6, 3, 0xBB8);
+ }
+
+ Actor_SetVelocityXYRotation(&this->actor);
+ }
+
+ Actor_ApplyMovement(&this->actor);
+
+ this->actor.world.pos.y += (this->unk_17C * 1.5f);
+
+ if (1) {}
+
+ if (this->unk_14A != 0) {
+ this->unk_160 = this->unk_14C;
+ this->unk_14A--;
+ if (this->unk_14E != 0) {
+ spF0 = 5;
+ spEE = 0x4000;
+ } else {
+ spF0 = 10;
+ spEE = 0x800;
+ }
+ this->unk_15E = -0x500 - this->actor.shape.rot.x;
+ spF4 = 5;
+ spF2 = 0x4000;
+ } else {
+ this->unk_14E = 0;
+ }
+
+ Math_ApproachS(&this->unk_158, this->unk_15E, spF4, spF2);
+ Math_ApproachS(&this->unk_15A, this->unk_160, spF0, spEE);
+ Math_ApproachS(&this->unk_15C, this->unk_162, spFA, 0x2000);
+
+ if (this->actor.speedXZ <= 0.5f) {
+ Math_ApproachS(&this->actor.shape.rot.x, 0, 10, this->unk_170);
+ Math_ApproachS(&this->unk_170, 0x500, 1, 0x20);
+ } else {
+ Math_ApproachS(&this->actor.shape.rot.x, -this->actor.world.rot.x, 10, 0x1000);
+ this->unk_170 = 0;
+ }
+
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+
+ if ((this->unk_150 != -1) && (this->unk_150 != -2) && (this->unk_150 != -25)) {
+ if ((this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) &&
+ (this->actor.prevPos.y <= WATER_SURFACE_Y(globalCtx))) {
+ func_809033F0(this, globalCtx, true);
+ func_80903C60(this, 1);
+ this->unk_17C = this->actor.velocity.y;
+ this->actor.velocity.y = 0.0f;
+ this->unk_162 = randPlusMinusPoint5Scaled(32768.0f);
+ } else if ((this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) &&
+ (this->actor.prevPos.y >= WATER_SURFACE_Y(globalCtx))) {
+ if (this->unk_17C < -5.0f) {
+ this->unk_17C = -5.0f;
+ }
+ this->actor.world.rot.x = -0xFA0;
+ func_809033F0(this, globalCtx, true);
+ this->unk_1CA = 20;
+ func_80903C60(this, 0);
+ }
+ }
+
+ if ((this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) &&
+ (this->actor.world.pos.y > (WATER_SURFACE_Y(globalCtx) - 10.0f)) && !(this->unk_154 & 1) &&
+ (this->actor.speedXZ > 0.0f)) {
+ Vec3f pos = this->actor.world.pos;
+
+ pos.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &pos, 80.0f, 500.0f, 150, 90);
+ }
+
+ if ((this->actor.speedXZ > 0.0f) || (this->unk_150 == 5)) {
+ f32 velocityY = this->actor.velocity.y;
+
+ spD8 = this->unk_1A4 * 0.1f;
+
+ this->actor.world.pos.y -= spD8;
+ this->actor.prevPos.y -= spD8;
+ this->actor.velocity.y = -1.0f;
+ if (KREG(90) == 0) { // Check added in MM
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 30.0f, 100.0f, 0x45);
+ }
+ this->actor.world.pos.y += spD8;
+ this->actor.prevPos.y += spD8;
+
+ this->actor.velocity.y = velocityY;
+
+ if (this->actor.bgCheckFlags & 8) {
+ this->unk_198 = 20;
+ }
+
+ if (this->actor.bgCheckFlags & 1) {
+ if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) {
+ this->unk_17C = Rand_ZeroFloat(3.0f) + 3.0f;
+ this->actor.velocity.x = this->actor.world.pos.x * -0.003f;
+ this->actor.velocity.z = this->actor.world.pos.z * -0.003f;
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP);
+ func_809036BC(this, globalCtx);
+
+ if (Rand_ZeroOne() < 0.5f) {
+ this->unk_162 = 0x4000;
+ } else {
+ this->unk_162 = -0x4000;
+ }
+
+ if (Rand_ZeroOne() < 0.5f) {
+ this->unk_15E = 0;
+ } else {
+ this->unk_15E = (s16)randPlusMinusPoint5Scaled(32.0f) + 0x8000;
+ }
+
+ this->unk_160 = (s16)randPlusMinusPoint5Scaled(16384.0f);
+ this->unk_188 = 1.0f;
+ this->unk_18C = 5000.0f;
+ this->unk_194 = 5000.0f;
+ } else {
+ this->unk_17C = 0.0f;
+
+ if ((this->unk_150 == 5) && !(this->unk_154 & 1)) {
+ Vec3f pos;
+
+ pos.x = randPlusMinusPoint5Scaled(10.0f) + this->actor.world.pos.x;
+ pos.z = randPlusMinusPoint5Scaled(10.0f) + this->actor.world.pos.z;
+ pos.y = this->actor.floorHeight + 5.0f;
+ EnFishing_SpawnWaterDust(&this->actor.projectedPos, globalCtx->specialEffects, &pos,
+ (this->unk_1A4 * 0.005f) + 0.15f);
+ }
+ }
+ }
+ }
+ }
+
+ if (this->unk_1CA != 0) {
+ s16 i;
+ Vec3f pos;
+ f32 range = (this->unk_1A4 * 0.075f) + 10.0f;
+
+ this->unk_1CA--;
+
+ for (i = 0; i < 2; i++) {
+ pos.x = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.x;
+ pos.y = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.y;
+ pos.z = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.z;
+ EnFishing_SpawnBubble(&this->actor.projectedPos, globalCtx->specialEffects, &pos,
+ Rand_ZeroFloat(0.035f) + 0.04f, 0);
+ }
+ }
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateFish.s")
+#endif
+
+s32 EnFishing_FishOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnFishing* this = THIS;
+
+ if (limbIndex == 13) {
+ rot->z -= this->unk_168 - 11000;
+ } else if ((limbIndex == 2) || (limbIndex == 3)) {
+ rot->y += this->unk_164;
+ } else if (limbIndex == 4) {
+ rot->y += this->unk_16E;
+ } else if (limbIndex == 0xE) {
+ rot->y -= this->unk_16A;
+ } else if (limbIndex == 0xF) {
+ rot->y += this->unk_16A;
+ } else if (limbIndex == 8) {
+ rot->y += this->unk_16C;
+ } else if (limbIndex == 9) {
+ rot->y -= this->unk_16C;
+ }
+
+ return false;
+}
+
+void EnFishing_FishPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ EnFishing* this = THIS;
+
+ if (limbIndex == 13) {
+ Matrix_MultiplyVector3fByState(&sFishMouthOffset, &this->fishMouthPos);
+ }
+}
+
+s32 EnFishing_LoachOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnFishing* this = THIS;
+
+ if (limbIndex == 3) {
+ rot->y += this->unk_1C4[0];
+ } else if (limbIndex == 4) {
+ rot->y += this->unk_1C4[1];
+ } else if (limbIndex == 5) {
+ rot->y += this->unk_1C4[2];
+ }
+
+ return 0;
+}
+
+void EnFishing_LoachPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f sLoachMouthOffset = { 500.0f, 500.0f, 0.0f };
+ EnFishing* this = THIS;
+
+ if (limbIndex == 11) {
+ Matrix_MultiplyVector3fByState(&sLoachMouthOffset, &this->fishMouthPos);
+ }
+}
+
+void EnFishing_DrawFish(Actor* thisx, GlobalContext* globalCtx) {
+ EnFishing* this = THIS;
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(((this->unk_15A + this->actor.shape.rot.y) / 32768.0f) * M_PI, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(((this->unk_158 + this->actor.shape.rot.x) / 32768.0f) * M_PI);
+ Matrix_InsertZRotation_f(((this->unk_15C + this->actor.shape.rot.z) / 32768.0f) * M_PI, MTXMODE_APPLY);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+
+ if (this->unk_148 == 0) {
+ Matrix_InsertYRotation_f((this->unk_164 * (M_PI / 32768)) - (M_PI / 2), MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, this->unk_164 * 10.0f * 0.01f, MTXMODE_APPLY);
+
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, EnFishing_FishOverrideLimbDraw, EnFishing_FishPostLimbDraw,
+ &this->actor);
+ } else {
+ Matrix_InsertTranslation(0.0f, 0.0f, 3000.0f, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(this->unk_164 * (M_PI / 32768), MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, -3000.0f, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(-(M_PI / 2), MTXMODE_APPLY);
+
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, EnFishing_LoachOverrideLimbDraw, EnFishing_LoachPostLimbDraw,
+ &this->actor);
+ }
+}
+
+void EnFishing_HandleReedContact(FishingProp* prop, Vec3f* entityPos) {
+ f32 dx = prop->pos.x - entityPos->x;
+ f32 dz = prop->pos.z - entityPos->z;
+ f32 distXZ = sqrtf(SQ(dx) + SQ(dz));
+
+ if (distXZ <= 20.0f) {
+ prop->rotY = Math_Acot2F(dz, dx);
+
+ Math_ApproachF(&prop->rotX, (20.0f - distXZ) * 0.03f, 0.2f, 0.2f);
+ }
+}
+
+void EnFishing_HandleLilyPadContact(FishingProp* prop, Vec3f* entityPos, u8 fishTimer) {
+ f32 dx = prop->pos.x - entityPos->x;
+ f32 dz = prop->pos.z - entityPos->z;
+ f32 distXZ = sqrtf(SQ(dx) + SQ(dz));
+
+ if (distXZ <= 40.0f) {
+ Math_ApproachS(&prop->lilyPadAngle, Math_FAtan2F(dz, dx), 10, 0x300);
+ }
+
+ if (fishTimer && (distXZ <= 60.0f)) {
+ f32 heightTarget = 1.0f;
+
+ if (fishTimer >= 21) {
+ heightTarget = 1.5f;
+ }
+
+ Math_ApproachF(&prop->lilyPadOffset, heightTarget, 0.1f, 0.2f);
+ }
+}
+
+void EnFishing_UpdatePondProps(GlobalContext* globalCtx) {
+ FishingProp* prop = &sPondProps[0];
+ Player* player = GET_PLAYER(globalCtx);
+ Actor* actor;
+ s16 i;
+
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (prop->type != FS_PROP_NONE) {
+ prop->shouldDraw = false;
+ prop->timer++;
+
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &prop->pos, &prop->projectedPos, &sProjectedW);
+
+ if ((prop->projectedPos.z < prop->drawDistance) &&
+ (fabsf(prop->projectedPos.x) < (100.0f + prop->projectedPos.z))) {
+ prop->shouldDraw = true;
+ }
+
+ if ((prop->projectedPos.z < 500.0f) && (fabsf(prop->projectedPos.x) < (100.0f + prop->projectedPos.z))) {
+ if (prop->type == FS_PROP_REED) {
+ EnFishing_HandleReedContact(prop, &player->actor.world.pos);
+
+ actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first;
+ while (actor != NULL) {
+ if (!((actor->id == ACTOR_EN_FISHING) && (actor->params >= 100))) {
+ actor = actor->next;
+ } else {
+ EnFishing_HandleReedContact(prop, &actor->world.pos);
+ actor = actor->next;
+ }
+ }
+
+ Math_ApproachZeroF(&prop->rotX, 0.05f, 0.05f);
+ } else if (prop->type == FS_PROP_LILY_PAD) {
+ EnFishing_HandleLilyPadContact(prop, &player->actor.world.pos, 0);
+
+ actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first;
+ while (actor != NULL) {
+ if (!((actor->id == ACTOR_EN_FISHING) && (actor->params >= 100))) {
+ actor = actor->next;
+ } else {
+ EnFishing_HandleLilyPadContact(prop, &actor->world.pos, ((EnFishing*)actor)->unk_149);
+ actor = actor->next;
+ }
+ }
+
+ Math_ApproachS(&prop->lilyPadAngle, 0, 20, 80);
+ prop->pos.y =
+ (Math_SinS(prop->timer * 0x1000) * prop->lilyPadOffset) + (WATER_SURFACE_Y(globalCtx) + 2.0f);
+ Math_ApproachZeroF(&prop->lilyPadOffset, 0.1f, 0.02f);
+ }
+ }
+ }
+
+ prop++;
+ }
+
+ if (sCameraId == MAIN_CAM) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &sFishingMain->collider.base);
+ }
+}
+
+void EnFishing_DrawPondProps(GlobalContext* globalCtx) {
+ u8 flag = 0;
+ FishingProp* prop = &sPondProps[0];
+ s16 i;
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_StatePush();
+
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (prop->type == FS_PROP_REED) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingReedSetupDL);
+ flag++;
+ }
+
+ if (prop->shouldDraw) {
+ Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
+ Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(prop->rotX);
+ Matrix_InsertYRotation_f(prop->reedAngle, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingReedVtxDL);
+ }
+ }
+
+ prop++;
+ }
+
+ prop = &sPondProps[0];
+ flag = 0;
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (prop->type == FS_PROP_WOOD_POST) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingWoodPostSetupDL);
+ flag++;
+ }
+
+ if (prop->shouldDraw) {
+ Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
+ Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingWoodPostVtxDL);
+ }
+ }
+
+ prop++;
+ }
+
+ prop = &sPondProps[0];
+ flag = 0;
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (prop->type == FS_PROP_LILY_PAD) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gFishingLilyPadSetupDL);
+ flag++;
+ }
+
+ if (prop->shouldDraw) {
+ Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
+ Matrix_Scale(prop->scale, 1.0f, prop->scale, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(prop->lilyPadAngle * (M_PI / 32768), MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 0.0f, 20.0f, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingLilyPadVtxDL);
+ }
+ }
+
+ prop++;
+ }
+
+ prop = &sPondProps[0];
+ flag = 0;
+ for (i = 0; i < POND_PROP_COUNT; i++) {
+ if (prop->type == FS_PROP_ROCK) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingRockSetupDL);
+ flag++;
+ }
+
+ if (prop->shouldDraw) {
+ Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
+ Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingRockVtxDL);
+ }
+ }
+
+ prop++;
+ }
+
+ Matrix_StatePop();
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnFishing_UpdateGroupFishes(GlobalContext* globalCtx) {
+ s16 groupContactFlags = 0;
+ Player* player = GET_PLAYER(globalCtx);
+ FishingGroupFish* fish = &sGroupFishes[0];
+ f32 dy;
+ f32 dx;
+ f32 dist;
+ f32 dz;
+ f32 offset;
+ s16 groupIndex;
+ s16 groupFlag;
+ f32 spD8;
+ s16 spD6;
+ s16 spD4;
+ s16 target;
+ s16 i;
+ Vec3f basePos[3];
+ Vec3f ripplePos;
+ Vec3f* refPos;
+ f32 temp1;
+ f32 temp2;
+
+ if ((D_80917264 != 0) || (D_8090CD14 == 4)) {
+ refPos = &sLurePos;
+ } else {
+ refPos = &player->actor.world.pos;
+ }
+
+ basePos[0].x = __sinf(sFishGroupAngle1) * 720.0f;
+ basePos[0].y = -35.0f;
+ basePos[0].z = __cosf(sFishGroupAngle1) * 720.0f;
+
+ temp1 = refPos->x - basePos[0].x;
+ temp2 = refPos->z - basePos[0].z;
+
+ if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) {
+ sFishGroupAngle1 += 0.3f;
+ groupContactFlags |= 1;
+ } else if (D_8090CF18 != 0) {
+ sFishGroupAngle1 += 0.05f;
+ basePos[0].y = WATER_SURFACE_Y(globalCtx) - 5.0f;
+ } else {
+ Math_ApproachF(&sFishGroupAngle1, 0.7f, 1.0f, 0.001f);
+ }
+
+ basePos[1].x = __sinf(sFishGroupAngle2) * 720.0f;
+ basePos[1].y = -35.0f;
+ basePos[1].z = __cosf(sFishGroupAngle2) * 720.0f;
+
+ temp1 = refPos->x - basePos[1].x;
+ temp2 = refPos->z - basePos[1].z;
+
+ if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) {
+ sFishGroupAngle2 -= 0.3f;
+ groupContactFlags |= 2;
+ } else if (D_8090CF18 != 0) {
+ sFishGroupAngle2 -= 0.05f;
+ basePos[1].y = WATER_SURFACE_Y(globalCtx) - 5.0f;
+ } else {
+ Math_ApproachF(&sFishGroupAngle2, 2.3f, 1.0f, 0.001f);
+ }
+
+ basePos[2].x = __sinf(sFishGroupAngle3) * 720.0f;
+ basePos[2].y = -35.0f;
+ basePos[2].z = __cosf(sFishGroupAngle3) * 720.0f;
+
+ temp1 = refPos->x - basePos[2].x;
+ temp2 = refPos->z - basePos[2].z;
+
+ if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) {
+ sFishGroupAngle3 -= 0.3f;
+ groupContactFlags |= 4;
+ } else if (D_8090CF18 != 0) {
+ sFishGroupAngle3 -= 0.05f;
+ basePos[2].y = WATER_SURFACE_Y(globalCtx) - 5.0f;
+ } else {
+ Math_ApproachF(&sFishGroupAngle3, 4.6f, 1.0f, 0.001f);
+ }
+
+ if (sLinkAge == 1) {
+ spD8 = 0.8f;
+ } else {
+ spD8 = 1.0f;
+ }
+
+ for (i = 0; i < GROUP_FISH_COUNT; i++) {
+ if (fish->type != FS_GROUP_FISH_NONE) {
+ fish->timer++;
+
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &fish->pos, &fish->projectedPos, &sProjectedW);
+
+ if ((fish->projectedPos.z < 400.0f) && (fabsf(fish->projectedPos.x) < (100.0f + fish->projectedPos.z))) {
+ fish->shouldDraw = true;
+ } else {
+ fish->shouldDraw = false;
+ }
+
+ if (i <= 20) {
+ groupIndex = 0;
+ groupFlag = 1;
+ } else if (i <= 40) {
+ groupIndex = 1;
+ groupFlag = 2;
+ } else {
+ groupIndex = 2;
+ groupFlag = 4;
+ }
+
+ dx = fish->unk_10.x - fish->pos.x;
+ dy = fish->unk_10.y - fish->pos.y;
+ dz = fish->unk_10.z - fish->pos.z;
+ spD4 = Math_FAtan2F(dz, dx);
+ dist = sqrtf(SQ(dx) + SQ(dz));
+ spD6 = Math_FAtan2F(dist, dy);
+
+ if ((dist < 10.0f) || (((fish->timer % 32) == 0) && (Rand_ZeroOne() > 0.5f))) {
+ fish->unk_10.y = basePos[groupIndex].y + randPlusMinusPoint5Scaled(10.0f);
+
+ if (D_8090CF18 != 0) {
+ fish->unk_10.x = basePos[groupIndex].x + randPlusMinusPoint5Scaled(200.0f);
+ fish->unk_10.z = basePos[groupIndex].z + randPlusMinusPoint5Scaled(200.0f);
+ } else {
+ fish->unk_10.x = basePos[groupIndex].x + randPlusMinusPoint5Scaled(100.0f);
+ fish->unk_10.z = basePos[groupIndex].z + randPlusMinusPoint5Scaled(100.0f);
+ }
+
+ ripplePos = fish->pos;
+ ripplePos.y = WATER_SURFACE_Y(globalCtx);
+ EnFishing_SpawnRipple(&fish->projectedPos, globalCtx->specialEffects, &ripplePos, 20.0f,
+ Rand_ZeroFloat(50.0f) + 100.0f, 150, 90);
+
+ if (fish->unk_28 < 1.5f) {
+ fish->unk_28 = 1.5f;
+ }
+
+ fish->unk_34 = 1.5f;
+ fish->unk_38 = 1.0f;
+ }
+
+ target = EnFishing_SmoothStepToS(&fish->unk_3E, spD4, 5, 0x4000) * 3.0f;
+ if (target > 0x1F40) {
+ target = 0x1F40;
+ } else if (target < -0x1F40) {
+ target = -0x1F40;
+ }
+
+ Math_ApproachS(&fish->unk_42, target, 3, 0x1388);
+
+ offset = fish->unk_42 * -0.0001f;
+ Math_ApproachS(&fish->unk_3C, spD6, 5, 0x4000);
+
+ if (groupContactFlags & groupFlag) {
+ fish->unk_38 = 1.0f;
+ fish->unk_28 = 6.0f;
+ fish->unk_34 = 2.0f;
+ }
+
+ if (D_8090CF18 != 0) {
+ fish->unk_38 = 1.0f;
+ fish->unk_28 = 4.0f;
+ fish->unk_34 = 2.0f;
+ }
+
+ Math_ApproachF(&fish->unk_28, 0.75f, 1.0f, 0.05f);
+
+ temp1 = fish->unk_28 * spD8;
+ temp2 = Math_CosS(fish->unk_3C) * temp1;
+
+ fish->pos.x += temp2 * Math_SinS(fish->unk_3E);
+ fish->pos.y += temp1 * Math_SinS(fish->unk_3C);
+ fish->pos.z += temp2 * Math_CosS(fish->unk_3E);
+
+ if (fish->shouldDraw) {
+ Math_ApproachF(&fish->unk_34, 1.0f, 1.0f, 0.1f);
+ Math_ApproachF(&fish->unk_38, 0.4f, 1.0f, 0.04f);
+ fish->unk_30 += fish->unk_34;
+ fish->unk_2C = (__cosf(fish->unk_30) * fish->unk_38) + offset;
+ }
+ }
+
+ fish++;
+ }
+
+ D_8090CF18 = 0;
+}
+
+void EnFishing_DrawGroupFishes(GlobalContext* globalCtx) {
+ u8 flag = 0;
+ FishingGroupFish* fish = &sGroupFishes[0];
+ f32 scale;
+ s16 i;
+ s32 pad;
+
+ if (sLinkAge == 1) {
+ scale = 0.003325f;
+ } else {
+ scale = 0.00475f;
+ }
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < GROUP_FISH_COUNT; i++) {
+ if (fish->type != FS_GROUP_FISH_NONE) {
+ if (flag == 0) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingGroupFishSetupDL);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 155, 155, 155, 255);
+ flag++;
+ }
+
+ if (fish->shouldDraw) {
+ Matrix_InsertTranslation(fish->pos.x, fish->pos.y, fish->pos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(((f32)fish->unk_3E * M_PI) / 32768.0f, MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis((-(f32)fish->unk_3C * M_PI) / 32768.0f);
+ Matrix_Scale(fish->unk_2C * scale, scale, scale, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gFishingGroupFishVtxDL);
+ }
+ }
+ fish++;
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+static u16 D_8090D638[] = { 0x4096, 0x408D, 0x408E, 0x408F, 0x4094, 0x4095 };
+
+void EnFishing_HandleOwnerDialog(EnFishing* this, GlobalContext* globalCtx) {
+ switch (this->unk_154) {
+ case 0:
+ if (D_809171FC == 0) {
+ if (sLinkAge != 1) {
+ if ((gSaveContext.save.roomInf[127][2] & 0x100) && !(gSaveContext.save.roomInf[127][2] & 0x200)) {
+ this->actor.textId = 0x4093;
+ } else {
+ this->actor.textId = 0x407B;
+ }
+ } else {
+ this->actor.textId = 0x407B;
+ }
+ } else if (D_8090CD0C == 0) {
+ this->actor.textId = 0x4084;
+ } else {
+ this->actor.textId = 0x4097;
+ }
+
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ if (D_809171FC == 0) {
+ this->unk_154 = 1;
+ if (sLinkAge != 1) {
+ gSaveContext.save.roomInf[127][2] |= 0x200;
+ } else {
+ gSaveContext.save.roomInf[127][2] |= 0x100;
+ }
+ } else {
+ this->unk_154 = 10;
+ }
+ } else {
+ func_800B8614(&this->actor, globalCtx, 100.0f);
+ }
+ break;
+
+ case 1:
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ if (gSaveContext.save.playerData.rupees >= 20) {
+ Rupees_ChangeBy(-20);
+ if (func_8013EE04() == 0) {
+ this->actor.textId = 0x407C;
+ } else {
+ this->actor.textId = 0x407D;
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ this->unk_154 = 2;
+ } else {
+ func_80151938(globalCtx, 0x407E);
+ this->unk_154 = 3;
+ }
+ break;
+ case 1:
+ func_80151938(globalCtx, 0x2D);
+ this->unk_154 = 3;
+ break;
+ }
+ }
+ break;
+
+ case 2:
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ func_80151938(globalCtx, 0x407F);
+ this->unk_154 = 4;
+ }
+ break;
+
+ case 3:
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ this->unk_154 = 0;
+ }
+ if (func_80152498(&globalCtx->msgCtx) == 6) {
+ this->unk_154 = 0;
+ }
+ break;
+
+ case 4:
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ D_8090CCF8 = D_809171CC;
+ func_80151938(globalCtx, 0x4080);
+ this->unk_154 = 5;
+ break;
+ case 1:
+ func_80151938(globalCtx, 0x407F);
+ break;
+ }
+ }
+ break;
+
+ case 5:
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ globalCtx->interfaceCtx.unk_27E = 1;
+ globalCtx->startPlayerFishing(globalCtx);
+ D_809171FC = 1;
+ D_8090CD04 = 20;
+ this->unk_154 = 0;
+
+ if ((gSaveContext.save.roomInf[127][2] & 0xFF0000) < 0xFF0000) {
+ gSaveContext.save.roomInf[127][2] += 0x10000;
+ }
+ }
+ break;
+
+ case 10:
+ if (D_8090CD0C != 0) {
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ func_80151938(globalCtx, 0x40B2);
+ D_8090CD08 = 1;
+ D_8090CD0C = 0;
+ this->unk_154 = 20;
+ break;
+ case 1:
+ this->unk_154 = 0;
+ break;
+ }
+ }
+ } else {
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ if (D_8090CCF0 == 0.0f) {
+ this->actor.textId = 0x408C;
+ this->unk_154 = 20;
+ } else if (D_809171D0 == 0) {
+ D_8090CCF8 = D_8090CCF0;
+ if ((s16)D_809171CC < (s16)D_8090CCF0) {
+ if (D_809171D2 == 2) {
+ this->actor.textId = 0x40B0;
+ } else {
+ this->actor.textId = 0x4086;
+ }
+ this->unk_154 = 11;
+ } else {
+ this->actor.textId = 0x408B;
+ this->unk_154 = 20;
+ }
+ } else {
+ this->actor.textId = 0x409B;
+ this->unk_154 = 11;
+ }
+ func_80151938(globalCtx, this->actor.textId);
+ break;
+ case 1:
+ if (D_8090CD00 > 36000) {
+ D_8090CD00 = 30000;
+ func_80151938(globalCtx, 0x4088);
+ } else {
+ if (D_809171CA == 0) {
+ if (D_809171D6 == 0) {
+ D_809171D6++;
+ }
+ }
+
+ if ((D_80917206 == 2) && (D_8090D638[D_809171D6] == 0x408D)) {
+ func_80151938(globalCtx, 0x40AF);
+ } else {
+ func_80151938(globalCtx, D_8090D638[D_809171D6]);
+ }
+
+ D_809171D6++;
+
+ if (sLinkAge != 1) {
+ if (D_809171D6 >= 6) {
+ D_809171D6 = 0;
+ }
+ } else {
+ if (D_809171D6 >= 4) {
+ D_809171D6 = 0;
+ }
+ }
+ }
+ this->unk_154 = 0;
+ break;
+ case 2:
+ if (D_809171D8 == 0) {
+ func_80151938(globalCtx, 0x4085);
+ } else if (sLinkAge == 1) {
+ func_80151938(globalCtx, 0x4092);
+ }
+ this->unk_154 = 22;
+ break;
+ }
+ }
+ }
+ break;
+
+ case 11:
+ if (((func_80152498(&globalCtx->msgCtx) == 5) || !func_80152498(&globalCtx->msgCtx)) &&
+ func_80147624(globalCtx)) {
+ s32 getItemId;
+
+ func_801477B4(globalCtx);
+
+ if (D_809171D0 == 0) {
+ D_809171CC = D_8090CCF0;
+ D_8090CCF0 = 0.0f;
+
+ if (sLinkAge == 1) {
+ f32 temp;
+
+ gSaveContext.save.roomInf[127][2] &= 0xFFFFFF00;
+ gSaveContext.save.roomInf[127][2] |= ((s16)D_809171CC & 0x7F);
+
+ temp = (gSaveContext.save.roomInf[127][2] & 0x7F000000) >> 0x18;
+ if (temp < D_809171CC) {
+ gSaveContext.save.roomInf[127][2] &= 0xFFFFFF;
+ gSaveContext.save.roomInf[127][2] |= ((s16)D_809171CC & 0x7F) << 0x18;
+
+ if (D_809171D2 == 2) {
+ gSaveContext.save.roomInf[127][2] |= 0x80000000;
+ }
+ }
+
+ if (D_809171D2 == 2) {
+ gSaveContext.save.roomInf[127][2] |= 0x80;
+ this->unk_154 = 0;
+ break;
+ }
+ } else {
+ gSaveContext.save.roomInf[127][2] &= 0xFFFFFF;
+ gSaveContext.save.roomInf[127][2] |= ((s16)D_809171CC & 0x7F) << 0x18;
+
+ if (D_809171D2 == 2) {
+ gSaveContext.save.roomInf[127][2] |= 0x80000000;
+ this->unk_154 = 0;
+ break;
+ }
+ }
+
+ if (D_809171CC >= 60.0f) {
+ getItemId = GI_RUPEE_PURPLE;
+ } else if (D_809171CC >= 50.0f) {
+ getItemId = GI_RUPEE_10;
+ } else if (D_809171CC >= 40.0f) {
+ getItemId = GI_RUPEE_BLUE;
+ } else {
+ getItemId = GI_RUPEE_GREEN;
+ }
+
+ if (sLinkAge == 1) {
+ if ((D_809171CC >= 50.0f) && !(gSaveContext.save.roomInf[127][2] & 0x400)) {
+ gSaveContext.save.roomInf[127][2] |= 0x400;
+ getItemId = GI_HEART_PIECE;
+ sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f;
+ }
+ } else {
+ if ((D_809171CC >= 60.0f) && !(gSaveContext.save.roomInf[127][2] & 0x800)) {
+ gSaveContext.save.roomInf[127][2] |= 0x800;
+ getItemId = GI_SCALE_GOLD;
+ sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f;
+ }
+ }
+ } else {
+ getItemId = GI_RUPEE_PURPLE;
+ D_8090CCF0 = 0.0f;
+ }
+
+ this->actor.parent = NULL;
+ func_800B8A1C(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f);
+ this->unk_154 = 23;
+ }
+ break;
+
+ case 20:
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ this->unk_154 = 0;
+ }
+ break;
+
+ case 21:
+ if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ this->unk_154 = 0;
+ break;
+ case 1:
+ if (D_809171D8 == 0) {
+ func_80151938(globalCtx, 0x4085);
+ } else if (sLinkAge == 1) {
+ func_80151938(globalCtx, 0x4092);
+ }
+ this->unk_154 = 22;
+ break;
+ }
+ }
+ break;
+
+ case 22:
+ if (!func_80152498(&globalCtx->msgCtx)) {
+ this->unk_154 = 0;
+ if (D_8090CD0C != 0) {
+ D_8090CD08 = 1;
+ D_8090CD0C = 0;
+ }
+ D_809171FC = 0;
+ globalCtx->interfaceCtx.unk_27E = 0;
+ }
+ break;
+
+ case 23:
+ D_8090CCF4 = false;
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ this->unk_154 = 24;
+ } else {
+ func_800B8A1C(&this->actor, globalCtx, GI_SCALE_GOLD, 2000.0f, 1000.0f);
+ }
+ break;
+
+ case 24:
+ D_8090CCF4 = false;
+ if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) {
+ if (D_809171D0 == 0) {
+ this->unk_154 = 0;
+ } else {
+ func_801518B0(globalCtx, 0x409C, NULL);
+ this->unk_154 = 20;
+ }
+ }
+ break;
+ }
+}
+
+static s16 D_8090D644[] = { 0, 1, 2, 2, 1 };
+
+static Vec3f sStreamSoundPos = { 670.0f, 0.0f, -600.0f };
+
+static Vec3s sSinkingLureLocationPos[] = {
+ { -364, -30, -269 },
+ { 1129, 3, -855 },
+ { -480, 0, -1055 },
+ { 553, -48, -508 },
+};
+
+#ifdef NON_MATCHING
+// Register flip around target near the end of the function
+void EnFishing_UpdateOwner(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnFishing* this = THIS;
+ Vec3f sp114;
+ Vec3f sp108;
+ Vec3f spFC;
+ s16 headRotTarget;
+ s16 playerShadowAlpha;
+ f32 target;
+ f32 camAtFraction;
+ f32 lureDistXZ;
+ s32 pad;
+ Player* player = GET_PLAYER(globalCtx);
+ Input* input = CONTROLLER1(globalCtx);
+ Camera* camera;
+
+ playerShadowAlpha = player->actor.shape.shadowAlpha;
+
+ if ((SQ(player->actor.world.pos.x) + SQ(player->actor.world.pos.z)) < SQ(920.0f)) {
+ Math_ApproachS(&playerShadowAlpha, 0, 1, 40);
+ } else {
+ Math_ApproachS(&playerShadowAlpha, 200, 1, 40);
+ }
+
+ player->actor.shape.shadowAlpha = playerShadowAlpha;
+
+ SkelAnime_Update(&this->skelAnime);
+
+ if ((D_8090CD04 != 0) || func_80152498(&globalCtx->msgCtx)) {
+ this->actor.flags &= ~1;
+ } else {
+ this->actor.flags |= 0x21;
+ }
+
+ if ((this->actor.xzDistToPlayer < 120.0f) || func_80152498(&globalCtx->msgCtx)) {
+ headRotTarget = this->actor.shape.rot.y - this->actor.yawTowardsPlayer;
+ } else {
+ headRotTarget = 0;
+ }
+
+ if (headRotTarget > 0x2710) {
+ headRotTarget = 0x2710;
+ } else if (headRotTarget < -0x2710) {
+ headRotTarget = -0x2710;
+ }
+
+ Math_ApproachS(&this->unk_15C, headRotTarget, 3, 0x1388);
+
+ if (((globalCtx->gameplayFrames % 32) == 0) && (Rand_ZeroOne() < 0.3f)) {
+ this->unk_15A = 4;
+ }
+
+ this->unk_158 = D_8090D644[this->unk_15A];
+
+ if (this->unk_15A != 0) {
+ this->unk_15A--;
+ }
+
+ if (D_8090CD04 != 0) {
+ D_8090CD04--;
+ }
+
+ if ((D_8090CD0C == 0) && (D_80917206 != 2) && (D_8090CD14 > 0) && (D_8090CD08 == 1) && (D_8090CD04 == 0)) {
+ f32 dx = sOwnerHeadPos.x - sLurePos.x;
+ f32 dy = sOwnerHeadPos.y - sLurePos.y;
+ f32 dz = sOwnerHeadPos.z - sLurePos.z;
+
+ if ((sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 25.0f)) {
+ D_8090CD08 = 0;
+ D_8090CD0C = 1;
+ func_801518B0(globalCtx, 0x4087, NULL);
+ }
+ }
+
+ if (D_8090CD08 == 0) {
+ gSaveContext.save.roomInf[127][2] |= 0x1000;
+ } else if (D_8090CD08 == 1) {
+ gSaveContext.save.roomInf[127][2] &= ~0x1000;
+ }
+
+ if (D_8090CCFC != 0) {
+ D_8090CCFC--;
+ if (D_8090CCFC == 0) {
+ func_801518B0(globalCtx, D_809171DA, NULL);
+ }
+ }
+
+ EnFishing_HandleOwnerDialog(this, globalCtx);
+
+ D_809101C8 = 0.0015f;
+ D_8090CD00++;
+
+ if ((D_809171FC != 0) && D_8090CCF4) {
+ EnFishing_UpdateLure(this, globalCtx);
+ }
+
+ EnFishing_UpdateEffects(globalCtx->specialEffects, globalCtx);
+ EnFishing_UpdatePondProps(globalCtx);
+ EnFishing_UpdateGroupFishes(globalCtx);
+
+ if ((D_809171FC != 0) && (D_8090CD4C == 0) && (player->actor.world.pos.z > 1360.0f) &&
+ (fabsf(player->actor.world.pos.x) < 25.0f)) {
+ player->actor.world.pos.z = 1360.0f;
+ player->actor.speedXZ = 0.0f;
+
+ if (D_8090CD50 == 0) {
+ D_8090CD4C = 10;
+ }
+ }
+
+ if ((sSinkingLureLocation != 0) &&
+ (fabsf(player->actor.world.pos.x - sSinkingLureLocationPos[sSinkingLureLocation - 1].x) < 25.0f) &&
+ (fabsf(player->actor.world.pos.y - sSinkingLureLocationPos[sSinkingLureLocation - 1].y) < 10.0f) &&
+ (fabsf(player->actor.world.pos.z - sSinkingLureLocationPos[sSinkingLureLocation - 1].z) < 25.0f)) {
+ sSinkingLureLocation = 0;
+ D_8090CD4C = 20;
+ func_8013EC44(0.0f, 150, 10, 10);
+ play_sound(NA_SE_SY_TRE_BOX_APPEAR);
+ Audio_QueueSeqCmd(0x101400FF);
+ }
+
+ if (D_8090CD50 != 0) {
+ D_8090CD50--;
+ }
+
+ switch (D_8090CD4C) {
+ case 0:
+ break;
+
+ case 1:
+ sCameraId = func_801694DC(globalCtx);
+ func_80169590(globalCtx, MAIN_CAM, 1);
+ func_80169590(globalCtx, sCameraId, 7);
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
+ sCameraEye.x = camera->eye.x;
+ sCameraEye.y = camera->eye.y;
+ sCameraEye.z = camera->eye.z;
+ sCameraAt.x = camera->at.x;
+ sCameraAt.y = camera->at.y;
+ sCameraAt.z = camera->at.z;
+ D_8090CD4C = 2;
+ Interface_ChangeAlpha(12);
+ D_80911F4C = 0.0f;
+ // fallthrough
+
+ case 2:
+ ShrinkWindow_SetLetterboxTarget(0x1B);
+
+ spFC.x = sLurePos.x - player->actor.world.pos.x;
+ spFC.z = sLurePos.z - player->actor.world.pos.z;
+ lureDistXZ = sqrtf(SQ(spFC.x) + SQ(spFC.z));
+ Matrix_InsertYRotation_f(Math_Acot2F(spFC.z, spFC.x), MTXMODE_NEW);
+
+ sp114.x = 0.0f;
+ sp114.y = 0.0f;
+ sp114.z = 100.0f;
+ Matrix_MultiplyVector3fByState(&sp114, &spFC);
+
+ if (D_8090CD14 == 1) {
+ camAtFraction = 0.2f;
+ } else {
+ camAtFraction = 0.1f;
+ }
+
+ Math_ApproachF(&sCameraAt.x, sLurePos.x, camAtFraction, fabsf(spFC.x) * D_80911F4C);
+ Math_ApproachF(&sCameraAt.y, sLurePos.y, camAtFraction, 50.0f * D_80911F4C);
+ Math_ApproachF(&sCameraAt.z, sLurePos.z, camAtFraction, fabsf(spFC.z) * D_80911F4C);
+
+ sp114.x = 0.0f - D_80911F50;
+ if (sLinkAge != 1) {
+ sp114.y = 80.0f;
+ } else {
+ sp114.y = 55.0f;
+ }
+ sp114.z = -80.0f;
+
+ Matrix_MultiplyVector3fByState(&sp114, &sp108);
+ sp108.x += player->actor.world.pos.x;
+ sp108.y += player->actor.world.pos.y;
+ sp108.z += player->actor.world.pos.z;
+
+ Math_ApproachF(&D_80911F50, 30.0f, 0.1f, 0.4f);
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_Z)) {
+ if ((D_809171DC >= 0) && (D_80917272 == 0)) {
+ D_809171DC++;
+
+ if (D_809171DC >= 4) {
+ D_809171DC = 0;
+ }
+
+ if ((D_809171DC == 0) || (D_809171DC == 3)) {
+ play_sound(NA_SE_SY_CAMERA_ZOOM_DOWN);
+ } else {
+ play_sound(NA_SE_SY_CAMERA_ZOOM_UP);
+ }
+ }
+ }
+
+ if (D_8090CD14 >= 3) {
+ if (lureDistXZ < 110.0f) {
+ D_809171DC = -1;
+ } else if ((lureDistXZ > 300.0f) && (D_809171DC < 0)) {
+ D_809171DC = 0;
+ }
+ }
+
+ if (D_809171DC > 0) {
+ f32 dist;
+ f32 offset;
+ f32 factor;
+
+ dist = sqrtf(SQ(spFC.x) + SQ(spFC.z)) * 0.001f;
+ if (dist > 1.0f) {
+ dist = 1.0f;
+ }
+ if (D_809171DC == 2) {
+ offset = 0.3f;
+ } else {
+ offset = 0.1f;
+ }
+ factor = 0.4f + offset + (dist * 0.4f);
+
+ sp108.x += (sLurePos.x - sp108.x) * factor;
+ sp108.y += ((sLurePos.y - sp108.y) * factor) + 20.0f;
+ sp108.z += (sLurePos.z - sp108.z) * factor;
+ D_809101C8 = 0.0005000001f;
+ }
+
+ sp114.x = 0.0f;
+ sp114.y = 0.0f;
+ sp114.z = 100.0f;
+ Matrix_MultiplyVector3fByState(&sp114, &spFC);
+
+ Math_ApproachF(&sCameraEye.x, sp108.x, 0.3f, fabsf(spFC.x) * D_80911F4C);
+ Math_ApproachF(&sCameraEye.y, sp108.y, 0.3f, 20.0f * D_80911F4C);
+ Math_ApproachF(&sCameraEye.z, sp108.z, 0.3f, fabsf(spFC.z) * D_80911F4C);
+ break;
+
+ case 3: {
+ Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM);
+
+ camera->eye = sCameraEye;
+ camera->eyeNext = sCameraEye;
+ camera->at = sCameraAt;
+ }
+ func_80169AFC(globalCtx, sCameraId, 0);
+ func_800EA0EC(globalCtx, &globalCtx->csCtx);
+ D_8090CD4C = 0;
+ sCameraId = MAIN_CAM;
+ func_800F6834(globalCtx, 0);
+ globalCtx->envCtx.unk_8C.fogNear = 0;
+ player->unk_B28 = -5;
+ D_80917200 = 5;
+ break;
+
+ case 10:
+ func_800EA0D4(globalCtx, &globalCtx->csCtx);
+ sCameraId = func_801694DC(globalCtx);
+ func_80169590(globalCtx, MAIN_CAM, 1);
+ func_80169590(globalCtx, sCameraId, 7);
+ func_800B7298(globalCtx, &this->actor, 4);
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
+ sCameraEye.x = camera->eye.x;
+ sCameraEye.y = camera->eye.y;
+ sCameraEye.z = camera->eye.z;
+ sCameraAt.x = camera->at.x;
+ sCameraAt.y = camera->at.y;
+ sCameraAt.z = camera->at.z;
+ func_801518B0(globalCtx, 0x409E, NULL);
+ D_8090CD4C = 11;
+ func_8013EC44(0.0f, 150, 10, 10);
+ // fallthrough
+
+ case 11:
+ player->actor.world.pos.z = 1360.0f;
+ player->actor.speedXZ = 0.0f;
+
+ if (!func_80152498(&globalCtx->msgCtx)) {
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
+
+ camera->eye = sCameraEye;
+ camera->eyeNext = sCameraEye;
+ camera->at = sCameraAt;
+ func_80169AFC(globalCtx, sCameraId, 0);
+ func_800EA0EC(globalCtx, &globalCtx->csCtx);
+ func_800B7298(globalCtx, &this->actor, 6);
+ D_8090CD4C = 0;
+ sCameraId = MAIN_CAM;
+ D_8090CD50 = 30;
+ func_800F6834(globalCtx, 0);
+ globalCtx->envCtx.unk_8C.fogNear = 0;
+ }
+ break;
+
+ case 20:
+ func_800EA0D4(globalCtx, &globalCtx->csCtx);
+ sCameraId = func_801694DC(globalCtx);
+ func_80169590(globalCtx, MAIN_CAM, 1);
+ func_80169590(globalCtx, sCameraId, 7);
+ func_800B7298(globalCtx, &this->actor, 4);
+ camera = Play_GetCamera(globalCtx, MAIN_CAM);
+ sCameraEye.x = camera->eye.x;
+ sCameraEye.y = camera->eye.y;
+ sCameraEye.z = camera->eye.z;
+ sCameraAt.x = camera->at.x;
+ sCameraAt.y = camera->at.y;
+ sCameraAt.z = camera->at.z;
+ func_801518B0(globalCtx, 0x409A, NULL);
+ D_8090CD4C = 21;
+ D_80911F48 = 45.0f;
+ D_8090CD50 = 10;
+ // fallthrough
+
+ case 21:
+ if ((D_8090CD50 == 0) && func_80147624(globalCtx)) {
+ D_8090CD4C = 22;
+ D_8090CD50 = 40;
+ // func_800B7298 call removed in MM
+ D_80911F64 = 0.0f;
+ }
+ break;
+
+ case 22:
+ if (D_8090CD50 == 30) {
+ Audio_QueueSeqCmd(0x8922); // changed from 0x922 to 0x8922 in MM
+ }
+
+ D_8090CD54 = 1;
+
+ Math_ApproachF(&D_80911F64, 71.0f, 0.5f, 3.0f);
+ Matrix_InsertYRotation_f(BINANG_TO_RAD(player->actor.shape.rot.y), MTXMODE_NEW);
+
+ sp114.x = Math_SinS(globalCtx->gameplayFrames * 0x1000);
+ sp114.y = D_80911F64;
+ sp114.z = -5.0f;
+ if (sLinkAge == 1) {
+ sp114.y -= 20.0f;
+ }
+
+ Matrix_MultiplyVector3fByState(&sp114, &sp108);
+
+ sSinkingLureBasePos.x = player->actor.world.pos.x + sp108.x;
+ sSinkingLureBasePos.y = player->actor.world.pos.y + sp108.y;
+ sSinkingLureBasePos.z = player->actor.world.pos.z + sp108.z;
+
+ Math_ApproachF(&D_80911F48, 15.0f, 0.1f, 0.75f);
+
+ sp114.x = D_80911F48 - 15.0f;
+
+ if (sLinkAge != 1) {
+ sp114.y = 60.0f;
+ sp114.z = -30.0f;
+ } else {
+ sp114.y = 40.0f;
+ sp114.z = -35.0f;
+ }
+
+ Matrix_MultiplyVector3fByState(&sp114, &sCameraEye);
+ sCameraEye.x += player->actor.world.pos.x;
+ sCameraEye.y += player->actor.world.pos.y;
+ sCameraEye.z += player->actor.world.pos.z;
+
+ sCameraAt = player->actor.world.pos;
+ if (sLinkAge != 1) {
+ sCameraAt.y += 62.0f;
+ } else {
+ sCameraAt.y += 40.0f;
+ }
+
+ if (D_8090CD50 == 0) {
+ if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) {
+ if (func_80147624(globalCtx)) {
+ Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM);
+
+ func_801477B4(globalCtx);
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ D_80917206 = 2;
+ D_809171D6 = 0;
+ }
+
+ camera->eye = sCameraEye;
+ camera->eyeNext = sCameraEye;
+ camera->at = sCameraAt;
+ func_80169AFC(globalCtx, sCameraId, 0);
+ func_800EA0EC(globalCtx, &globalCtx->csCtx);
+ func_800B7298(globalCtx, &this->actor, 6); // arg2 changed from 7 to 6 in MM
+ D_8090CD4C = 0;
+ sCameraId = MAIN_CAM;
+ player->unk_B28 = -5;
+ D_80917200 = 5;
+ D_8090CD54 = 0;
+ D_809171F6 = 20;
+ func_800F6834(globalCtx, 0);
+ globalCtx->envCtx.unk_8C.fogNear = 0;
+ }
+ }
+ }
+ break;
+
+ case 100:
+ break;
+ }
+
+ if (sCameraId != MAIN_CAM) {
+ Play_CameraSetAtEye(globalCtx, sCameraId, &sCameraAt, &sCameraEye);
+ Math_ApproachF(&D_80911F4C, 1.0f, 1.0f, 0.02f);
+
+ if (sCameraEye.y <= (WATER_SURFACE_Y(globalCtx) + 1.0f)) {
+ func_800F6834(globalCtx, 1);
+ if (D_809171CA != 0) {
+ globalCtx->envCtx.unk_8C.fogNear = -0xB2;
+ } else {
+ globalCtx->envCtx.unk_8C.fogNear = -0x2E;
+ }
+ } else {
+ func_800F6834(globalCtx, 0);
+ globalCtx->envCtx.unk_8C.fogNear = 0;
+ }
+ }
+
+ if ((player->actor.floorHeight < (WATER_SURFACE_Y(globalCtx) - 3.0f)) &&
+ (player->actor.world.pos.y < (player->actor.floorHeight + 3.0f)) && (player->actor.speedXZ > 1.0f) &&
+ ((globalCtx->gameplayFrames % 2) == 0)) {
+ Vec3f pos;
+
+ pos.x = randPlusMinusPoint5Scaled(20.0f) + player->actor.world.pos.x;
+ pos.z = randPlusMinusPoint5Scaled(20.0f) + player->actor.world.pos.z;
+ pos.y = player->actor.floorHeight + 5.0f;
+ EnFishing_SpawnWaterDust(NULL, globalCtx->specialEffects, &pos, 0.5f);
+ }
+
+ if ((player->actor.floorHeight < WATER_SURFACE_Y(globalCtx)) &&
+ (player->actor.floorHeight > (WATER_SURFACE_Y(globalCtx) - 10.0f)) && (player->actor.speedXZ >= 4.0f) &&
+ ((globalCtx->gameplayFrames % 4) == 0)) {
+ s16 i;
+
+ for (i = 0; i < 10; i++) {
+ Vec3f pos;
+ Vec3f vel;
+ f32 speedXZ;
+ f32 angle;
+
+ speedXZ = Rand_ZeroFloat(1.5f) + 1.5f;
+ angle = Rand_ZeroFloat(6.28f);
+
+ vel.x = __sinf(angle) * speedXZ;
+ vel.z = __cosf(angle) * speedXZ;
+ vel.y = Rand_ZeroFloat(3.0f) + 2.0f;
+
+ pos = player->actor.world.pos;
+ pos.x += 2.0f * vel.x;
+ pos.y = WATER_SURFACE_Y(globalCtx);
+ pos.z += 2.0f * vel.z;
+ EnFishing_SpawnDustSplash(NULL, globalCtx->specialEffects, &pos, &vel,
+ Rand_ZeroFloat(0.01f) + 0.020000001f);
+ }
+ }
+
+ if (D_809171CB >= 2) {
+ D_809171CB--;
+ }
+
+ if ((D_809171CB == 1) && !func_80152498(&globalCtx->msgCtx) && ((D_8090CD00 & 0xFFF) == 0xFFF)) {
+ D_809171CB = 200;
+
+ if (Rand_ZeroOne() < 0.5f) {
+ D_8090CCD4 = Rand_ZeroFloat(10.0f) + 5.0f;
+ globalCtx->envCtx.unk_E1 = 1;
+ } else {
+ D_8090CCD4 = 0;
+ globalCtx->envCtx.unk_E1 = 2;
+ }
+ }
+
+ Math_ApproachF(&D_8090CCD0, D_8090CCD4, 1.0f, 0.05f);
+
+ if (D_8090CCD0 > 0.0f) {
+ target = (D_8090CCD0 * 0.03f) + 0.8f;
+ if (target > 1.2f) {
+ target = 1.2f;
+ }
+ Math_ApproachF(&D_8090CCE8, target, 1.0f, 0.01f);
+ }
+
+ target = (10.0f - D_8090CCD0) * 150.1f;
+ if (target < 0.0f) {
+ target = 0.0f;
+ }
+ Math_ApproachF(&D_8090CCDC.z, target, 1.0f, 5.0f);
+
+ if (D_8090CCDC.z < 1500.0f) {
+ func_8019FAD8(&D_8090CCDC, NA_SE_EV_RAIN - SFX_FLAG, D_8090CCE8);
+ }
+
+ if (D_8090CCD4 != 0) {
+ Math_ApproachF(&D_8090CCD8, -200.0f, 1.0f, 2.0f);
+ } else {
+ Math_ApproachZeroF(&D_8090CCD8, 1.0f, 2.0f);
+ }
+
+ globalCtx->envCtx.unk_8C.diffuseColor1[0] = globalCtx->envCtx.unk_8C.diffuseColor1[1] =
+ globalCtx->envCtx.unk_8C.diffuseColor1[2] = D_8090CCD8;
+
+ if ((u8)D_8090CCD0 > 0) {
+ s32 pad;
+ Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM);
+ s16 i;
+ s32 pad1;
+ Vec3f pos;
+ Vec3f rot;
+ Vec3f projectedPos;
+ s32 pad2;
+
+ rot.x = 1.6707964f;
+ rot.y = 1.0f;
+ rot.z = (func_800DFC68(camera) * -(M_PI / 32768)) + rot.y;
+
+ for (i = 0; i < (u8)D_8090CCD0; i++) {
+ pos.x = randPlusMinusPoint5Scaled(700.0f) + globalCtx->view.eye.x;
+ pos.y = (Rand_ZeroFloat(100.0f) + 150.0f) - 170.0f;
+ pos.z = randPlusMinusPoint5Scaled(700.0f) + globalCtx->view.eye.z;
+
+ if (pos.z < 1160.0f) {
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &pos, &projectedPos, &sProjectedW);
+
+ if (projectedPos.z < 0.0f) {
+ i--;
+ } else {
+ EnFishing_SpawnRainDrop(globalCtx->specialEffects, &pos, &rot);
+ }
+ }
+ }
+ }
+
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sStreamSoundPos, &sStreamSoundProjectedPos,
+ &sProjectedW);
+
+ func_8019F1C0(&sStreamSoundProjectedPos, NA_SE_EV_WATER_WALL - SFX_FLAG);
+
+ if (gSaveContext.options.language == 0) { // Added in MM
+ gSaveContext.minigameScore = D_8090CCF8;
+ } else {
+ gSaveContext.minigameScore = (SQ((f32)D_8090CCF8) * 0.0036f) + 0.5f;
+ }
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateOwner.s")
+#endif
+
+s32 EnFishing_OwnerOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnFishing* this = THIS;
+
+ if (limbIndex == 8) { // Head
+ rot->x -= this->unk_15C;
+ }
+
+ return false;
+}
+
+void EnFishing_OwnerPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ if (limbIndex == 8) { // Head
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_MultiplyVector3fByState(&sZeroVec, &sOwnerHeadPos);
+
+ if (D_8090CD08 == 1) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL);
+ } else if (D_8090CD08 == 2) {
+ gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHairDL);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+}
+
+static UNK_TYPE sFishingOwnerEyeTexs[] = {
+ &gFishingOwnerEyeOpenTex,
+ &gFishingOwnerEyeHalfTex,
+ &gFishingOwnerEyeClosedTex,
+};
+
+void EnFishing_DrawOwner(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnFishing* this = THIS;
+ Input* input = CONTROLLER1(globalCtx);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ if ((this->actor.projectedPos.z < 1500.0f) &&
+ (fabsf(this->actor.projectedPos.x) < (100.0f + this->actor.projectedPos.z))) {
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sFishingOwnerEyeTexs[this->unk_158]));
+
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, EnFishing_OwnerOverrideLimbDraw, EnFishing_OwnerPostLimbDraw,
+ &this->actor);
+ }
+
+ EnFishing_DrawPondProps(globalCtx);
+ EnFishing_DrawEffects(globalCtx->specialEffects, globalCtx);
+ EnFishing_DrawGroupFishes(globalCtx);
+ EnFishing_DrawStreamSplash(globalCtx);
+
+ if (D_809171F6 != 0) {
+ D_809171F6--;
+
+ if (D_809171F6 == 0) {
+ if (sLinkAge != 1) {
+ Audio_QueueSeqCmd(0x8019); // Changed from 0x19 in OoT
+ } else {
+ Audio_QueueSeqCmd(0x8027); // Changed from 0x27 in OoT
+ }
+
+ if (sLinkAge != 1) {
+ Audio_QueueSeqCmd(0x8019); // Changed from 0x19 in OoT
+ } else {
+ Audio_QueueSeqCmd(0x8027); // Changed from 0x27 in OoT
+ }
+ }
+ }
+
+ if ((D_809171FC != 0) && D_8090CCF4) {
+ EnFishing_DrawRod(globalCtx);
+ EnFishing_UpdateLinePos(sReelLinePos);
+ EnFishing_UpdateLine(globalCtx, &sRodTipPos, sReelLinePos, sReelLineRot, sReelLineUnk);
+ EnFishing_DrawLureAndLine(globalCtx, sReelLinePos, sReelLineRot);
+
+ D_8090CD44 = input->rel.stick_x;
+ D_8090CD48 = input->rel.stick_y;
+ }
+
+ D_8090CCF4 = true;
+
+ Matrix_InsertTranslation(130.0f, 40.0f, 1300.0f, MTXMODE_NEW);
+ Matrix_Scale(0.08f, 0.12f, 0.14f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, gFishingAquariumBottomDL);
+ gSPDisplayList(POLY_XLU_DISP++, gFishingAquariumContainerDL);
+
+ if ((D_809171FC != 0) && (D_80917206 == 2)) {
+ EnFishing_DrawSinkingLure(globalCtx);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h
index d954b4cf8..3cd594b38 100644
--- a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h
+++ b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h
@@ -9,7 +9,56 @@ typedef void (*EnFishingActionFunc)(struct EnFishing*, GlobalContext*);
typedef struct EnFishing {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x404];
+ /* 0x0144 */ UNK_TYPE1 unk_144[0x004];
+ /* 0x0148 */ u8 unk_148;
+ /* 0x0149 */ u8 unk_149;
+ /* 0x014A */ u8 unk_14A;
+ /* 0x014C */ s16 unk_14C;
+ /* 0x014E */ u8 unk_14E;
+ /* 0x014F */ u8 unk_14F;
+ /* 0x0150 */ s16 unk_150;
+ /* 0x0152 */ s16 unk_152;
+ /* 0x0154 */ s16 unk_154;
+ /* 0x0156 */ s16 unk_156;
+ /* 0x0158 */ s16 unk_158;
+ /* 0x015A */ s16 unk_15A;
+ /* 0x015C */ s16 unk_15C;
+ /* 0x015E */ s16 unk_15E;
+ /* 0x0160 */ s16 unk_160;
+ /* 0x0162 */ s16 unk_162;
+ /* 0x0164 */ s16 unk_164;
+ /* 0x0166 */ s16 unk_166;
+ /* 0x0168 */ s16 unk_168;
+ /* 0x016A */ s16 unk_16A;
+ /* 0x016C */ s16 unk_16C;
+ /* 0x016E */ s16 unk_16E;
+ /* 0x0170 */ s16 unk_170;
+ /* 0x0172 */ s16 unk_172[4];
+ /* 0x017C */ f32 unk_17C;
+ /* 0x0180 */ f32 unk_180;
+ /* 0x0184 */ f32 unk_184;
+ /* 0x0188 */ f32 unk_188;
+ /* 0x018C */ f32 unk_18C;
+ /* 0x0190 */ f32 unk_190;
+ /* 0x0194 */ f32 unk_194;
+ /* 0x0198 */ s16 unk_198;
+ /* 0x019A */ s16 unk_19A;
+ /* 0x019C */ s16 unk_19C;
+ /* 0x01A0 */ f32 unk_1A0;
+ /* 0x01A4 */ f32 unk_1A4;
+ /* 0x01A8 */ f32 unk_1A8;
+ /* 0x01AC */ Vec3f unk_1AC;
+ /* 0x01B8 */ Vec3f fishMouthPos;
+ /* 0x01C4 */ s16 unk_1C4[3];
+ /* 0x01CA */ u8 unk_1CA;
+ /* 0x01CB */ u8 unk_1CB;
+ /* 0x01CC */ u8 unk_1CC;
+ /* 0x01CD */ u8 unk_1CD;
+ /* 0x01D0 */ SkelAnime skelAnime;
+ /* 0x0214 */ LightNode* lightNode;
+ /* 0x0218 */ LightInfo lightInfo;
+ /* 0x0228 */ ColliderJntSph collider;
+ /* 0x0248 */ ColliderJntSphElement colliderElements[12];
} EnFishing; // size = 0x548
extern const ActorInit En_Fishing_InitVars;
diff --git a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c
index 6d78480e7..17eeeec1a 100644
--- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c
+++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c
@@ -5,6 +5,7 @@
*/
#include "z_en_gb2.h"
+#include "objects/object_ps/object_ps.h"
#define FLAGS 0x00000039
@@ -15,6 +16,7 @@ void EnGb2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnGb2_Update(Actor* thisx, GlobalContext* globalCtx);
void EnGb2_Draw(Actor* thisx, GlobalContext* globalCtx);
+void func_80B0FBF0(EnGb2* this, GlobalContext* globalCtx);
void func_80B0FEBC(EnGb2* this, GlobalContext* globalCtx);
void func_80B0FFA8(EnGb2* this, GlobalContext* globalCtx);
void func_80B10240(EnGb2* this, GlobalContext* globalCtx);
@@ -29,11 +31,11 @@ void func_80B10B5C(EnGb2* this, GlobalContext* globalCtx);
void func_80B10DAC(EnGb2* this, GlobalContext* globalCtx);
void func_80B10E98(EnGb2* this, GlobalContext* globalCtx);
void func_80B11048(EnGb2* this, GlobalContext* globalCtx);
+void func_80B110F8(EnGb2* this, GlobalContext* globalCtx);
void func_80B111AC(EnGb2* this, GlobalContext* globalCtx);
void func_80B11268(EnGb2* this, GlobalContext* globalCtx);
void func_80B11344(EnGb2* this, GlobalContext* globalCtx);
-#if 0
const ActorInit En_Gb2_InitVars = {
ACTOR_EN_GB2,
ACTORCAT_NPC,
@@ -46,98 +48,984 @@ const ActorInit En_Gb2_InitVars = {
(ActorFunc)EnGb2_Draw,
};
-// static ColliderCylinderInitType1 sCylinderInit = {
-static ColliderCylinderInitType1 D_80B11A40 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+typedef struct {
+ /* 0x00 */ s16 unk_00;
+ /* 0x04 */ Vec3f unk_04;
+ /* 0x10 */ s16 unk_10;
+} EnGbStruct; // size = 0x14
+
+static EnGbStruct D_80B119B0[] = {
+ { ACTOR_EN_PO_SISTERS, { 0.0f, 0.0f, 0.0f }, 0x300 },
+ { ACTOR_EN_PO_SISTERS, { 100.0f, 0.0f, 0.0f }, 0x200 },
+ { ACTOR_EN_PO_SISTERS, { -100.0f, 0.0f, 0.0f }, 0x100 },
+ { ACTOR_EN_PO_SISTERS, { 0.0f, 0.0f, 0.0f }, 0 },
+};
+
+static f32 D_80B11A00[][4] = {
+ { 0.0f, -13.0f, 549.0f, 0.0f },
+ { -242.0f, -13.0f, 390.0f, -90.0f },
+ { 0.0f, -13.0f, 148.0f, 180.0f },
+ { 244.0f, -13.0f, 390.0f, 90.0f },
+};
+
+static ColliderCylinderInitType1 sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 40, 75, 0, { 0, 0, 0 } },
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80B11AC4[] = {
+void func_80B0F5E0(EnGb2* this, GlobalContext* globalCtx) {
+ this->collider.dim.pos.x = this->actor.world.pos.x;
+ this->collider.dim.pos.y = this->actor.world.pos.y;
+ this->collider.dim.pos.z = this->actor.world.pos.z;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+s32 func_80B0F660(EnGb2* this, GlobalContext* globalCtx) {
+ Actor* temp_v0;
+ Actor* phi_s0 = NULL;
+
+ while (true) {
+ temp_v0 = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_NPC, ACTOR_EN_GB2);
+ if (temp_v0 == NULL) {
+ break;
+ }
+
+ if ((EnGb2*)temp_v0 != this) {
+ return true;
+ }
+
+ temp_v0 = temp_v0->next;
+ if (temp_v0 == NULL) {
+ break;
+ }
+ phi_s0 = temp_v0;
+ };
+
+ return false;
+}
+
+void func_80B0F6DC(EnGb2* this) {
+ if (!(gSaveContext.save.weekEventReg[54] & 0x20)) {
+ gSaveContext.save.weekEventReg[54] |= 0x20;
+ this->unk_26E = 0x14D0;
+ } else {
+ this->unk_26E = 0x14D1;
+ }
+ this->unk_288 = 30;
+ this->actionFunc = func_80B0FEBC;
+}
+
+void func_80B0F728(EnGb2* this, GlobalContext* globalCtx) {
+ if (gSaveContext.eventInf[4] & 0x10) {
+ func_80B0FBF0(this, globalCtx);
+ this->unk_26E = 0x14E1;
+ if (gSaveContext.eventInf[4] & 0x80) {
+ this->unk_288 = 10;
+ } else {
+ this->unk_288 = 30;
+ }
+ } else if (gSaveContext.eventInf[4] & 0x20) {
+ func_80B0FBF0(this, globalCtx);
+ this->unk_26E = 0x14E0;
+ this->unk_26C |= 2;
+ } else {
+ this->unk_26E = 0x14DC;
+ }
+
+ gSaveContext.eventInf[4] &= (u8)~0x10;
+ gSaveContext.eventInf[4] &= (u8)~0x20;
+ gSaveContext.eventInf[4] &= (u8)~0x40;
+ this->actionFunc = func_80B10584;
+}
+
+u16 func_80B0F7FC(EnGb2* this) {
+ switch (this->unk_26E) {
+ case 0x14D0:
+ return 0x14D1;
+
+ case 0x14D1:
+ if (gSaveContext.eventInf[4] & 0x80) {
+ return 0x14E4;
+ }
+
+ if (gSaveContext.save.playerData.health > 48) {
+ return 0x14D2;
+ }
+
+ this->unk_26C |= 2;
+ return 0x14D3;
+
+ case 0x14E4:
+ if (gSaveContext.save.playerData.health > 48) {
+ return 0x14D2;
+ }
+
+ this->unk_26C |= 2;
+ return 0x14D3;
+
+ case 0x14D2:
+ if (gSaveContext.eventInf[4] & 0x80) {
+ return 0x14E5;
+ }
+ return 0x14D4;
+
+ case 0x14D4:
+ case 0x14E5:
+ return 0x14D5;
+
+ case 0x14D8:
+ return 0x14D9;
+
+ case 0x14D9:
+ return 0x14DA;
+ }
+ return 0;
+}
+
+u16 func_80B0F8F8(EnGb2* this) {
+ switch (this->unk_26E) {
+ case 0x14DC:
+ this->unk_26C |= 2;
+ return 0x14DD;
+
+ case 0x14DD:
+ return 0x14DE;
+
+ case 0x14DE:
+ this->unk_26C |= 2;
+ gSaveContext.save.weekEventReg[54] |= 0x80;
+ return 0x14DF;
+
+ case 0x14E1:
+ return 0x14E2;
+ }
+ return 0;
+}
+
+u16 func_80B0F97C(EnGb2* this) {
+ switch (this->unk_26E) {
+ case 0x14F5:
+ return 0x14F6;
+
+ case 0x14F6:
+ return 0x14F7;
+
+ case 0x14F7:
+ gSaveContext.save.weekEventReg[76] |= 0x80;
+ this->unk_26C |= 2;
+ return 0x14F8;
+
+ case 0x14F9:
+ return 0x14FA;
+
+ case 0x14FA:
+ this->unk_26C |= 2;
+ return 0x14FB;
+ }
+ return 0;
+}
+
+void func_80B0FA04(EnGb2* this) {
+ this->unk_282[0] = this->actor.cutscene;
+ this->unk_282[1] = ActorCutscene_GetAdditionalCutscene(this->unk_282[0]);
+ this->unk_282[2] = ActorCutscene_GetAdditionalCutscene(this->unk_282[1]);
+}
+
+s32 func_80B0FA48(EnGb2* this, GlobalContext* globalCtx) {
+ switch (Player_GetMask(globalCtx)) {
+ case PLAYER_MASK_GIBDO:
+ this->unk_26C |= 4;
+ this->unk_26E = 0x14E6;
+ return false;
+
+ case PLAYER_MASK_GARO:
+ this->unk_26C |= 8;
+ this->unk_26E = 0x14E6;
+ return false;
+
+ case PLAYER_MASK_CAPTAIN:
+ if (!(gSaveContext.save.weekEventReg[80] & 0x40)) {
+ this->unk_26E = 0x14EB;
+ return false;
+ }
+ this->unk_26E = 0x14EE;
+ return true;
+ }
+
+ if (!(gSaveContext.save.weekEventReg[80] & 0x20)) {
+ this->unk_26E = 0x14EF;
+ return false;
+ } else {
+ this->unk_26E = 0x14F4;
+ return true;
+ }
+}
+
+u16 func_80B0FB24(EnGb2* this) {
+ switch (this->unk_26E) {
+ case 0x14E6:
+ if (this->unk_26C & 4) {
+ return 0x14E7;
+ }
+
+ if (this->unk_26C & 8) {
+ return 0x14E9;
+ }
+
+ case 0x14E7:
+ this->unk_26C |= 2;
+ return 0x14E8;
+
+ case 0x14E9:
+ this->unk_26C |= 2;
+ return 0x14EA;
+
+ case 0x14EB:
+ return 0x14EC;
+
+ case 0x14EC:
+ this->unk_26C |= 2;
+ return 0x14ED;
+
+ case 0x14EF:
+ return 0x14F0;
+
+ case 0x14F0:
+ return 0x14F1;
+
+ case 0x14F1:
+ return 0x14F2;
+
+ case 0x14F2:
+ this->unk_26C |= 2;
+ return 0x14F3;
+ }
+ return 0;
+}
+
+void func_80B0FBF0(EnGb2* this, GlobalContext* globalCtx) {
+ Vec3f sp90[4] = {
+ { 120.0f, 0.0f, 800.0f },
+ { -120.0f, 0.0f, 750.0f },
+ { 60.0f, 0.0f, 750.0f },
+ { -60.0f, 0.0f, 800.0f },
+ };
+ Vec3s sp78[] = {
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ };
+ s32 sp68[] = {
+ 0x1000,
+ 0x1100,
+ 0x1200,
+ 0x1300,
+ };
+ s16 i;
+ s16 end = ARRAY_COUNT(sp90);
+
+ for (i = 0; i < end; i++) {
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, sp90[i].x, sp90[i].y,
+ sp90[i].z, sp78[i].x, sp78[i].y, sp78[i].z, sp68[i]);
+ }
+}
+
+void func_80B0FD8C(EnGb2* this, GlobalContext* globalCtx) {
+ this->unk_280++;
+ this->unk_268 = this->actor.child;
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS,
+ D_80B119B0[this->unk_280].unk_04.x, D_80B119B0[this->unk_280].unk_04.y,
+ D_80B119B0[this->unk_280].unk_04.z, 0, 0, 0, D_80B119B0[this->unk_280].unk_10);
+}
+
+void func_80B0FE18(GlobalContext* globalCtx) {
+ func_800FD750(0x38);
+ globalCtx->nextEntranceIndex = 0x9C10;
+ globalCtx->unk_1887F = 0x40;
+ gSaveContext.nextTransition = 0x40;
+ globalCtx->sceneLoadFlag = 0x14;
+}
+
+void func_80B0FE7C(GlobalContext* globalCtx) {
+ globalCtx->nextEntranceIndex = 0x9C20;
+ globalCtx->unk_1887F = 0x40;
+ gSaveContext.nextTransition = 0x40;
+ globalCtx->sceneLoadFlag = 0x14;
+}
+
+void func_80B0FEBC(EnGb2* this, GlobalContext* globalCtx) {
+ if ((globalCtx->msgCtx.ocarinaMode == 3) && (globalCtx->msgCtx.unk1202E == 7)) {
+ globalCtx->msgCtx.ocarinaMode = 4;
+ gSaveContext.eventInf[4] |= 0x80;
+ this->unk_26E = 0x14D1;
+ this->unk_288 = 10;
+ }
+
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ this->actionFunc = func_80B0FFA8;
+ } else if ((this->actor.xzDistToPlayer < 300.0f) || this->actor.isTargeted) {
+ func_800B863C(&this->actor, globalCtx);
+ }
+}
+
+void func_80B0FFA8(EnGb2* this, GlobalContext* globalCtx) {
+ u8 temp_v0 = func_80152498(&globalCtx->msgCtx);
+
+ if (temp_v0 == 5) {
+ if (func_80147624(globalCtx)) {
+ if (this->unk_26C & 2) {
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ this->unk_26E = 0x14D1;
+ this->unk_288 = 30;
+ gSaveContext.eventInf[4] &= (u8)~0x80;
+ this->unk_26C &= ~2;
+ this->actionFunc = func_80B0FEBC;
+ } else {
+ this->unk_26E = func_80B0F7FC(this);
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ }
+ }
+ } else if ((temp_v0 == 4) && func_80147624(globalCtx)) {
+ if (this->unk_26E == 0x14D5) {
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ if (gSaveContext.save.playerData.rupees < this->unk_288) {
+ play_sound(NA_SE_SY_ERROR);
+ this->unk_26E = 0x14D7;
+ this->unk_26C |= 2;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ } else {
+ func_8019F208();
+ this->unk_26E = 0x14D8;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ }
+ break;
+
+ case 1:
+ func_8019F230();
+ this->unk_26E = 0x14D6;
+ this->unk_26C |= 2;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ break;
+ }
+ } else if (this->unk_26E == 0x14DA) {
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ func_8019F208();
+ Rupees_ChangeBy(-this->unk_288);
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ func_800B7298(globalCtx, NULL, 7);
+ this->actionFunc = func_80B11344;
+ break;
+
+ case 1:
+ func_8019F230();
+ this->unk_26E = 0x14DB;
+ this->unk_26C |= 2;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ break;
+ }
+ }
+ }
+}
+
+void func_80B10240(EnGb2* this, GlobalContext* globalCtx) {
+ this->unk_27C = D_80B119B0[this->unk_280].unk_00;
+ this->unk_27E = D_80B119B0[this->unk_280].unk_10;
+ this->unk_282[0] = this->actor.cutscene;
+ this->unk_268 = NULL;
+ if (ActorCutscene_GetCanPlayNext(this->unk_282[0])) {
+ ActorCutscene_Start(this->unk_282[0], &this->actor);
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, this->unk_27C,
+ D_80B119B0[this->unk_280].unk_04.x, D_80B119B0[this->unk_280].unk_04.y,
+ D_80B119B0[this->unk_280].unk_04.z, 0, 0, 0, this->unk_27E);
+ if (this->unk_280 == 0) {
+ func_8010E9F0(1, 180);
+ }
+ this->actionFunc = func_80B10344;
+ } else {
+ ActorCutscene_SetIntentToPlay(this->unk_282[0]);
+ }
+}
+
+void func_80B10344(EnGb2* this, GlobalContext* globalCtx) {
+ if (this->unk_280 == 1) {
+ func_80B0FD8C(this, globalCtx);
+ }
+
+ if (this->unk_280 == 2) {
+ if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) {
+ this->unk_268 = NULL;
+ this->unk_26C |= 0x400;
+ }
+ }
+
+ if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) {
+ this->actor.child = NULL;
+ this->unk_26C |= 0x200;
+ }
+
+ if (this->unk_26C & 0x200) {
+ if (this->unk_280 == 3) {
+ this->unk_26C &= ~0x200;
+ gSaveContext.unk_3DD0[1] = 5;
+ func_800FE498();
+ gSaveContext.eventInf[4] |= 0x40;
+ func_80B0FE7C(globalCtx);
+ } else if (this->unk_280 == 2) {
+ if (this->unk_26C & 0x400) {
+ this->unk_280++;
+ this->unk_26C &= ~0x200;
+ this->unk_26C &= ~0x400;
+ this->actionFunc = func_80B10240;
+ }
+ } else {
+ this->unk_280++;
+ this->unk_26C &= ~0x200;
+ this->actionFunc = func_80B10240;
+ }
+ }
+
+ if (gSaveContext.save.playerData.health < 49) {
+ gSaveContext.unk_3DD0[1] = 5;
+ gSaveContext.eventInf[4] |= 0x40;
+ gSaveContext.eventInf[4] |= 0x20;
+
+ if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) {
+ this->unk_268 = NULL;
+ }
+
+ if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) {
+ this->actor.child = NULL;
+ }
+
+ func_80B0FE7C(globalCtx);
+ } else if (gSaveContext.unk_3DE0[1] == 0) {
+ gSaveContext.unk_3DD0[1] = 5;
+ gSaveContext.eventInf[4] |= 0x40;
+ gSaveContext.eventInf[4] |= 0x10;
+
+ if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) {
+ this->unk_268 = NULL;
+ }
+
+ if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) {
+ this->actor.child = NULL;
+ }
+
+ func_80B0FE7C(globalCtx);
+ }
+}
+
+void func_80B10584(EnGb2* this, GlobalContext* globalCtx) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ this->actor.flags &= ~0x10000;
+ this->actionFunc = func_80B10634;
+ } else if (this->actor.xzDistToPlayer < 300.0f) {
+ this->actor.flags |= 0x10000;
+ func_800B8614(&this->actor, globalCtx, 300.0f);
+ }
+}
+
+void func_80B10634(EnGb2* this, GlobalContext* globalCtx) {
+ u8 temp_v0 = func_80152498(&globalCtx->msgCtx);
+
+ if (temp_v0 == 5) {
+ if (func_80147624(globalCtx)) {
+ if (this->unk_26C & 2) {
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ this->unk_26C &= ~2;
+ if (this->unk_26E == 0x14DD) {
+ this->unk_26E = 0x14DE;
+ this->actionFunc = func_80B10924;
+ } else if (this->unk_26E == 0x14DF) {
+ this->actionFunc = func_80B10A48;
+ } else {
+ this->unk_26E = 0x14D1;
+ this->unk_288 = 30;
+ gSaveContext.eventInf[4] &= (u8)~0x80;
+ this->actionFunc = func_80B0FEBC;
+ }
+ } else {
+ this->unk_26E = func_80B0F8F8(this);
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ }
+ }
+ } else if ((temp_v0 == 4) && func_80147624(globalCtx)) {
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0:
+ if (gSaveContext.save.playerData.rupees < this->unk_288) {
+ play_sound(NA_SE_SY_ERROR);
+ this->unk_26E = 0x14D7;
+ this->unk_26C |= 2;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ } else {
+ func_8019F208();
+ Rupees_ChangeBy(-this->unk_288);
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ func_800B7298(globalCtx, NULL, 7);
+ this->actionFunc = func_80B11344;
+ }
+ break;
+
+ case 1:
+ func_8019F230();
+ this->unk_26E = 0x14E3;
+ this->unk_26C |= 2;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ break;
+ }
+ }
+}
+
+void func_80B10868(EnGb2* this, GlobalContext* globalCtx) {
+ if (ActorCutscene_GetCurrentIndex() != this->unk_282[2]) {
+ if (ActorCutscene_GetCanPlayNext(this->unk_282[this->unk_290])) {
+ this->actionFunc = func_80B10A48;
+ ActorCutscene_StartAndSetFlag(this->unk_282[this->unk_290], &this->actor);
+ } else {
+ ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]);
+ }
+ } else {
+ this->unk_290 = 1;
+ ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]);
+ }
+}
+
+void func_80B10924(EnGb2* this, GlobalContext* globalCtx) {
+ s32 sp24;
+
+ if (gSaveContext.save.weekEventReg[54] & 0x40) {
+ sp24 = 5;
+ } else {
+ sp24 = 12;
+ }
+
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ this->actor.parent = NULL;
+ if (sp24 == 12) {
+ gSaveContext.save.weekEventReg[54] |= 0x40;
+ } else {
+ Rupees_ChangeBy(50);
+ }
+ this->actionFunc = func_80B109DC;
+ } else {
+ func_800B8A1C(&this->actor, globalCtx, sp24, 300.0f, 300.0f);
+ }
+}
+
+void func_80B109DC(EnGb2* this, GlobalContext* globalCtx) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ this->actionFunc = func_80B10634;
+ } else {
+ func_800B85E0(&this->actor, globalCtx, 300.0f, -1);
+ }
+}
+
+void func_80B10A48(EnGb2* this, GlobalContext* globalCtx) {
+ this->unk_28A -= 5;
+ if (this->unk_28A < 5) {
+ this->unk_28A = 0;
+
+ switch (ENGB2_GET_7(&this->actor)) {
+ case ENGB2_7_0:
+ Actor_MarkForDeath(&this->actor);
+ break;
+
+ case ENGB2_7_1:
+ ActorCutscene_Stop(this->unk_282[this->unk_290]);
+ Actor_MarkForDeath(&this->actor);
+ break;
+
+ case ENGB2_7_2:
+ ActorCutscene_Stop(this->unk_282[this->unk_290]);
+ if (this->unk_26E == 0x14FB) {
+ Actor_SetSwitchFlag(globalCtx, ENGB2_GET_7F8(&this->actor));
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ this->actor.draw = NULL;
+ this->unk_26C |= 0x100;
+ this->actor.flags &= ~1;
+ this->actionFunc = func_80B111AC;
+ }
+ break;
+ }
+ }
+}
+
+void func_80B10B5C(EnGb2* this, GlobalContext* globalCtx) {
+ s32 mask = Player_GetMask(globalCtx);
+
+ if (this->unk_28C != mask) {
+ this->unk_28C = Player_GetMask(globalCtx);
+ this->unk_26C &= ~0x80;
+ this->unk_26C &= ~0x20;
+ this->unk_26C &= ~0x40;
+ }
+
+ if (func_80B0FA48(this, globalCtx)) {
+ this->unk_26C &= ~0x20;
+ if (func_800B84D0(&this->actor, globalCtx) && (this->unk_26C & 0x40)) {
+ if ((this->unk_26E == 0x14EE) || (this->unk_26E == 0x14F4)) {
+ this->unk_26C |= 2;
+ }
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ this->unk_290 = 1;
+ this->unk_26C &= ~0x40;
+ this->actionFunc = func_80B10DAC;
+ } else if ((this->actor.xzDistToPlayer < 300.0f) && this->actor.isTargeted) {
+ this->unk_26C |= 0x40;
+ func_800B8614(&this->actor, globalCtx, 300.0f);
+ }
+ } else {
+ this->unk_26C &= ~0x40;
+ if (func_800B84D0(&this->actor, globalCtx) && (this->unk_26C & 0x20)) {
+ this->actor.flags &= ~0x10000;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ if (this->unk_26E == 0x14EB) {
+ gSaveContext.save.weekEventReg[80] |= 0x40;
+ } else if (this->unk_26E == 0x14EF) {
+ gSaveContext.save.weekEventReg[80] |= 0x20;
+ }
+ this->unk_26C &= ~0x20;
+ this->unk_290 = 0;
+ this->unk_26C |= 0x80;
+ this->actionFunc = func_80B10DAC;
+ } else if (this->actor.xzDistToPlayer < 300.0f) {
+ if (!(this->unk_26C & 0x80)) {
+ this->actor.flags |= 0x10000;
+ this->unk_26C |= 0x20;
+ func_800B8614(&this->actor, globalCtx, 300.0f);
+ }
+ }
+ }
+}
+
+void func_80B10DAC(EnGb2* this, GlobalContext* globalCtx) {
+ if (ActorCutscene_GetCanPlayNext(this->unk_282[this->unk_290])) {
+ if (ENGB2_GET_7(&this->actor) == ENGB2_7_1) {
+ if (this->unk_290 != 2) {
+ this->actionFunc = func_80B10E98;
+ } else {
+ Actor_SetSwitchFlag(globalCtx, ENGB2_GET_7F8(&this->actor));
+ this->actionFunc = func_80B10868;
+ }
+ } else {
+ this->actionFunc = func_80B110F8;
+ }
+ ActorCutscene_StartAndSetFlag(this->unk_282[this->unk_290], &this->actor);
+ } else {
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ }
+ ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]);
+ }
+}
+
+void func_80B10E98(EnGb2* this, GlobalContext* globalCtx) {
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ if (this->unk_26C & 2) {
+ this->unk_26C &= ~2;
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ if ((this->unk_26E != 0x14E8) && (this->unk_26E != 0x14EA)) {
+ ActorCutscene_Stop(this->unk_282[this->unk_290]);
+ this->actionFunc = func_80B10B5C;
+ } else if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(&this->actor))) {
+ this->actionFunc = func_80B10A48;
+ } else {
+ ActorCutscene_Stop(this->unk_282[this->unk_290]);
+ this->unk_290 = 2;
+ ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]);
+ this->actionFunc = func_80B10DAC;
+ }
+ } else {
+ s32 temp;
+
+ this->unk_26E = func_80B0FB24(this);
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ temp = this->unk_26E;
+ if ((temp == 0x14E7) || (temp == 0x14E9) || (temp == 0x14EC) || (temp == 0x14F0)) {
+ ActorCutscene_Stop(this->unk_282[this->unk_290]);
+ this->unk_290 = 1;
+ ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]);
+ this->actionFunc = func_80B10DAC;
+ }
+ }
+ }
+}
+
+void func_80B11048(EnGb2* this, GlobalContext* globalCtx) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ this->actor.flags &= ~0x10000;
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ this->actionFunc = func_80B10DAC;
+ } else if (this->actor.xzDistToPlayer < 300.0f) {
+ this->actor.flags |= 0x10000;
+ func_800B8614(&this->actor, globalCtx, 200.0f);
+ }
+}
+
+void func_80B110F8(EnGb2* this, GlobalContext* globalCtx) {
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ if (this->unk_26C & 2) {
+ globalCtx->msgCtx.unk11F22 = 0x43;
+ globalCtx->msgCtx.unk12023 = 4;
+ this->unk_26C &= ~2;
+ this->actionFunc = func_80B10A48;
+ } else {
+ this->unk_26E = func_80B0F97C(this);
+ func_801518B0(globalCtx, this->unk_26E, &this->actor);
+ }
+ }
+}
+
+void func_80B111AC(EnGb2* this, GlobalContext* globalCtx) {
+ s32 index;
+
+ if (globalCtx->roomCtx.currRoom.num == 1) {
+ return;
+ }
+
+ switch (globalCtx->roomCtx.currRoom.num) {
+ case 2:
+ index = 1;
+ break;
+
+ case 3:
+ case 4:
+ index = 2;
+ break;
+
+ case 5:
+ index = 3;
+ break;
+
+ default:
+ index = 0;
+ }
+
+ this->actor.world.pos.x = D_80B11A00[index][0];
+ this->actor.world.pos.y = D_80B11A00[index][1];
+ this->actor.world.pos.z = D_80B11A00[index][2];
+ this->actor.world.rot.y = D_80B11A00[index][3] * 182.04445f;
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->actionFunc = func_80B11268;
+}
+
+void func_80B11268(EnGb2* this, GlobalContext* globalCtx) {
+ if (globalCtx->roomCtx.currRoom.num == 1) {
+ this->unk_290 = 0;
+ this->unk_282[0] = this->actor.cutscene;
+ if (Actor_GetRoomCleared(globalCtx, 2) && Actor_GetRoomCleared(globalCtx, 3) &&
+ Actor_GetRoomCleared(globalCtx, 4) && Actor_GetRoomCleared(globalCtx, 5)) {
+ this->unk_28A = 0xFF;
+ this->unk_26C &= ~0x100;
+ this->actor.flags |= 1;
+ this->actor.draw = EnGb2_Draw;
+ this->unk_26E = 0x14F9;
+ this->actionFunc = func_80B11048;
+ } else {
+ this->actionFunc = func_80B111AC;
+ }
+ }
+}
+
+void func_80B11344(EnGb2* this, GlobalContext* globalCtx) {
+ if (gSaveContext.rupeeAccumulator == 0) {
+ func_80B0FE18(globalCtx);
+ }
+}
+
+static InitChainEntry sInitChain[] = {
ICHAIN_U8(targetMode, 4, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 2200, ICHAIN_STOP),
};
-#endif
+void EnGb2_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnGb2* this = THIS;
-extern ColliderCylinderInit D_80B11A40;
-extern InitChainEntry D_80B11AC4[];
+ if (func_80B0F660(this, globalCtx)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-extern UNK_TYPE D_0600049C;
+ this->actor.room = -1;
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ps_Skel_007230, &object_ps_Anim_00049C, this->jointTable,
+ this->morphTable, 12);
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ Actor_SetScale(&this->actor, 0.01f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F5E0.s")
+ switch (ENGB2_GET_7(&this->actor)) {
+ case ENGB2_7_0:
+ if (gSaveContext.save.weekEventReg[54] & 0x80) {
+ Actor_MarkForDeath(&this->actor);
+ } else if (gSaveContext.save.weekEventReg[52] & 0x20) {
+ Actor_MarkForDeath(&this->actor);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F660.s")
+ if (gSaveContext.save.entranceIndex == 0x9C10) {
+ func_800FE484();
+ this->actionFunc = func_80B10240;
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F6DC.s")
+ this->unk_28A = 255;
+ this->actor.flags |= 0x10;
+ this->actor.flags |= 0x2000000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F728.s")
+ if (gSaveContext.eventInf[4] & 0x40) {
+ func_80B0F728(this, globalCtx);
+ } else {
+ func_80B0FBF0(this, globalCtx);
+ func_80B0F6DC(this);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F7FC.s")
+ case ENGB2_7_1:
+ if ((globalCtx->curSpawn == 1) || (gSaveContext.save.weekEventReg[80] & 0x80)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F8F8.s")
+ if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(thisx))) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F97C.s")
+ this->unk_28A = 255;
+ func_80B0FA04(this);
+ this->unk_28C = Player_GetMask(globalCtx);
+ this->actionFunc = func_80B10B5C;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FA04.s")
+ case ENGB2_7_2:
+ this->unk_290 = 0;
+ this->unk_282[0] = this->actor.cutscene;
+ if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(thisx))) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FA48.s")
+ if (Actor_GetRoomCleared(globalCtx, 2) && Actor_GetRoomCleared(globalCtx, 3) &&
+ Actor_GetRoomCleared(globalCtx, 4) && Actor_GetRoomCleared(globalCtx, 5)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FB24.s")
+ if (gSaveContext.save.weekEventReg[76] & 0x80) {
+ this->actor.draw = NULL;
+ this->unk_26C |= 0x100;
+ this->actor.flags &= ~1;
+ this->actionFunc = func_80B111AC;
+ } else {
+ this->unk_28A = 255;
+ this->unk_26E = 0x14F5;
+ this->actionFunc = func_80B11048;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FBF0.s")
+ default:
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FD8C.s")
+void EnGb2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnGb2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FE18.s")
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FE7C.s")
+void EnGb2_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnGb2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FEBC.s")
+ SkelAnime_Update(&this->skelAnime);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FFA8.s")
+ this->actionFunc(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10240.s")
+ if (!(this->unk_26C & 0x100)) {
+ func_80B0F5E0(this, globalCtx);
+ }
+ func_800E9250(globalCtx, &this->actor, &this->unk_270, &this->unk_276, this->actor.focus.pos);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10344.s")
+s32 EnGb2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx,
+ Gfx** gfx) {
+ EnGb2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10584.s")
+ if (limbIndex == 7) {
+ limbIndex = limbIndex;
+ Matrix_RotateY(this->unk_270.y, MTXMODE_APPLY);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10634.s")
+ if (limbIndex == 1) {
+ *dList = NULL;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10868.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10924.s")
+void EnGb2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) {
+ EnGb2* this = THIS;
+ Vec3f sp18 = { 2400.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B109DC.s")
+ if (limbIndex == 7) {
+ Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10A48.s")
+void EnGb2_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnGb2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10B5C.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10DAC.s")
+ if (this->unk_28A == 255) {
+ func_8012C28C(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10E98.s")
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11048.s")
+ Scene_SetRenderModeXlu(globalCtx, 0, 1);
+ POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, EnGb2_OverrideLimbDraw, EnGb2_PostLimbDraw,
+ &this->actor, POLY_OPA_DISP);
+ } else {
+ func_8012C2DC(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B110F8.s")
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, this->unk_28A);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B111AC.s")
+ Scene_SetRenderModeXlu(globalCtx, 1, 2);
+ POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, EnGb2_OverrideLimbDraw, EnGb2_PostLimbDraw,
+ &this->actor, POLY_XLU_DISP);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11268.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11344.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Init.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Destroy.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Update.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B1179C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B117FC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Draw.s")
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h
index 17274b82f..c054c4ed2 100644
--- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h
+++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h
@@ -7,11 +7,35 @@ struct EnGb2;
typedef void (*EnGb2ActionFunc)(struct EnGb2*, GlobalContext*);
+#define ENGB2_GET_7(thisx) ((thisx)->params & 7)
+#define ENGB2_GET_7F8(thisx) (((thisx)->params & 0x7F8) >> 3)
+
+enum {
+ /* 0 */ ENGB2_7_0,
+ /* 1 */ ENGB2_7_1,
+ /* 2 */ ENGB2_7_2,
+};
+
typedef struct EnGb2 {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0xD4];
- /* 0x0218 */ EnGb2ActionFunc actionFunc;
- /* 0x021C */ char unk_21C[0x78];
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ Vec3s jointTable[12];
+ /* 0x1D0 */ Vec3s morphTable[12];
+ /* 0x218 */ EnGb2ActionFunc actionFunc;
+ /* 0x21C */ ColliderCylinder collider;
+ /* 0x268 */ Actor* unk_268;
+ /* 0x26C */ u16 unk_26C;
+ /* 0x26E */ u16 unk_26E;
+ /* 0x270 */ Vec3s unk_270;
+ /* 0x276 */ Vec3s unk_276;
+ /* 0x27C */ s16 unk_27C;
+ /* 0x27E */ s16 unk_27E;
+ /* 0x280 */ s16 unk_280;
+ /* 0x282 */ s16 unk_282[3];
+ /* 0x288 */ s16 unk_288;
+ /* 0x28A */ u8 unk_28A;
+ /* 0x28C */ s32 unk_28C;
+ /* 0x290 */ s16 unk_290;
} EnGb2; // size = 0x294
extern const ActorInit En_Gb2_InitVars;
diff --git a/src/overlays/actors/ovl_En_Geg/z_en_geg.c b/src/overlays/actors/ovl_En_Geg/z_en_geg.c
index ab8af7dcb..39784722f 100644
--- a/src/overlays/actors/ovl_En_Geg/z_en_geg.c
+++ b/src/overlays/actors/ovl_En_Geg/z_en_geg.c
@@ -259,7 +259,7 @@ Vec3f* func_80BB19C0(Vec3f* arg0, EnGeg* this, GlobalContext* globalCtx) {
u8 func_80BB1B14(EnGeg* this, GlobalContext* globalCtx) {
Actor* explosive;
- Actor* mm = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_EN_MM);
+ Actor* mm = SubS_FindActor(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_EN_MM);
if (mm != NULL) {
this->unk_4B0 = Math_Vec3f_Yaw(&this->actor.world.pos, &mm->world.pos);
diff --git a/src/overlays/actors/ovl_En_Giant/z_en_giant.c b/src/overlays/actors/ovl_En_Giant/z_en_giant.c
index 69e615372..bb131a020 100644
--- a/src/overlays/actors/ovl_En_Giant/z_en_giant.c
+++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.c
@@ -5,6 +5,7 @@
*/
#include "z_en_giant.h"
+#include "objects/object_giant/object_giant.h"
#define FLAGS 0x00000030
@@ -31,41 +32,21 @@ const ActorInit En_Giant_InitVars = {
(ActorFunc)EnGiant_Draw,
};
-extern AnimationHeader D_06002168;
-extern Gfx D_06005A80[];
-extern Gfx D_06006280[];
-extern Gfx D_06007610[];
-extern Gfx D_06006A80[];
-extern FlexSkeletonHeader D_060079B0;
-extern AnimationHeader D_06008394;
-extern AnimationHeader D_060096E4;
-extern AnimationHeader D_0600A1C4;
-extern AnimationHeader D_0600ACA4;
-extern AnimationHeader D_0600B784;
-extern AnimationHeader D_0600C5D4;
-extern AnimationHeader D_0600D040;
-extern AnimationHeader D_0600DE84;
-extern AnimationHeader D_060102A4;
-extern AnimationHeader D_060116E4;
-extern AnimationHeader D_06012A38;
-extern AnimationHeader D_06013004;
-extern AnimationHeader D_06013FE8;
-extern AnimationHeader D_06015334;
-extern AnimationHeader D_06017944;
-
-static AnimationHeader* sAnimationTable[] = {
- &D_06008394, &D_060096E4, &D_060102A4, &D_060116E4, &D_06012A38, &D_06013004, &D_06013FE8, &D_06015334,
- &D_06017944, &D_0600A1C4, &D_0600D040, &D_0600DE84, &D_0600ACA4, &D_0600B784, &D_0600C5D4,
+static AnimationHeader* sAnimations[] = {
+ &gGiantLookUpStartAnim, &gGiantLookUpLoopAnim, &gGiantFallingOverAnim, &gGiantRaisedArmsStartAnim,
+ &gGiantRaisedArmsLoopAnim, &gGiantStruggleStartAnim, &gGiantStruggleLoopAnim, &gGiantIdleAnim,
+ &gGiantWalkingAnim, &gGiantBigCallStartAnim, &gGiantBigCallLoopAnim, &gGiantBigCallEndAnim,
+ &gGiantSmallCallStartAnim, &gGiantSmallCallLoopAnim, &gGiantSmallCallEndAnim,
};
void EnGiant_ChangeAnimation(EnGiant* this, s16 newAnimationId) {
if (newAnimationId >= GIANT_ANIMATION_LOOK_UP_START && newAnimationId < GIANT_ANIMATION_MAX) {
if ((this->animationId == GIANT_ANIMATION_WALKING_LOOP && newAnimationId != GIANT_ANIMATION_WALKING_LOOP) ||
(newAnimationId == GIANT_ANIMATION_WALKING_LOOP && this->animationId != GIANT_ANIMATION_WALKING_LOOP)) {
- Animation_Change(&this->skelAnime, sAnimationTable[newAnimationId], 1.0f, 0.0f,
- Animation_GetLastFrame(&sAnimationTable[newAnimationId]->common), 2, 10.0f);
+ Animation_Change(&this->skelAnime, sAnimations[newAnimationId], 1.0f, 0.0f,
+ Animation_GetLastFrame(&sAnimations[newAnimationId]->common), 2, 10.0f);
} else {
- Animation_PlayOnce(&this->skelAnime, sAnimationTable[newAnimationId]);
+ Animation_PlayOnce(&this->skelAnime, sAnimations[newAnimationId]);
}
this->animationId = newAnimationId;
}
@@ -118,7 +99,8 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) {
this->actor.uncullZoneScale = 2000.0f;
this->actor.uncullZoneDownward = 2400.0f;
Actor_SetScale(&this->actor, 0.32f);
- SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060079B0, &D_06002168, this->jointTable, this->morphTable, 16);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGiantSkel, &gGiantLargeStrideAnim, this->jointTable,
+ this->morphTable, GIANT_LIMB_MAX);
EnGiant_ChangeAnimation(this, GIANT_ANIMATION_IDLE_LOOP);
this->csAction = GIANT_CS_ACTION_NONE;
this->actionFunc = EnGiant_PerformCutsceneActions;
@@ -131,20 +113,20 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) {
case GIANT_TYPE_CANYON_TERMINA_FIELD:
case GIANT_TYPE_CANYON_CLOCK_TOWER_SUCCESS:
case GIANT_TYPE_CANYON_GIANTS_CHAMBER_AND_ENDING:
- this->unk_24A = 0x1C6;
+ this->actorActionCommand = 0x1C6;
break;
case GIANT_TYPE_SWAMP_TERMINA_FIELD:
case GIANT_TYPE_SWAMP_CLOCK_TOWER_SUCCESS:
case GIANT_TYPE_SWAMP_GIANTS_CHAMBER_AND_ENDING:
- this->unk_24A = 0x1C7;
+ this->actorActionCommand = 0x1C7;
break;
case GIANT_TYPE_OCEAN_TERMINA_FIELD:
case GIANT_TYPE_OCEAN_CLOCK_TOWER_SUCCESS:
case GIANT_TYPE_OCEAN_GIANTS_CHAMBER_AND_ENDING:
- this->unk_24A = 0x1C8;
+ this->actorActionCommand = 0x1C8;
break;
default:
- this->unk_24A = 0x1C5;
+ this->actorActionCommand = 0x1C5;
break;
}
@@ -153,11 +135,12 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_MarkForDeath(&this->actor);
return;
}
- this->unk_24A = 0x1C5;
+ this->actorActionCommand = 0x1C5;
Actor_SetScale(&this->actor, 0.32f);
this->actionFunc = EnGiant_PerformClockTowerSuccessActions;
- Animation_Change(&this->skelAnime, &D_060116E4, 0.0f, Animation_GetLastFrame(&D_060116E4) - 1.0f,
- Animation_GetLastFrame(&D_060116E4), 2, 0.0f);
+ Animation_Change(&this->skelAnime, &gGiantRaisedArmsStartAnim, 0.0f,
+ Animation_GetLastFrame(&gGiantRaisedArmsStartAnim) - 1.0f,
+ Animation_GetLastFrame(&gGiantRaisedArmsStartAnim), 2, 0.0f);
this->actor.draw = EnGiant_Draw;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = 0.0f;
@@ -167,7 +150,8 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) {
if (GIANT_TYPE_IS_CLOCK_TOWER_FAILURE(type)) {
Actor_SetScale(&this->actor, 0.32f);
this->actionFunc = EnGiant_PlayClockTowerFailureAnimation;
- Animation_Change(&this->skelAnime, &D_06013FE8, 1.0f, 0.0f, Animation_GetLastFrame(&D_06013004), 0, 0.0f);
+ Animation_Change(&this->skelAnime, &gGiantStruggleLoopAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gGiantStruggleStartAnim), 0, 0.0f);
this->actor.draw = EnGiant_Draw;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = 0.0f;
@@ -204,7 +188,7 @@ void EnGiant_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
/**
- * The animations in sAnimationTable are organized such that looping animations
+ * The animations in sAnimations are organized such that looping animations
* appear immediately after their respective starting animations. The point of
* this function is to play the requested start animation if it has not been
* played yet and play the respetive looping animation otherwise.
@@ -266,8 +250,9 @@ void EnGiant_ChangeAnimationBasedOnCsAction(EnGiant* this) {
}
break;
case GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER:
- Animation_Change(&this->skelAnime, &D_060116E4, 0.0f, Animation_GetLastFrame(&D_060116E4) - 1.0f,
- Animation_GetLastFrame(&D_060116E4), 2, 0.0f);
+ Animation_Change(&this->skelAnime, &gGiantRaisedArmsStartAnim, 0.0f,
+ Animation_GetLastFrame(&gGiantRaisedArmsStartAnim) - 1.0f,
+ Animation_GetLastFrame(&gGiantRaisedArmsStartAnim), 2, 0.0f);
break;
}
}
@@ -352,20 +337,19 @@ void EnGiant_PlaySound(EnGiant* this) {
void EnGiant_UpdatePosition(EnGiant* this, GlobalContext* globalCtx, u32 actionIndex) {
CsCmdActorAction* actorAction = globalCtx->csCtx.npcActions[actionIndex];
- f32 floatUnk10 = actorAction->unk0C.y;
+ f32 startPosY = actorAction->unk0C.y;
s32 pad[2];
- f32 floatUnk1C = actorAction->unk18.y;
- f32 functionTemp;
+ f32 endPosY = actorAction->unk18.y;
+ f32 scale = func_800F5A8C(actorAction->endFrame, actorAction->startFrame, globalCtx->csCtx.frames, globalCtx);
- functionTemp = func_800F5A8C(actorAction->endFrame, actorAction->startFrame, globalCtx->csCtx.frames, globalCtx);
- this->actor.world.pos.y = ((floatUnk1C - floatUnk10) * functionTemp) + floatUnk10;
+ this->actor.world.pos.y = ((endPosY - startPosY) * scale) + startPosY;
}
void EnGiant_PerformClockTowerSuccessActions(EnGiant* this, GlobalContext* globalCtx) {
- if (func_800EE29C(globalCtx, this->unk_24A)) {
- EnGiant_UpdatePosition(this, globalCtx, func_800EE200(globalCtx, this->unk_24A));
- if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0) {
- this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0;
+ if (func_800EE29C(globalCtx, this->actorActionCommand)) {
+ EnGiant_UpdatePosition(this, globalCtx, func_800EE200(globalCtx, this->actorActionCommand));
+ if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0) {
+ this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0;
EnGiant_ChangeAnimationBasedOnCsAction(this);
}
EnGiant_UpdateAlpha(this);
@@ -385,10 +369,10 @@ void EnGiant_PlayClockTowerFailureAnimation(EnGiant* this, GlobalContext* global
void EnGiant_PerformCutsceneActions(EnGiant* this, GlobalContext* globalCtx) {
this->actor.draw = EnGiant_Draw;
- if (func_800EE29C(globalCtx, this->unk_24A)) {
- func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, this->unk_24A));
- if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0) {
- this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0;
+ if (func_800EE29C(globalCtx, this->actorActionCommand)) {
+ func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, this->actorActionCommand));
+ if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0) {
+ this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0;
EnGiant_ChangeAnimationBasedOnCsAction(this);
}
EnGiant_UpdateAlpha(this);
@@ -427,10 +411,10 @@ void EnGiant_Update(Actor* thisx, GlobalContext* globalCtx) {
}
void EnGiant_PostLimbDrawOpa(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
- if (limbIndex == 1) {
+ if (limbIndex == GIANT_LIMB_HEAD) {
OPEN_DISPS(globalCtx->state.gfxCtx);
- gSPDisplayList(POLY_OPA_DISP++, D_06007610);
+ gSPDisplayList(POLY_OPA_DISP++, gGiantBeardDL);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
@@ -440,21 +424,15 @@ void EnGiant_PostLimbDrawXlu(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis
Gfx** gfx) {
EnGiant* this = THIS;
- if (limbIndex == 1) {
- Matrix_CopyCurrentState(&this->unk_254);
+ if (limbIndex == GIANT_LIMB_HEAD) {
+ Matrix_CopyCurrentState(&this->headDrawMtxF);
}
}
void EnGiant_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGiant* this = THIS;
-
- /**
- * 0 = eyes fully open face
- * 1 = eyes half-closed face
- * 2 = eyes fully closed face
- */
- static TexturePtr sFaceTextures[] = { D_06005A80, D_06006280, D_06006A80 };
+ static TexturePtr sFaceTextures[] = { gGiantFaceEyeOpenTex, gGiantFaceEyeHalfTex, gGiantFaceEyeClosedTex };
if (this->alpha > 0) {
OPEN_DISPS(globalCtx->state.gfxCtx);
@@ -479,10 +457,10 @@ void EnGiant_Draw(Actor* thisx, GlobalContext* globalCtx) {
POLY_XLU_DISP =
SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, NULL, EnGiant_PostLimbDrawXlu, thisx, POLY_XLU_DISP);
- Matrix_InsertMatrix(&this->unk_254, MTXMODE_NEW);
+ Matrix_InsertMatrix(&this->headDrawMtxF, MTXMODE_NEW);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_XLU_DISP++, D_06007610);
+ gSPDisplayList(POLY_XLU_DISP++, gGiantBeardDL);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
diff --git a/src/overlays/actors/ovl_En_Giant/z_en_giant.h b/src/overlays/actors/ovl_En_Giant/z_en_giant.h
index 6f50370f7..e28aa2a32 100644
--- a/src/overlays/actors/ovl_En_Giant/z_en_giant.h
+++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.h
@@ -86,6 +86,26 @@ typedef enum {
/* 15 */ GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER
} GiantCsActionIndex;
+typedef enum {
+ /* 0 */ GIANT_LIMB_NONE,
+ /* 1 */ GIANT_LIMB_HEAD,
+ /* 2 */ GIANT_LIMB_LEFT_THIGH,
+ /* 3 */ GIANT_LIMB_LEFT_LOWER_LEG,
+ /* 4 */ GIANT_LIMB_LEFT_FOOT,
+ /* 5 */ GIANT_LIMB_RIGHT_THIGH,
+ /* 6 */ GIANT_LIMB_RIGHT_LOWER_LEG,
+ /* 7 */ GIANT_LIMB_RIGHT_FOOT,
+ /* 8 */ GIANT_LIMB_LEFT_SHOULDER,
+ /* 9 */ GIANT_LIMB_LEFT_UPPER_ARM,
+ /* 10 */ GIANT_LIMB_LEFT_FOREARM,
+ /* 11 */ GIANT_LIMB_LEFT_HAND,
+ /* 12 */ GIANT_LIMB_RIGHT_SHOULDER,
+ /* 13 */ GIANT_LIMB_RIGHT_UPPER_ARM,
+ /* 14 */ GIANT_LIMB_RIGHT_FOREARM,
+ /* 15 */ GIANT_LIMB_RIGHT_HAND,
+ /* 16 */ GIANT_LIMB_MAX,
+} EnGiantLimbs;
+
struct EnGiant;
typedef void (*EnGiantActionFunc)(struct EnGiant*, GlobalContext*);
@@ -93,14 +113,14 @@ typedef void (*EnGiantActionFunc)(struct EnGiant*, GlobalContext*);
typedef struct EnGiant {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
- /* 0x188 */ Vec3s jointTable[16];
- /* 0x1E8 */ Vec3s morphTable[16];
+ /* 0x188 */ Vec3s jointTable[GIANT_LIMB_MAX];
+ /* 0x1E8 */ Vec3s morphTable[GIANT_LIMB_MAX];
/* 0x248 */ s16 animationId;
- /* 0x24A */ u16 unk_24A;
+ /* 0x24A */ u16 actorActionCommand;
/* 0x24C */ u16 csAction;
/* 0x24E */ s16 alpha;
/* 0x250 */ u16 sfxId;
- /* 0x254 */ MtxF unk_254;
+ /* 0x254 */ MtxF headDrawMtxF;
/* 0x294 */ s16 faceIndex;
/* 0x296 */ s16 blinkTimer;
/* 0x298 */ EnGiantActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/src/overlays/actors/ovl_En_Gm/z_en_gm.c
index 347bc6cd6..03b0cfb45 100644
--- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c
+++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c
@@ -159,7 +159,7 @@ Actor* func_8094DEE0(EnGm* this, GlobalContext* globalCtx, u8 arg2, s16 arg3) {
Actor* actor;
while (true) {
- actor = func_ActorCategoryIterateById(globalCtx, foundActor, arg2, arg3);
+ actor = SubS_FindActor(globalCtx, foundActor, arg2, arg3);
foundActor = actor;
if (actor == NULL) {
break;
@@ -212,7 +212,7 @@ EnDoor* func_8094DF90(GlobalContext* globalCtx, s32 arg1) {
phi_a1 = -1;
}
- return (EnDoor*)func_8013A7C0(globalCtx, phi_a1);
+ return SubS_FindDoor(globalCtx, phi_a1);
}
s32 func_8094DFF8(EnGm* this, GlobalContext* globalCtx) {
diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.c b/src/overlays/actors/ovl_En_Go/z_en_go.c
index a79aef7ea..0e86bfc37 100644
--- a/src/overlays/actors/ovl_En_Go/z_en_go.c
+++ b/src/overlays/actors/ovl_En_Go/z_en_go.c
@@ -5,6 +5,10 @@
*/
#include "z_en_go.h"
+#include "objects/object_oF1d_map/object_oF1d_map.h"
+#include "objects/object_hakugin_demo/object_hakugin_demo.h"
+#include "objects/object_taisou/object_taisou.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x02000019
@@ -23,8 +27,56 @@ void func_80A14EB0(EnGo* this, GlobalContext* globalCtx);
void func_80A14FC8(EnGo* this, GlobalContext* globalCtx);
void func_80A153FC(EnGo* this, GlobalContext* globalCtx);
void func_80A157C4(EnGo* this, GlobalContext* globalCtx);
+void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx);
+
+static s32 D_80A16100[] = {
+ 0x00150800, 0x40010022, 0x00150200, 0x180E0E10, 0x0C0F0E11, 0x0C0F0E12, 0x0C0F0E13, 0x0C0F0E14, 0x0C111502,
+ 0x100E0E15, 0x0C100015, 0x0400110E, 0x0E160C0F, 0x0E170C0F, 0x0E180C11, 0x15041610, 0x0E0E190C, 0x10001504,
+ 0x000D0100, 0x050E0E31, 0x0C100E0E, 0x2F0C1001, 0x00050E0E, 0x2D0C100E, 0x0E2B0C10,
+};
+
+static s32 D_80A16164[] = {
+ 0x00150800, 0x7E01004D, 0x00150400, 0x180E0E1A, 0x0C170F0E, 0x230C180F, 0x0E240C0F, 0x0E250C12, 0x16111508,
+ 0x100E0E1A, 0x0C170F0E, 0x230C180F, 0x0E240C0F, 0x0E250C17, 0x0F0E260C, 0x180F0E27, 0x0C170F0E, 0x280C180F,
+ 0x0E290C17, 0x0F0E2A0C, 0x16111508, 0x100E0E1A, 0x0C170F0E, 0x1B0C180F, 0x0E1C0C0F, 0x0E1D0C0F, 0x0E1E0C17,
+ 0x0F0E1F0C, 0x180F0E20, 0x0C170F0E, 0x210C0F0E, 0x220C1611, 0x15081000, 0x1504000D, 0x0100050E, 0x0E320C10,
+ 0x0E0E300C, 0x10010005, 0x0E0E2E0C, 0x100E0E2C, 0x0C100000,
+};
+
+static s32 D_80A16208[2] = { 0xE0E520C, 0x10000000 };
+
+static s32 D_80A16210[17] = {
+ 0x160400, 0x38010010, 0xE0E430C, 0xF0E440C, 0xF0E450C, 0x11188010, 0x160800, 0x1B0E0E46, 0xC0F0E47,
+ 0xC0F0E48, 0xC0F0E49, 0xC0F0E4A, 0xC111608, 0x11188010, 0xE0E4B0C, 0x100E0E42, 0xC100000,
+};
+
+static s32 D_80A16254[11] = {
+ 0x160400, 0x22010009, 0xE0E4D0C, 0xF0E4E0C, 0x10001701, 0xC0E0E,
+ 0x4F0C0F0E, 0x500C1117, 0x1100E0E, 0x510C100E, 0xE4C0C10,
+};
+
+static s32 D_80A16280[52] = {
+ 0x1001200, 0x12200008, 0xE0C8E0C, 0x11122010, 0xE0C8F0C, 0x10001240, 0x1D0E0C, 0x800C1112, 0x40001280,
+ 0x742500, 0xC006F00, 0x13010045, 0xF0C810C, 0x19001300, 0x1280005E, 0x25000C00, 0x59001301, 0x2F0E0C,
+ 0x810C0F0C, 0x820C0500, 0x1A00, 0x1A300E0C, 0x830C1209, 0x700, 0xE0C84, 0x160C1113, 0x1100E0C,
+ 0x840C1031, 0xE0C850C, 0x1029FFF2, 0x130200, 0xF0E0C88, 0xC0F0C89, 0xC05000A, 0xFFE3FFE3, 0xE0C860C,
+ 0x11128019, 0x213019, 0xFFC02900, 0x2C0E0C8C, 0xC050000, 0x50000, 0x8006400, 0x6320E0C, 0x8D0C1030,
+ 0x14FF9C12, 0x6003400, 0x130034, 0x700000E, 0xC870C16, 0x100E0C8B, 0xC100000,
+};
+
+static s32 D_80A16350[27] = {
+ 0x584000, 0x2903000E, 0x2001301, 0x180058, 0x80005119, 0x1E0059, 0x1004919, 0x160059, 0x2004119,
+ 0xE0059, 0x4003919, 0x2F0E0D, 0x4D0C1210, 0xE0D480C, 0xF0D490C, 0xF0D4A0C, 0x5000000, 0xF000F30,
+ 0xE0D4B0C, 0x15090000, 0xE0D4D0C, 0x1210310E, 0xD4C0C12, 0x100E0D4E, 0xC19FFD8, 0xE0D4F0C, 0x19FFD500,
+};
+
+static s32 D_80A163BC[4] = { 0x100060E, 0xDFE0C12, 0x100E0DFF, 0xC121000 };
+static s32 D_80A163CC[4] = { 0x100060E, 0xE000C12, 0x100E0E01, 0xC121000 };
+static s32 D_80A163DC[4] = { 0x100060E, 0xE020C12, 0x100E0E03, 0xC121000 };
+static s32 D_80A163EC[4] = { 0x100060E, 0xE040C12, 0x100E0E05, 0xC121000 };
+static s32 D_80A163FC[4] = { 0x100060E, 0xE060C12, 0x100E0E07, 0xC121000 };
+static s32 D_80A1640C[2] = { 0xE023A0C, 0x12100000 };
-#if 0
const ActorInit En_Go_InitVars = {
ACTOR_EN_GO,
ACTORCAT_NPC,
@@ -37,32 +89,69 @@ const ActorInit En_Go_InitVars = {
(ActorFunc)NULL,
};
-// static ColliderSphereInit sSphereInit = {
-static ColliderSphereInit D_80A16434 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, },
- { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderSphereInit sSphereInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_SPHERE,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x20000000, 0x00, 0x04 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 0 }, 100 },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A16460 = {
- { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x02, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit1 = {
+ {
+ COLTYPE_METAL,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK2,
+ { 0xF7CFFFFF, 0x02, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, 0, 0, { 0, 0, 0 } },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A1648C = {
- { COLTYPE_HIT1, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit2 = {
+ {
+ COLTYPE_HIT1,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK1,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, 0, 0, { 0, 0, 0 } },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_80A164B8 = { 0, 0, 0, 0, MASS_IMMOVABLE };
+static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE };
-// static DamageTable sDamageTable = {
-static DamageTable D_80A164C4 = {
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(1, 0x0),
/* Deku Stick */ DMG_ENTRY(1, 0x0),
/* Horse trample */ DMG_ENTRY(1, 0x0),
@@ -97,156 +186,1887 @@ static DamageTable D_80A164C4 = {
/* Powder Keg */ DMG_ENTRY(1, 0x0),
};
+static ActorAnimationEntryS sAnimations[] = {
+ { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, 0 }, { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, -4 },
+ { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, 0 }, { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, -4 },
+ { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, 2, 0 }, { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, 0 },
+ { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, -4 }, { &object_oF1d_map_Anim_0039D8, 1.0f, 0, -1, 2, -4 },
+ { &object_oF1d_map_Anim_003650, 1.0f, 0, -1, 0, 0 }, { &object_oF1d_map_Anim_0135E8, 1.0f, 0, -1, 2, -4 },
+
+ { &object_taisou_Anim_004DD4, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_0016C8, 1.0f, 0, -1, 0, 0 },
+ { &object_taisou_Anim_00283C, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_007764, 1.0f, 0, -1, 0, 0 },
+ { &object_taisou_Anim_005EE0, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_002C48, 1.0f, 0, -1, 0, 0 },
+ { &object_taisou_Anim_0031D8, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_005790, 1.0f, 0, -1, 0, 0 },
+
+ { &object_hakugin_demo_Anim_001420, 1.0f, 0, -1, 2, 0 }, { &object_hakugin_demo_Anim_001A4C, 1.0f, 0, -1, 0, -4 },
+ { &object_hakugin_demo_Anim_002704, 1.0f, 0, -1, 2, 0 }, { &object_hakugin_demo_Anim_003378, 1.0f, 0, -1, 0, -4 },
+};
+
+EnGoStruct* func_80A10FD0(EnGoStruct ptr[], Vec3f arg1, Vec3f arg2, Vec3f arg3, f32 arg4, f32 arg5, s32 arg6) {
+ s32 i;
+
+ for (i = 16; i < 32; i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_00 = 7;
+ ptr->unk_01 = (Rand_ZeroOne() * (2.0f * (arg6 / 3.0f))) + (arg6 / 3.0f);
+ ptr->unk_02 = ptr->unk_01;
+ ptr->unk_10 = arg1;
+ ptr->unk_1C = arg2;
+ ptr->unk_28 = arg3;
+ ptr->unk_34 = arg4;
+ ptr->unk_38 = arg5;
+ break;
+ }
+ }
+
+ return ptr;
+}
+
+void func_80A11144(EnGoStruct ptr[], GlobalContext* globalCtx) {
+ s32 pad;
+ s32 i;
+ s32 flag = false;
+ f32 temp;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 32; i++, ptr++) {
+
+ if (ptr->unk_00 == 7) {
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ if (!flag) {
+ gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_0031A0);
+ flag = true;
+ }
+
+ Matrix_StatePush();
+
+ temp = ((f32)ptr->unk_02 / ptr->unk_01);
+ temp *= 255;
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (u8)temp);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (ptr->unk_02 + (i * 3)) * 3,
+ (ptr->unk_02 + (i * 3)) * 15, 0x20, 0x40, 1, 0, 0, 0x20, 0x20));
+
+ Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(ptr->unk_34, ptr->unk_34, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_003258);
+
+ Matrix_StatePop();
+ if (globalCtx->state.gfxCtx) {}
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A1143C(EnGoStruct ptr[], Vec3f arg1, Vec3f arg2, Vec3f arg3, f32 arg4, f32 arg5, s32 arg6, s32 arg7) {
+ s32 i;
+
+ for (i = 16; i < 32; i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_00 = arg7 + 4;
+
+ ptr->unk_01 = (Rand_ZeroOne() * (2.0f * (arg6 / 3.0f))) + (arg6 / 3.0f);
+ ptr->unk_02 = ptr->unk_01;
+
+ ptr->unk_10 = arg1;
+ ptr->unk_1C = arg2;
+ ptr->unk_28 = arg3;
+ ptr->unk_34 = arg4;
+ ptr->unk_38 = arg5;
+ break;
+ }
+ }
+}
+
+void func_80A115B4(EnGoStruct ptr[], GlobalContext* globalCtx) {
+ static TexturePtr D_80A16644[] = {
+ &gameplay_keep_Tex_08F7E0, &gameplay_keep_Tex_08F3E0, &gameplay_keep_Tex_08EFE0, &gameplay_keep_Tex_08EBE0,
+ &gameplay_keep_Tex_08E7E0, &gameplay_keep_Tex_08E3E0, &gameplay_keep_Tex_08DFE0, &gameplay_keep_Tex_08DBE0,
+ };
+ static Color_RGBA8 D_80A16664[] = {
+ { 255, 255, 255, 0 },
+ { 170, 130, 90, 0 },
+ { 0, 0, 0, 0 },
+ };
+ static Color_RGBA8 D_80A16670[] = {
+ { 255, 255, 255, 0 },
+ { 100, 60, 20, 0 },
+ { 0, 0, 0, 0 },
+ };
+ s32 i;
+ u8 flag = false;
+ f32 temp;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 32; i++, ptr++) {
+ if ((ptr->unk_00 >= 4) && (ptr->unk_00 < 7)) {
+ if (!flag) {
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
+ gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014CF0);
+ flag = true;
+ }
+ Matrix_StatePush();
+
+ temp = (f32)ptr->unk_02 / ptr->unk_01;
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80A16664[(s32)ptr->unk_00 - 4].r,
+ D_80A16664[(s32)ptr->unk_00 - 4].g, D_80A16664[(s32)ptr->unk_00 - 4].b, (u8)(temp * 255));
+ gDPSetEnvColor(POLY_XLU_DISP++, D_80A16670[(s32)ptr->unk_00 - 4].r, D_80A16670[(s32)ptr->unk_00 - 4].g,
+ D_80A16670[(s32)ptr->unk_00 - 4].b, 0);
+
+ Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW);
+ Matrix_Scale(ptr->unk_34, ptr->unk_34, 1.0f, MTXMODE_APPLY);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A16644[(s32)(temp * 7.0f)]));
+ gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014D00);
+
+ Matrix_StatePop();
+ }
+ if (globalCtx->state.gfxCtx) {}
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+#ifdef NON_MATCHING
+void func_80A118F8(EnGoStruct ptr[32], Vec3f arg1) {
+ static u8 D_80A1667C[] = {
+ 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2,
+ };
+ EnGoStruct* ptr2 = &ptr[16];
+ s32 i;
+ Vec3f spB4;
+ Vec3f spA8;
+ f32 temp_f20;
+
+ for (i = 0; i < 16; i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_10 = arg1;
+ ptr->unk_10.y += 56.0f;
+
+ ptr->unk_04.x = (Rand_ZeroOne() - 0.5f) * 5460.0f;
+ ptr->unk_04.y = (Rand_ZeroOne() - 0.5f) * 5460.0f;
+ ptr->unk_04.z = (Rand_ZeroOne() - 0.5f) * 5460.0f;
+
+ temp_f20 = (Rand_ZeroOne() * 4.0f) + 6.0f;
+ ptr->unk_28.x = Math_SinS(i * 0x1000) * temp_f20;
+ ptr->unk_28.z = Math_CosS(i * 0x1000) * temp_f20;
+ ptr->unk_28.y = (Rand_ZeroOne() * 3.0f) + 6.0f;
+
+ ptr->unk_1C = gZeroVec3f;
+ ptr->unk_1C.y = -0.8f;
+
+ ptr->unk_01 = ptr->unk_02 = 1;
+ ptr->unk_00 = D_80A1667C[i];
+
+ spB4.x = ((Rand_ZeroOne() - 0.5f) * 80.0f) + ptr->unk_10.x;
+ spB4.y = ((Rand_ZeroOne() - 0.5f) * 40.0f) + ptr->unk_10.y;
+ spB4.z = ((Rand_ZeroOne() - 0.5f) * 80.0f) + ptr->unk_10.z;
+
+ spA8 = gZeroVec3f;
+ spA8.y = (Rand_ZeroOne() * 3.0f) + 1.0f;
+
+ func_80A1143C(ptr2, spB4, gZeroVec3f, spA8, 0.6f, 0.2f, 16, 0);
+ }
+ }
+}
+#else
+static u8 D_80A1667C[] = {
+ 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2,
+};
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A118F8.s")
#endif
-extern ColliderSphereInit D_80A16434;
-extern ColliderCylinderInit D_80A16460;
-extern ColliderCylinderInit D_80A1648C;
-extern CollisionCheckInfoInit2 D_80A164B8;
-extern DamageTable D_80A164C4;
+void func_80A11BF8(EnGoStruct ptr[], f32 arg1) {
+ f32 test;
+ f32 test2;
+ f32 x;
+ f32 z;
-extern UNK_TYPE D_06000458;
-extern UNK_TYPE D_06003258;
-extern UNK_TYPE D_060091A8;
-extern UNK_TYPE D_06011AC8;
-extern UNK_TYPE D_06014D00;
+ ptr->unk_10.x += ptr->unk_28.x;
+ ptr->unk_10.y += ptr->unk_28.y;
+ ptr->unk_10.z += ptr->unk_28.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A10FD0.s")
+ ptr->unk_28.y += ptr->unk_1C.y;
+ ptr->unk_34 += ptr->unk_38;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11144.s")
+ if (ptr->unk_10.y < arg1) {
+ ptr->unk_10.y = arg1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1143C.s")
+ ptr->unk_00 = 4;
+ ptr->unk_01 = (Rand_ZeroOne() * 8.0f) + 4.0f;
+ ptr->unk_02 = ptr->unk_01;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A115B4.s")
+ ptr->unk_28 = gZeroVec3f;
+ ptr->unk_28.y = (Rand_ZeroOne() * 3.0f) + 1.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A118F8.s")
+ ptr->unk_34 = 0.4f;
+ ptr->unk_38 = 0.1f;
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11BF8.s")
+ if (ptr->unk_28.x != 0.0f) {
+ x = ptr->unk_28.x / fabsf(ptr->unk_28.x);
+ x *= ((sREG(13) + 140) * 0.01f);
+ Math_StepToF(&ptr->unk_28.x, x, (sREG(14) + 40) * 0.01f);
+ }
+ if (ptr->unk_28.z != 0.0f) {
+ z = ptr->unk_28.z / fabsf(ptr->unk_28.z);
+ z *= ((sREG(13) + 140) * 0.01f);
+ Math_StepToF(&ptr->unk_28.z, z, (sREG(14) + 40) * 0.01f);
+ }
+
+ ptr->unk_0A.x += ptr->unk_04.x;
+ ptr->unk_0A.y += ptr->unk_04.y;
+ ptr->unk_0A.z += ptr->unk_04.z;
+}
+
+#ifdef NON_MATCHING
+void func_80A11EC0(EnGoStruct ptr[], GlobalContext* globalCtx, Gfx arg2[], Gfx arg3[], u8 arg4) {
+ s32 i;
+ u8 flag = false;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 16; i++, ptr++) {
+ if (ptr->unk_00 == arg4) {
+ if (!flag) {
+ gSPDisplayList(POLY_OPA_DISP++, arg2);
+ flag = true;
+ }
+
+ Matrix_StatePush();
+ Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW);
+ Matrix_Scale(0.08f, 0.08f, 0.08f, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(ptr->unk_0A.z, MTXMODE_APPLY);
+ Matrix_InsertXRotation_s(ptr->unk_0A.x, MTXMODE_APPLY);
+ Matrix_RotateY(ptr->unk_0A.y, MTXMODE_APPLY);
+
+ if (1) {
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, arg3);
+ }
+
+ Matrix_StatePop();
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11EC0.s")
+#endif
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1203C.s")
+void func_80A1203C(EnGo* this) {
+ EnGoStruct* ptr = this->unk_3F8;
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1213C.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++, ptr++) {
+ if (ptr->unk_00 != 0) {
+ if (ptr->unk_02 == 0) {
+ ptr->unk_00 = 0;
+ } else if ((ptr->unk_00 > 0) && (ptr->unk_00 < 4)) {
+ func_80A11BF8(ptr, this->actor.world.pos.y);
+ } else {
+ ptr->unk_10.x += ptr->unk_28.x;
+ ptr->unk_10.y += ptr->unk_28.y;
+ ptr->unk_10.z += ptr->unk_28.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A121F4.s")
+ ptr->unk_28.x += ptr->unk_1C.x;
+ ptr->unk_28.y += ptr->unk_1C.y;
+ ptr->unk_28.z += ptr->unk_1C.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1222C.s")
+ ptr->unk_34 += ptr->unk_38;
+ ptr->unk_02--;
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A122EC.s")
+void func_80A1213C(EnGo* this, GlobalContext* globalCtx) {
+ func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_0003D0, object_oF1d_map_DL_000458, 1);
+ func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_0008C0, object_oF1d_map_DL_000948, 2);
+ func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_000D50, object_oF1d_map_DL_000DD8, 3);
+ func_80A11144(this->unk_3F8, globalCtx);
+ func_80A115B4(this->unk_3F8, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A123A0.s")
+s32 func_80A121F4(GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A124A0.s")
+ if ((player->transformation == PLAYER_FORM_GORON) && (player->stateFlags3 & 0x2000000)) {
+ return false;
+ }
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A124FC.s")
+s32 func_80A1222C(EnGo* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s32 ret = false;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A125BC.s")
+ if (((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.ocarinaMode == 3) &&
+ (globalCtx->msgCtx.unk1202E == 1) && (this->unk_3EC == 0) && (this->actor.xzDistToPlayer < 400.0f)) ||
+ (!(gSaveContext.save.weekEventReg[22] & 4) && (globalCtx->sceneNum == SCENE_16GORON_HOUSE) &&
+ (gSaveContext.sceneSetupIndex == 0) && (this->unk_3EC == 0) && (globalCtx->csCtx.unk_12 == 1))) {
+ ret = true;
+ }
+ return ret;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12660.s")
+s32 func_80A122EC(EnGo* this) {
+ static Vec3f D_80A1668C = { 0.0f, 100.0f, 160.0f };
+ s32 pad;
+ f32 sp20 = 58.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A126BC.s")
+ if (ENGO_GET_F(&this->actor) == ENGO_F_8) {
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A1668C,
+ &this->actor.focus.pos);
+ } else {
+ if ((this->unk_390 & 0x200) || (this->unk_390 & 0x100)) {
+ sp20 = this->actor.shape.yOffset;
+ }
+ Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos);
+ this->actor.focus.pos.y += sp20;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12774.s")
+ this->actor.focus.rot.x = this->actor.world.rot.x;
+ this->actor.focus.rot.y = this->actor.world.rot.y;
+ this->actor.focus.rot.z = this->actor.world.rot.z;
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12868.s")
+void func_80A123A0(EnGo* this, GlobalContext* globalCtx) {
+ Vec3f sp2C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12954.s")
+ Math_Vec3f_Copy(&sp2C, &this->actor.world.pos);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12A64.s")
+ this->colliderSphere.dim.worldSphere.center.x = sp2C.x;
+ this->colliderSphere.dim.worldSphere.center.y = sp2C.y;
+ this->colliderSphere.dim.worldSphere.center.y += (s16)this->actor.shape.yOffset;
+ this->colliderSphere.dim.worldSphere.center.z = sp2C.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12B78.s")
+ this->colliderSphere.dim.modelSphere.radius = 48;
+ this->colliderSphere.dim.worldSphere.radius =
+ this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12C48.s")
+ if (func_80A121F4(globalCtx)) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12D6C.s")
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12DF4.s")
+void func_80A124A0(EnGo* this, GlobalContext* globalCtx) {
+ this->colliderSphere.dim.worldSphere.radius =
+ this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale;
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12E80.s")
+void func_80A124FC(EnGo* this, GlobalContext* globalCtx) {
+ Vec3f sp1C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12FE8.s")
+ Math_Vec3f_Copy(&sp1C, &this->actor.world.pos);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A131F8.s")
+ this->colliderSphere.dim.worldSphere.center.x = sp1C.x;
+ this->colliderSphere.dim.worldSphere.center.y = sp1C.y;
+ this->colliderSphere.dim.worldSphere.center.y += (s16)this->actor.shape.yOffset;
+ this->colliderSphere.dim.worldSphere.center.z = sp1C.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A132C8.s")
+ this->colliderSphere.dim.modelSphere.radius = 20;
+ this->colliderSphere.dim.worldSphere.radius =
+ this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A133A8.s")
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13400.s")
+void func_80A125BC(EnGo* this, GlobalContext* globalCtx) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A134B0.s")
+ Math_Vec3f_ToVec3s(&this->colliderCylinder.dim.pos, &this->actor.world.pos);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A134F4.s")
+ this->colliderCylinder.dim.radius = 46;
+ this->colliderCylinder.dim.height = 78;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13564.s")
+ if (this->unk_3C6 == 0) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+ }
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A136B8.s")
+void func_80A12660(EnGo* this, GlobalContext* globalCtx) {
+ Math_Vec3f_ToVec3s(&this->colliderCylinder.dim.pos, &this->actor.world.pos);
+ this->colliderCylinder.dim.radius = 24;
+ this->colliderCylinder.dim.height = 62;
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13728.s")
+void func_80A126BC(EnGo* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A137C0.s")
+ if (!(player->stateFlags2 & 0x4000)) {
+ if (this->unk_3C6 != 0) {
+ this->unk_3C6--;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A139E4.s")
+ if (ENGO_GET_F(&this->actor) == ENGO_F_8) {
+ func_80A124A0(this, globalCtx);
+ } else if (this->unk_390 & 0x100) {
+ func_80A123A0(this, globalCtx);
+ } else if (this->unk_390 & 0x200) {
+ func_80A124FC(this, globalCtx);
+ } else if (this->unk_390 & 0x400) {
+ func_80A125BC(this, globalCtx);
+ } else {
+ func_80A12660(this, globalCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13B1C.s")
+s32 func_80A12774(EnGo* this, GlobalContext* globalCtx) {
+ if (!(this->unk_390 & 7) || !func_800B84D0(&this->actor, globalCtx)) {
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13E80.s")
+ if ((ENGO_GET_F(&this->actor) != ENGO_F_8) && (ENGO_GET_F(&this->actor) != ENGO_F_1)) {
+ if (!(this->unk_390 & 0x200)) {
+ this->unk_390 |= 8;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14018.s")
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_5) || (ENGO_GET_F(&this->actor) == ENGO_F_6) ||
+ (ENGO_GET_F(&this->actor) == ENGO_F_7)) {
+ this->unk_3BC = 0;
+ this->unk_3BE = 0;
+ this->unk_390 |= 0x20;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14104.s")
+ func_8013AED4(&this->unk_390, 0, 7);
+ this->unk_3C0 = 0;
+ this->unk_3C4 = 0;
+ this->unk_18C = this->actionFunc;
+ this->actionFunc = func_80A157C4;
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A141D4.s")
+s32 func_80A12868(EnGo* this, GlobalContext* globalCtx) {
+ this->unk_390 &= ~0x800;
+ this->unk_390 &= ~0x1000;
+ this->unk_390 &= ~0x2000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1428C.s")
+ if ((this->colliderCylinder.base.atFlags & AT_HIT) || (this->colliderSphere.base.atFlags & AT_HIT)) {
+ this->colliderCylinder.base.atFlags &= ~AT_HIT;
+ this->colliderSphere.base.atFlags &= ~AT_HIT;
+ this->unk_390 |= 0x800;
+ this->unk_3C6 = 0x28;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14324.s")
+ if ((this->colliderCylinder.base.acFlags & AC_HIT) || (this->colliderSphere.base.acFlags & AC_HIT)) {
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ this->colliderSphere.base.acFlags &= ~AC_HIT;
+ this->unk_390 |= 0x1000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A143A8.s")
+ if ((this->colliderCylinder.base.ocFlags1 & OC1_HIT) || (this->colliderSphere.base.ocFlags1 & OC1_HIT)) {
+ this->colliderCylinder.base.ocFlags1 &= ~OC1_HIT;
+ this->colliderSphere.base.ocFlags1 &= ~OC1_HIT;
+ this->unk_390 |= 0x2000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14430.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1449C.s")
+s32 func_80A12954(EnGo* this, GlobalContext* globalCtx) {
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_4) && (globalCtx->csCtx.state != 0) && (this->actor.draw != NULL) &&
+ (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA2) && (gSaveContext.sceneSetupIndex == 1) &&
+ (globalCtx->csCtx.unk_12 == 0)) {
+ if (this->unk_3F0 == 0) {
+ this->actor.flags &= ~1;
+ this->unk_394 = 255;
+ this->unk_3F0 = 1;
+ this->unk_18C = this->actionFunc;
+ }
+ func_8013AED4(&this->unk_390, 0, 7);
+ this->actionFunc = func_80A14FC8;
+ } else if (this->unk_3F0 != 0) {
+ this->actor.flags |= 1;
+ this->unk_394 = 255;
+ this->unk_3F0 = 0;
+ func_8013AED4(&this->unk_390, 3, 7);
+ this->actionFunc = this->unk_18C;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A144F4.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A145AC.s")
+s32 func_80A12A64(EnGo* this, GlobalContext* globalCtx) {
+ s8 objIdx = this->actor.objBankIndex;
+ s8 objIdx2 = -1;
+ s32 ret = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14668.s")
+ if ((this->unk_3DC >= 18) && (this->unk_289 >= 0)) {
+ objIdx2 = this->unk_289;
+ } else if ((this->unk_3DC >= 10) && (this->unk_288 >= 0)) {
+ objIdx2 = this->unk_288;
+ } else if (this->unk_3DC < 10) {
+ objIdx2 = this->actor.objBankIndex;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A146CC.s")
+ if (objIdx2 >= 0) {
+ gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx2].segment);
+ this->skelAnime.playSpeed = this->unk_398;
+ ret = SkelAnime_Update(&this->skelAnime);
+ gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx].segment);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14798.s")
+ return ret;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A149B0.s")
+s32 func_80A12B78(EnGo* this, GlobalContext* globalCtx) {
+ if (globalCtx->csCtx.state == 0) {
+ if (this->unk_3DC == 4) {
+ if (Animation_OnFrame(&this->skelAnime, 2.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_CIRCLE);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14B30.s")
+ if (Animation_OnFrame(&this->skelAnime, 22.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_IMT);
+ }
+ } else if ((this->unk_3DC == 2) || (this->unk_3DC == 3)) {
+ if (Animation_OnFrame(&this->skelAnime, 2.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_CIRCLE_OFF);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14E14.s")
+ if (Animation_OnFrame(&this->skelAnime, 24.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_STAND_IMT);
+ }
+ }
+ }
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14E74.s")
+s32 func_80A12C48(EnGo* this, GlobalContext* globalCtx, s32 arg2) {
+ s8 objIdx = this->actor.objBankIndex;
+ s8 objIdx2 = -1;
+ s32 ret = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14EB0.s")
+ if ((arg2 >= 18) && (this->unk_289 >= 0)) {
+ objIdx2 = this->unk_289;
+ } else if ((arg2 >= 10) && (this->unk_288 >= 0)) {
+ objIdx2 = this->unk_288;
+ } else if (arg2 < 10) {
+ objIdx2 = this->actor.objBankIndex;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14FC8.s")
+ if (objIdx2 >= 0) {
+ gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx2].segment);
+ this->unk_3DC = arg2;
+ ret = func_8013BC6C(&this->skelAnime, sAnimations, arg2);
+ this->unk_398 = this->skelAnime.playSpeed;
+ gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx].segment);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A153FC.s")
+ return ret;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15684.s")
+void func_80A12D6C(EnGo* this) {
+ if ((this->unk_390 & 0x20) && (DECR(this->unk_3BC) == 0)) {
+ this->unk_3BE++;
+ if (this->unk_3BE >= 4) {
+ this->unk_3BC = Rand_S16Offset(30, 30);
+ this->unk_3BE = 0;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A157C4.s")
+void func_80A12DF4(EnGo* this, GlobalContext* globalCtx) {
+ if (this->unk_3D4 == 0) {
+ func_80A12C48(this, globalCtx, 9);
+ this->unk_3D4++;
+ } else if ((this->unk_3D4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ func_80A12C48(this, globalCtx, 6);
+ this->unk_3D4++;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Init.s")
+s32 func_80A12E80(EnGo* this, GlobalContext* globalCtx) {
+ u16 temp = globalCtx->msgCtx.unk11F04;
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Destroy.s")
+ if (ENGO_GET_F(&this->actor) != ENGO_F_4) {
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Update.s")
+ if (player->stateFlags1 & 0x40) {
+ if (this->unk_392 != temp) {
+ switch (temp) {
+ case 0xE1A:
+ this->unk_390 |= 8;
+ this->unk_38C = this->actor.child;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15B80.s")
+ case 0xE1D:
+ case 0xE25:
+ if (ENGO_GET_70(&this->actor) == ENGO_70_1) {
+ this->unk_38C = &GET_PLAYER(globalCtx)->actor;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15D04.s")
+ case 0xE27:
+ if (ENGO_GET_70(&this->actor) == ENGO_70_1) {
+ this->unk_38C = this->actor.child;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15E38.s")
+ case 0xE16:
+ case 0xE1E:
+ this->unk_190 = func_80A12DF4;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15FEC.s")
+ case 0xE1F:
+ if (ENGO_GET_70(&this->actor) == ENGO_70_0) {
+ this->unk_38C = &GET_PLAYER(globalCtx)->actor;
+ }
+ break;
+ }
+ }
+ this->unk_3F4 = 1;
+ this->unk_392 = temp;
+ } else if (this->unk_3F4 != 0) {
+ this->unk_3F4 = 0;
+ this->unk_190 = NULL;
+ this->unk_392 = 0;
+ func_80A12C48(this, globalCtx, 5);
+ this->unk_390 &= ~8;
+ }
+
+ if (this->unk_190 != NULL) {
+ this->unk_190(this, globalCtx);
+ }
+
+ return false;
+}
+
+s32 func_80A12FE8(EnGo* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Vec3f sp40;
+ Vec3f sp34;
+ s16 sp32;
+
+ Math_Vec3f_Copy(&sp40, &this->unk_38C->world.pos);
+ Math_Vec3f_Copy(&sp34, &this->actor.world.pos);
+ sp32 = Math_Vec3f_Yaw(&sp34, &sp40);
+
+ Math_ApproachS(&this->unk_3B2, (sp32 - this->unk_3B6) - this->actor.shape.rot.y, 4, 0x2AA8);
+ this->unk_3B2 = CLAMP(this->unk_3B2, -0x1FFE, 0x1FFE);
+
+ Math_ApproachS(&this->unk_3B6, (sp32 - this->unk_3B2) - this->actor.shape.rot.y, 4, 0x2AA8);
+ this->unk_3B6 = CLAMP(this->unk_3B6, -0x1C70, 0x1C70);
+
+ Math_Vec3f_Copy(&sp34, &this->actor.focus.pos);
+
+ if (this->unk_38C->id == ACTOR_PLAYER) {
+ sp40.y = ((Player*)this->unk_38C)->bodyPartsPos[7].y + 3.0f;
+ } else {
+ Math_Vec3f_Copy(&sp40, &this->unk_38C->focus.pos);
+ }
+
+ Math_ApproachS(&this->unk_3B0, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3B4, 4, 0x2AA8);
+ this->unk_3B0 = CLAMP(this->unk_3B0, -0x1554, 0x1554);
+
+ Math_ApproachS(&this->unk_3B4, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3B0, 4, 0x2AA8);
+ this->unk_3B4 = CLAMP(this->unk_3B4, -0xE38, 0xE38);
+
+ return false;
+}
+
+s32 func_80A131F8(EnGo* this, GlobalContext* globalCtx) {
+ if (this->unk_3F4 == 0) {
+ this->unk_38C = &GET_PLAYER(globalCtx)->actor;
+ }
+
+ func_80A12E80(this, globalCtx);
+
+ if (this->unk_390 & 8) {
+ this->unk_390 &= ~0x40;
+ this->unk_390 |= 0x10;
+ func_80A12FE8(this, globalCtx);
+ } else if (this->unk_390 & 0x10) {
+ this->unk_390 &= ~0x10;
+ this->unk_3B0 = 0;
+ this->unk_3B2 = 0;
+ this->unk_3B4 = 0;
+ this->unk_3B6 = 0;
+ this->unk_3BA = 0x14;
+ } else if (DECR(this->unk_3BA) == 0) {
+ this->unk_390 |= 0x40;
+ this->unk_3BA = 0x14;
+ }
+
+ return true;
+}
+
+void func_80A132C8(EnGo* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s16 temp_v1 = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y);
+
+ if ((fabsf(this->actor.playerHeightRel) > 20.0f) || (this->actor.xzDistToPlayer > 300.0f)) {
+ func_8013AED4(&this->unk_390, 3, 7);
+ } else if ((player->transformation != PLAYER_FORM_GORON) || (ABS_ALT(temp_v1) >= 0x1C70) ||
+ (gSaveContext.save.weekEventReg[21] & 4) || (gSaveContext.save.weekEventReg[21] & 8)) {
+ func_8013AED4(&this->unk_390, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_390, 4, 7);
+ }
+}
+
+void func_80A133A8(EnGo* this, GlobalContext* globalCtx) {
+ if (gSaveContext.save.weekEventReg[21] & 8) {
+ func_8013AED4(&this->unk_390, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_390, 4, 7);
+ }
+}
+
+Actor* func_80A13400(EnGo* this, GlobalContext* globalCtx) {
+ Actor* actor;
+ Actor* retActor = NULL;
+
+ while (true) {
+ actor = SubS_FindActor(globalCtx, retActor, ACTORCAT_NPC, ACTOR_EN_GO);
+ retActor = actor;
+
+ if ((actor != NULL) && ((EnGo*)actor != this) && (ENGO_GET_F(actor) == ENGO_F_4) &&
+ (ENGO_GET_70(actor) == ENGO_70_0)) {
+ return retActor;
+ }
+
+ if (actor == NULL) {
+ break;
+ }
+
+ actor = actor->next;
+ if (actor == NULL) {
+ break;
+ }
+ retActor = actor;
+ }
+
+ return NULL;
+}
+
+void func_80A134B0(EnGo* this, GlobalContext* globalCtx, s32 arg2) {
+ if ((gSaveContext.save.weekEventReg[18] & 0x80) || (globalCtx->actorCtx.unk5 & 1) || arg2) {
+ this->colliderSphere.dim.modelSphere.radius = 300;
+ } else {
+ this->colliderSphere.dim.modelSphere.radius = 380;
+ }
+}
+
+s32 func_80A134F4(EnGo* this, s16 arg1) {
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ } else if (ActorCutscene_GetCanPlayNext(arg1)) {
+ ActorCutscene_StartAndSetUnkLinkFields(arg1, &this->actor);
+ return true;
+ }
+ ActorCutscene_SetIntentToPlay(arg1);
+ return false;
+}
+
+s32 func_80A13564(EnGo* this, f32 arg1, f32 arg2, s32 arg3) {
+ s32 pad;
+ f32 temp_f0 = 1.0f;
+ f32 temp_f14 = this->actor.velocity.y + this->actor.gravity;
+ s32 ret;
+
+ if (this->actor.bgCheckFlags & 2) {
+ ret = true;
+ } else {
+ if (temp_f14 > 0.0f) {
+ temp_f0 = temp_f14 / arg1;
+ this->actor.shape.rot.x += (s16)(9100.0f * temp_f0);
+ this->unk_3AE = 0;
+ } else if ((s32)this->actor.velocity.y == 0) {
+ if (arg3 >= this->unk_3AE) {
+ temp_f0 = (f32)this->unk_3AE / arg3;
+ } else {
+ this->actor.gravity = -6.0f;
+ }
+ this->unk_3AE++;
+ } else if (this->unk_3AE == 0) {
+ this->actor.velocity.y = 0.0f;
+ this->actor.gravity = 0.0f;
+ temp_f0 = temp_f14 / arg1;
+ }
+ ret = false;
+ }
+
+ this->unk_3A8 = (1.0f - temp_f0) * arg2;
+ this->actor.scale.x = this->unk_3A4 - this->unk_3A8;
+ this->actor.scale.y = this->unk_3A4 + this->unk_3A8;
+
+ if (this->actor.scale.y < this->actor.scale.x) {
+ this->actor.scale.z = this->actor.scale.x;
+ } else {
+ this->actor.scale.z = this->actor.scale.y;
+ }
+ return ret;
+}
+
+void func_80A136B8(GlobalContext* globalCtx, s16 arg1, s16 arg2, s16 arg3) {
+ s16 sp26 = Quake_Add(Play_GetCamera(globalCtx, MAIN_CAM), 3);
+
+ Quake_SetCountdown(sp26, arg3);
+ Quake_SetSpeed(sp26, arg1);
+ Quake_SetQuakeValues(sp26, arg2, 0, 0, 0);
+}
+
+void func_80A13728(EnGo* this, GlobalContext* globalCtx) {
+ func_80A136B8(globalCtx, 0x6C77, 7, 20);
+ globalCtx->actorCtx.unk2 = 4;
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TEST, this->actor.world.pos.x, this->actor.world.pos.y,
+ this->actor.world.pos.z, 0, 0, 0, 0);
+ EffectSsBlast_SpawnWhiteShockwave(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f);
+}
+
+void func_80A137C0(EnGo* this, GlobalContext* globalCtx, f32 arg2, f32 arg3) {
+ u32 frames1;
+ u32 frames2;
+
+ if (this->unk_390 & 0x400) {
+ Matrix_StatePush();
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_Scale(arg2 * 0.7f, arg2 * 0.8f, arg2, MTXMODE_APPLY);
+ func_800B8118(&this->actor, globalCtx, 0);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ frames1 = globalCtx->gameplayFrames % 256;
+ frames2 = (globalCtx->gameplayFrames * 2) % 256;
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, frames1, 0x20, 0x10, 1, 0, frames2, 0x40, 0x20));
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, (u8)arg3);
+ gSPDisplayList(POLY_XLU_DISP++, &gameplay_keep_DL_050D10);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_StatePop();
+ }
+}
+
+void func_80A139E4(EnGo* this) {
+ static Vec3f D_80A16698 = { 0.0f, 0.06f, 0.0f };
+ Vec3f sp54;
+ Vec3f sp48;
+ s16 sp46 = Rand_ZeroOne() * 360.0f * 182.0f;
+
+ Math_Vec3f_Copy(&sp54, &gZeroVec3f);
+ sp54.z = 28.0f;
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp46, &sp54, &sp48);
+ sp48.y = (Rand_ZeroOne() * 10.0f) + 4.0f;
+ sp48.y += this->actor.floorHeight;
+ func_80A10FD0(&this->unk_3F8[16], sp48, D_80A16698, gZeroVec3f, 0.01f, 0.002f, 16);
+}
+
+s32 func_80A13B1C(EnGo* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s32 pad;
+ s32 ret = false;
+
+ switch (this->unk_3C0) {
+ case 0:
+ this->unk_3B8 = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene);
+ if (func_80A134F4(this, this->unk_3B8)) {
+ this->unk_3C4 = 1;
+ this->unk_3C0 = 1;
+ } else {
+ break;
+ }
+
+ case 1:
+ if (ActorCutscene_GetCurrentIndex() != this->unk_3B8) {
+ this->unk_3B8 = ActorCutscene_GetAdditionalCutscene(this->unk_3B8);
+ this->unk_3C0 = 2;
+ } else {
+ break;
+ }
+
+ case 2:
+ if (func_80A134F4(this, this->unk_3B8)) {
+ this->unk_3C0 = 3;
+ } else {
+ break;
+ }
+
+ case 3:
+ if (ActorCutscene_GetCanPlayNext(0x7C)) {
+ ActorCutscene_StartAndSetUnkLinkFields(0x7C, NULL);
+ this->unk_3C0 = 4;
+ } else if (ActorCutscene_GetCurrentIndex() == this->unk_3B8) {
+ ActorCutscene_SetIntentToPlay(0x7C);
+ }
+ }
+
+ switch (this->unk_3C4) {
+ case 1:
+ func_80A12C48(this, globalCtx, 4);
+ this->unk_390 |= 0x4000;
+ this->unk_3C4++;
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_390 &= ~0x4000;
+ this->unk_390 &= ~0x80;
+ this->unk_390 |= 0x200;
+ this->unk_3C4++;
+ this->unk_3C2 = 0;
+ this->actor.shape.yOffset = 14.0f;
+ }
+ break;
+
+ case 3:
+ this->unk_3C2++;
+ if (this->unk_3C2 >= 10) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_JUMP);
+ this->actor.velocity.y = 10.0f;
+ this->actor.gravity = -1.0f;
+ this->unk_3C4++;
+ }
+ break;
+
+ case 4:
+ if (func_80A13564(this, 10.0f, 0.004f, 6)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_LAND_BIG);
+ func_80A13728(this, globalCtx);
+ this->unk_3C4++;
+ this->unk_3C2 = 0;
+ gSaveContext.save.weekEventReg[88] |= 0x40;
+ }
+ break;
+
+ case 5:
+ this->unk_3C2++;
+ if (this->unk_3C2 >= 10) {
+ func_80A12C48(this, globalCtx, 5);
+ this->actor.shape.rot.x = 0;
+ this->unk_390 &= ~0x200;
+ this->unk_390 |= 0x80;
+ this->unk_3C4++;
+ }
+ break;
+
+ case 6:
+ this->unk_3C0++;
+ if (this->unk_3C0 >= 65) {
+ switch (player->transformation) {
+ case 4:
+ gSaveContext.save.weekEventReg[88] |= 0x80;
+ break;
+
+ case 1:
+ gSaveContext.save.weekEventReg[89] |= 4;
+ break;
+
+ case 2:
+ gSaveContext.save.weekEventReg[89] |= 2;
+ break;
+
+ case 3:
+ gSaveContext.save.weekEventReg[89] |= 1;
+ break;
+ }
+ ret = true;
+ }
+ break;
+ }
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ return ret;
+}
+
+s32 func_80A13E80(EnGo* this, GlobalContext* globalCtx) {
+ static Vec3f D_80A166A4 = { 0.0f, 200.0f, 280.0f };
+ s32 pad;
+ Vec3f sp48;
+ s32 ret = false;
+
+ switch (this->unk_3C0) {
+ case 0:
+ this->unk_3B8 = this->actor.cutscene;
+ if (func_80A134F4(this, this->unk_3B8)) {
+ this->unk_3C0++;
+ }
+ break;
+
+ case 1:
+ func_80A12C48(this, globalCtx, 7);
+ this->unk_3C0++;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, 16.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_HAND_HIT);
+ }
+
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ func_80A12C48(this, globalCtx, 1);
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A166A4, &sp48);
+ gSaveContext.powderKegTimer = 2400;
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, sp48.x, sp48.y, sp48.z, 1, 0, 0, 0);
+ func_80A134B0(this, globalCtx, 1);
+ this->unk_3C2 = 0;
+ this->unk_3C0++;
+ }
+ break;
+
+ case 3:
+ if (this->unk_3C2 >= 60) {
+ ActorCutscene_Stop(this->unk_3B8);
+ this->unk_3C2 = 0;
+ this->unk_3C0 = 0;
+ ret = true;
+ } else {
+ this->unk_3C2++;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+void func_80A14018(EnGo* this, GlobalContext* globalCtx) {
+ static Vec3f D_80A166B0 = { 0.0f, 0.0f, 40.0f };
+ static s32 D_80A166BC[] = { 11, 10, 12, 13, 14, 17 };
+ Vec3f sp2C;
+ s32 phi_v0 = ENGO_GET_70(&this->actor) % 6;
+
+ if (phi_v0 < 4) {
+ phi_v0 = ((gSaveContext.eventInf[2] & 0xF) + phi_v0) % 4;
+ }
+
+ func_80A12C48(this, globalCtx, D_80A166BC[phi_v0]);
+
+ if (this->unk_3DC == 14) {
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A166B0, &sp2C);
+ Math_Vec3f_Copy(&this->actor.world.pos, &sp2C);
+ }
+ this->actor.flags &= ~1;
+ Actor_SetScale(&this->actor, this->unk_3A4);
+ this->unk_3EC = 0;
+ this->unk_390 = 0;
+ this->unk_390 |= (0x40 | 0x20);
+ this->actor.gravity = 0.0f;
+}
+
+void func_80A14104(EnGo* this, GlobalContext* globalCtx) {
+ static s32 D_80A166D4[] = { 15, 16 };
+ s16 temp;
+
+ func_80A12C48(this, globalCtx, D_80A166D4[ENGO_GET_70(&this->actor) % 2]);
+ temp = Rand_ZeroOne() * this->skelAnime.endFrame;
+ this->skelAnime.curFrame = temp;
+ this->actor.flags &= ~1;
+ Actor_SetScale(&this->actor, this->unk_3A4);
+ this->unk_3EC = 0;
+ this->unk_390 = 0;
+ this->unk_390 |= 0x40;
+ this->unk_390 |= 0x20;
+ this->actor.gravity = 0.0f;
+}
+
+void func_80A141D4(EnGo* this, GlobalContext* globalCtx) {
+ Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit1);
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+ this->unk_3DC = -1;
+ func_80A12C48(this, globalCtx, 5);
+ this->unk_3EC = 0;
+ this->unk_39C = (this->unk_3A4 / 0.01f) * 0.9f;
+ this->unk_3BE = 2;
+ this->unk_390 = 0;
+ this->unk_390 |= 0x40;
+ this->unk_390 |= 0x400;
+ this->unk_3A0 = 100.0f;
+}
+
+void func_80A1428C(EnGo* this, GlobalContext* globalCtx) {
+ s16 temp;
+ Vec3f sp30;
+ Vec3f sp24;
+
+ Math_Vec3f_Copy(&sp30, &this->actor.world.pos);
+ if (this->unk_284 != NULL) {
+ this->actor.flags &= ~0x2000000;
+ func_8013C8B8(this->unk_284, 0, &sp24);
+ temp = Math_Vec3f_Yaw(&sp30, &sp24);
+ this->actor.shape.rot.y = temp;
+ this->actor.world.rot.y = temp;
+ }
+ this->unk_390 = 0;
+ this->unk_390 |= 0x100;
+ this->actor.shape.yOffset = 46.0f;
+ this->actor.gravity = -1.0f;
+}
+
+void func_80A14324(EnGo* this, GlobalContext* globalCtx) {
+ func_80A12C48(this, globalCtx, 8);
+ Actor_SetScale(&this->actor, this->unk_3A4);
+ this->unk_390 = 0;
+ this->actor.gravity = -1.0f;
+ func_8013AED4(&this->unk_390, 3, 7);
+ this->unk_3EC = 0;
+ this->unk_390 |= 0x40;
+ this->unk_3BC = 0;
+ this->unk_3BE = 4;
+ this->unk_39C = 0.0f;
+ this->unk_3A0 = 0.0f;
+}
+
+void func_80A143A8(EnGo* this, GlobalContext* globalCtx) {
+ func_80A12C48(this, globalCtx, 5);
+ Actor_SetScale(&this->actor, this->unk_3A4);
+ this->unk_390 = 0;
+ this->actor.gravity = -1.0f;
+ func_8013AED4(&this->unk_390, 3, 7);
+ this->unk_3EC = 0;
+ this->unk_390 |= 0x40;
+ this->unk_390 |= 0x20;
+ this->unk_3BC = 0;
+ this->unk_3BE = 0;
+ this->unk_39C = 0.0f;
+ this->unk_3A0 = 0.0f;
+}
+
+void func_80A14430(EnGo* this, GlobalContext* globalCtx) {
+ if (((gSaveContext.save.entranceIndex == 0xD000) || (gSaveContext.save.entranceIndex == 0xD020)) &&
+ (gSaveContext.save.weekEventReg[33] & 0x80)) {
+ func_80A14018(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_80A1449C(EnGo* this, GlobalContext* globalCtx) {
+ if ((gSaveContext.save.entranceIndex == 0xD010) || (gSaveContext.save.entranceIndex == 0x1C00)) {
+ func_80A14104(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_80A144F4(EnGo* this, GlobalContext* globalCtx) {
+ if (gSaveContext.save.day >= 2) {
+ this->unk_284 = func_8013BEDC(globalCtx, ENGO_GET_7F80(&this->actor), 0xFF, &this->unk_3E4);
+ if (this->unk_284 != NULL) {
+ this->unk_3E4 = 1;
+ }
+ func_80A1428C(this, globalCtx);
+ this->actionFunc = func_80A153FC;
+ this->unk_3D8 = func_80A13B1C;
+ } else {
+ func_80A143A8(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ this->unk_3D8 = func_80A13B1C;
+ }
+}
+
+void func_80A145AC(EnGo* this, GlobalContext* globalCtx) {
+ if ((ENGO_GET_70(&this->actor) == ENGO_70_1) &&
+ (((globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA2) && (gSaveContext.sceneSetupIndex == 1) &&
+ (globalCtx->csCtx.unk_12 == 0)) ||
+ !(gSaveContext.save.weekEventReg[21] & 8))) {
+ this->actor.child = func_80A13400(this, globalCtx);
+ this->actor.child->child = &this->actor;
+ func_80A141D4(this, globalCtx);
+ this->actionFunc = func_80A14E14;
+ } else {
+ func_80A143A8(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ }
+}
+
+void func_80A14668(EnGo* this, GlobalContext* globalCtx) {
+ if (!(gSaveContext.save.weekEventReg[22] & 4)) {
+ func_80A14324(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ } else {
+ func_80A143A8(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ }
+}
+
+void func_80A146CC(EnGo* this, GlobalContext* globalCtx) {
+ func_80A134B0(this, globalCtx, 0);
+ func_80A12C48(this, globalCtx, 0);
+ this->unk_3A4 *= 5.0f;
+ Actor_SetScale(&this->actor, this->unk_3A4);
+ this->actor.flags &= ~1;
+ this->actor.targetMode = 3;
+ this->unk_390 = 0;
+ this->actor.gravity = -1.0f;
+ func_8013AED4(&this->unk_390, 3, 7);
+ this->unk_390 |= 0x40;
+ this->unk_390 |= 0x20;
+ this->unk_3D8 = func_80A13E80;
+ this->actionFunc = func_80A149B0;
+}
+
+void func_80A14798(EnGo* this, GlobalContext* globalCtx) {
+ s32 sp38[2] = { 0x0000003E, 0x00000F64 };
+
+ if ((this->unk_288 < 0) || func_8013D8DC(this->unk_288, globalCtx) || (this->unk_289 < 0) ||
+ func_8013D8DC(this->unk_289, globalCtx)) {
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_oF1d_map_Skel_011AC8, NULL, this->jointTable,
+ this->morphTable, 18);
+
+ this->unk_3DC = -1;
+ func_80A12C48(this, globalCtx, 2);
+ this->actor.draw = func_80A15FEC;
+
+ Collider_InitAndSetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit);
+ Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit2);
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+ Effect_Add(globalCtx, &this->unk_3E8, 4, 0, 0, &sp38);
+
+ this->actor.targetMode = 1;
+ this->unk_3A4 = 0.01f;
+ this->unk_3D8 = NULL;
+
+ switch (ENGO_GET_F(&this->actor)) {
+ case ENGO_F_1:
+ func_80A14430(this, globalCtx);
+ break;
+
+ case ENGO_F_2:
+ func_80A1449C(this, globalCtx);
+ break;
+
+ case ENGO_F_3:
+ func_80A144F4(this, globalCtx);
+ break;
+
+ case ENGO_F_4:
+ func_80A145AC(this, globalCtx);
+ break;
+
+ case ENGO_F_5:
+ case ENGO_F_6:
+ case ENGO_F_7:
+ func_80A14668(this, globalCtx);
+ break;
+
+ case ENGO_F_8:
+ func_80A146CC(this, globalCtx);
+ break;
+
+ default:
+ Actor_MarkForDeath(&this->actor);
+ break;
+ }
+ }
+}
+
+void func_80A149B0(EnGo* this, GlobalContext* globalCtx) {
+ s16 sp26 = this->actor.world.rot.y;
+
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_2) && (gSaveContext.save.entranceIndex == 0xD010)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_CHEER - SFX_FLAG);
+ } else if (ENGO_GET_F(&this->actor) != ENGO_F_8) {
+ if (func_80A1222C(this, globalCtx)) {
+ func_8013AED4(&this->unk_390, 0, 7);
+ this->unk_3EC = 1;
+ this->actionFunc = func_80A14B30;
+ } else if (ENGO_GET_F(&this->actor) == ENGO_F_4) {
+ switch (ENGO_GET_70(&this->actor)) {
+ case ENGO_70_0:
+ func_80A132C8(this, globalCtx);
+ break;
+
+ case ENGO_70_1:
+ func_80A133A8(this, globalCtx);
+ break;
+ }
+ } else if (ENGO_GET_F(&this->actor) == ENGO_F_1) {
+ if (ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)) < 0x3FFC) {
+ func_8013AED4(&this->unk_390, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_390, 0, 7);
+ }
+ }
+ }
+ Math_ApproachS(&this->actor.shape.rot.y, sp26, 4, 0x2AA8);
+}
+
+void func_80A14B30(EnGo* this, GlobalContext* globalCtx) {
+ s16 sp26 = this->actor.world.rot.y;
+ u16 sfxId;
+
+ if (func_80A1222C(this, globalCtx)) {
+ this->unk_3EC = 1;
+ }
+
+ if (this->unk_390 & 0x4000) {
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_390 &= ~0x4000;
+ this->unk_390 |= 0x200;
+ if (this->unk_3EC != 0) {
+ this->unk_3AE = 0;
+ }
+ this->actor.shape.yOffset = 14.0f;
+ }
+ } else if (this->unk_390 & 0x8000) {
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_390 |= 0x80;
+ this->unk_390 &= ~0x8000;
+ }
+ } else if (this->unk_390 & 0x200) {
+ if ((this->actor.xzDistToPlayer < 160.0f) && (this->actor.playerHeightRel < 20.0f) && (this->unk_3EC == 0)) {
+ func_80A12C48(this, globalCtx, 3);
+ this->unk_390 &= ~0x80;
+ this->unk_390 &= ~0x200;
+ this->unk_390 |= 0x8000;
+ this->actor.shape.yOffset = 0.0f;
+ } else if ((this->unk_3EC != 0) && (gSaveContext.save.weekEventReg[22] & 4)) {
+ this->actor.scale.x = this->unk_3A4 - (Math_SinS(this->unk_3AE) * 0.001f);
+ this->actor.scale.y = (Math_SinS(this->unk_3AE) * 0.001f) + this->unk_3A4;
+ this->actor.scale.z = (Math_SinS(this->unk_3AE) * 0.001f) + this->unk_3A4;
+ if (this->unk_3AE == 0) {
+ this->unk_3EC = -this->unk_3EC;
+ if (this->unk_3EC > 0) {
+ sfxId = NA_SE_EN_GOLON_SNORE1;
+ } else {
+ sfxId = NA_SE_EN_GOLON_SNORE2;
+ }
+ Audio_PlayActorSound2(&this->actor, sfxId);
+ }
+ this->unk_3AE += 0x400;
+ this->actor.shape.yOffset = (this->actor.scale.y / this->unk_3A4) * 14.0f;
+ func_8013AED4(&this->unk_390, 3, 7);
+ }
+ } else if ((this->actor.xzDistToPlayer >= 240.0f) || (this->actor.playerHeightRel >= 20.0f) ||
+ (this->unk_3EC != 0)) {
+ func_80A12C48(this, globalCtx, 4);
+ this->unk_390 &= ~0x80;
+ this->unk_390 &= ~0x200;
+ this->unk_390 |= 0x4000;
+ this->actor.shape.yOffset = 0.0f;
+ }
+
+ func_8013D9C8(globalCtx, &this->unk_3CE[0], &this->unk_3C8[0], 3);
+ Math_ApproachS(&this->actor.shape.rot.y, sp26, 4, 0x2AA8);
+}
+
+void func_80A14E14(EnGo* this, GlobalContext* globalCtx) {
+ Actor* actor = this->colliderCylinder.base.ac;
+
+ if ((this->unk_390 & 0x1000) && (((actor != NULL) && (actor->id == ACTOR_OBJ_AQUA) && (actor->params & 1)) ||
+ (this->actor.colChkInfo.damageEffect == 2))) {
+ this->actionFunc = func_80A14E74;
+ }
+}
+
+void func_80A14E74(EnGo* this, GlobalContext* globalCtx) {
+ if (func_80A134F4(this, this->actor.cutscene)) {
+ this->actionFunc = func_80A14EB0;
+ }
+}
+
+void func_80A14EB0(EnGo* this, GlobalContext* globalCtx) {
+ EnGo* sp24 = (EnGo*)this->actor.child;
+
+ if ((s32)(this->unk_39C * 3.0f) != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG);
+ Math_ApproachF(&this->unk_39C, 0.0f, 0.02f, 1.0f);
+ this->unk_3A0 = (this->unk_39C / 0.9f) * 100.0f;
+ func_80A139E4(this);
+ } else {
+ ActorCutscene_Stop(this->actor.cutscene);
+ func_80A143A8(this, globalCtx);
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_4) && (ENGO_GET_70(&this->actor) == ENGO_70_1)) {
+ func_8013AED4(&this->unk_390, 4, 7);
+ func_80A143A8(sp24, globalCtx);
+ sp24->actionFunc = func_80A149B0;
+ }
+ this->actionFunc = func_80A149B0;
+ }
+}
+
+void func_80A14FC8(EnGo* this, GlobalContext* globalCtx) {
+ s32 sp38[] = {
+ 0, 2, 6, 20, 18, 5, 5, 15,
+ };
+ u16 sp36 = 0;
+ s32 sp30;
+ u32 sp2C;
+
+ switch (ENGO_GET_70(&this->actor)) {
+ case ENGO_70_0:
+ sp36 = 0x80;
+ break;
+
+ case ENGO_70_1:
+ sp36 = 0x81;
+ break;
+ }
+
+ if ((sp36 == 0x80) || (sp36 == 0x81)) {
+ if (func_800EE29C(globalCtx, sp36)) {
+ sp2C = func_800EE200(globalCtx, sp36);
+ sp30 = globalCtx->csCtx.npcActions[sp2C]->unk0;
+
+ if (this->unk_394 != (u8)sp30) {
+ this->unk_394 = sp30;
+ func_80A12C48(this, globalCtx, sp38[sp30]);
+ this->unk_390 = 0;
+ this->unk_390 |= 0x20;
+ this->unk_3BE = 0;
+ this->unk_39C = 0.0f;
+ this->unk_3A0 = 0.0f;
+
+ switch (sp30) {
+ case 1:
+ this->unk_390 |= 0x80;
+ this->skelAnime.curFrame = this->skelAnime.endFrame;
+ break;
+
+ case 5:
+ case 6:
+ func_80A141D4(this, globalCtx);
+ break;
+ }
+ }
+
+ switch (this->unk_394) {
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (this->unk_3DC == 20)) {
+ func_80A12C48(this, globalCtx, 21);
+ }
+ break;
+
+ case 4:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (this->unk_3DC == 18)) {
+ func_80A12C48(this, globalCtx, 19);
+ }
+ break;
+
+ case 6:
+ if ((s32)(this->unk_39C * 3.0f) != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG);
+ Math_ApproachF(&this->unk_39C, 0.0f, 0.02f, 1.0f);
+ this->unk_3A0 = (this->unk_39C / 0.9f) * 100.0f;
+ func_80A139E4(this);
+ } else if (this->unk_390 & 0x400) {
+ func_80A143A8(this, globalCtx);
+ }
+ break;
+ }
+
+ if (sp36 == 0x80) {
+ switch (globalCtx->csCtx.frames) {
+ case 55:
+ case 100:
+ case 130:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD);
+ break;
+
+ case 185:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP);
+ break;
+
+ case 250:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_EYE_BIG);
+ break;
+
+ case 465:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_IWAIGORON_SOLO);
+ break;
+
+ case 490:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL);
+ break;
+ }
+ } else if (sp36 == 0x81) {
+ switch (globalCtx->csCtx.frames) {
+ case 360:
+ case 390:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD);
+ break;
+
+ case 430:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP);
+ break;
+
+ case 450:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_EYE_BIG);
+ break;
+
+ case 480:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL);
+ break;
+ }
+ }
+
+ func_8013D9C8(globalCtx, this->unk_3CE, this->unk_3C8, 3);
+ func_800EDF24(&this->actor, globalCtx, sp2C);
+ }
+ }
+}
+
+void func_80A153FC(EnGo* this, GlobalContext* globalCtx) {
+ Vec3s* sp5C;
+ Vec3f sp50;
+ Vec3f sp44;
+
+ if ((this->unk_390 & 0x1000) && (this->actor.colChkInfo.damageEffect == 0xF)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_SNOWBALL_BROKEN);
+
+ this->actor.flags &= ~0x10;
+ this->actor.flags |= 0x2000000;
+
+ func_80A118F8(this->unk_3F8, this->actor.world.pos);
+ this->actor.shape.rot.x = 0;
+ this->actor.speedXZ = 0.0f;
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD);
+
+ if (gSaveContext.save.day == 3) {
+ func_80A141D4(this, globalCtx);
+ this->actionFunc = func_80A14E14;
+ } else {
+ func_80A143A8(this, globalCtx);
+ this->actionFunc = func_80A149B0;
+ }
+ } else if (this->unk_284 != NULL) {
+ if (this->unk_390 & 0x800) {
+ func_800B8E58(&GET_PLAYER(globalCtx)->actor, NA_SE_PL_BODY_HIT);
+ func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0);
+ }
+
+ sp5C = Lib_SegmentedToVirtual(this->unk_284->points);
+ if (func_8013BD40(&this->actor, this->unk_284, this->unk_3E4)) {
+ if (this->unk_3E4 >= (this->unk_284->count - 1)) {
+ this->unk_3E4 = 0;
+ } else {
+ this->unk_3E4++;
+ }
+ }
+
+ Math_Vec3s_ToVec3f(&sp44, &sp5C[this->unk_3E4]);
+ Math_Vec3f_Copy(&sp50, &this->actor.world.pos);
+ Math_ApproachS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&sp50, &sp44), 4, 0x38E);
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+
+ if (this->actor.bgCheckFlags & 1) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BIGBALL_ROLL - SFX_FLAG);
+ func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->unk_3E8), &this->actor.world.pos, 18.0f,
+ this->actor.shape.rot.y, this->actor.floorPoly, this->actor.floorBgId);
+ } else {
+ func_800AEF44(Effect_GetByIndex(this->unk_3E8));
+ }
+
+ this->actor.speedXZ = 4.0f;
+ this->actor.shape.rot.x += (s16)(this->actor.speedXZ * 546.0f);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ }
+}
+
+s32* func_80A15684(EnGo* this, GlobalContext* globalCtx) {
+ static s32 D_80A16704[] = {
+ D_80A16100,
+ D_80A16164,
+ };
+
+ if (this->unk_3EC != 0) {
+ return D_80A1640C;
+ }
+
+ if (ENGO_GET_F(&this->actor) == ENGO_F_1) {
+ switch (ENGO_GET_70(&this->actor) % 6) {
+ case ENGO_70_0:
+ return D_80A163BC;
+ case ENGO_70_1:
+ return D_80A163CC;
+ case ENGO_70_2:
+ return D_80A163DC;
+ case ENGO_70_3:
+ return D_80A163EC;
+ case ENGO_70_4:
+ return D_80A163FC;
+ case ENGO_70_5:
+ return D_80A163FC;
+ }
+ }
+
+ switch (ENGO_GET_F(&this->actor)) {
+ case ENGO_F_3:
+ return D_80A16350;
+ case ENGO_F_4:
+ return D_80A16704[ENGO_GET_70(&this->actor)];
+ case ENGO_F_5:
+ return D_80A16208;
+ case ENGO_F_6:
+ return D_80A16254;
+ case ENGO_F_7:
+ return D_80A16210;
+ case ENGO_F_8:
+ return D_80A16280;
+ default:
+ return D_80A16208;
+ }
+}
+
+void func_80A157C4(EnGo* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Vec3f sp40;
+ Vec3f sp34;
+
+ if (!func_8010BF58(&this->actor, globalCtx, func_80A15684(this, globalCtx), this->unk_3D8, &this->unk_28C)) {
+ if ((ENGO_GET_F(&this->actor) != ENGO_F_1) && !(this->unk_390 & 0x200)) {
+ Math_Vec3f_Copy(&sp40, &this->unk_38C->world.pos);
+ Math_Vec3f_Copy(&sp34, &this->actor.world.pos);
+ Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&sp34, &sp40), 4, 0x2AA8);
+ }
+ func_8013D9C8(globalCtx, this->unk_3CE, this->unk_3C8, 3);
+ return;
+ }
+
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_5) || (ENGO_GET_F(&this->actor) == ENGO_F_6) ||
+ (ENGO_GET_F(&this->actor) == ENGO_F_7)) {
+ this->unk_3BC = 0;
+ this->unk_390 &= ~0x20;
+ this->unk_3BE = 4;
+ }
+
+ this->unk_390 &= ~0x8;
+ func_8013AED4(&this->unk_390, 3, 7);
+ this->unk_28C = 0;
+ this->unk_390 |= 0x40;
+ this->actionFunc = this->unk_18C;
+}
+
+void EnGo_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnGo* this = THIS;
+
+ this->unk_288 = func_8013D924(OBJECT_TAISOU, globalCtx);
+ this->unk_289 = func_8013D924(OBJECT_HAKUGIN_DEMO, globalCtx);
+ this->actionFunc = func_80A14798;
+}
+
+void EnGo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnGo* this = THIS;
+
+ Collider_DestroyCylinder(globalCtx, &this->colliderCylinder);
+ Collider_DestroySphere(globalCtx, &this->colliderSphere);
+ Effect_Destroy(globalCtx, this->unk_3E8);
+}
+
+void EnGo_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnGo* this = THIS;
+ f32 phi_f0;
+
+ func_80A12868(this, globalCtx);
+ if (!func_80A12774(this, globalCtx)) {
+ func_80A12954(this, globalCtx);
+ }
+
+ this->actionFunc(this, globalCtx);
+
+ if (!(this->unk_390 & 0x400)) {
+ func_80A12D6C(this);
+ func_80A12A64(this, globalCtx);
+ func_80A131F8(this, globalCtx);
+ func_80A12B78(this, globalCtx);
+ }
+
+ if (!(this->unk_390 & 0x100) && !(this->unk_390 & 0x200) && !(this->unk_390 & 0x400)) {
+ if (ENGO_GET_F(&this->actor) == ENGO_F_8) {
+ phi_f0 = this->colliderSphere.dim.worldSphere.radius + 60;
+ } else {
+ phi_f0 = this->colliderCylinder.dim.radius + 40;
+ }
+ func_8013C964(&this->actor, globalCtx, phi_f0, 20.0f, 0, this->unk_390 & 7);
+ } else if ((this->unk_390 & 0x200) && (this->unk_3EC != 0)) {
+ phi_f0 = this->colliderCylinder.dim.radius + 40;
+ func_8013C964(&this->actor, globalCtx, phi_f0, 20.0f, 0, this->unk_390 & 7);
+ }
+
+ if ((ENGO_GET_F(&this->actor) != ENGO_F_8) && (ENGO_GET_F(&this->actor) != ENGO_F_2) &&
+ (ENGO_GET_F(&this->actor) != ENGO_F_1)) {
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4);
+ }
+
+ func_80A122EC(this);
+ func_80A126BC(this, globalCtx);
+ func_80A1203C(this);
+}
+
+void func_80A15B80(EnGo* this, GlobalContext* globalCtx) {
+ Gfx* gfx;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset,
+ this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY);
+
+ if (this->unk_390 & 0x100) {
+ Matrix_Scale(this->actor.scale.x * 8.0f, this->actor.scale.y * 8.0f, this->actor.scale.z * 8.0f, MTXMODE_APPLY);
+ } else {
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ }
+
+ Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, (this->unk_390 & 0x100) ? object_oF1d_map_DL_001560 : object_oF1d_map_DL_0091A8);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+s32 EnGo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnGo* this = THIS;
+ Vec3f sp30;
+ s32 idx;
+
+ if ((ENGO_GET_F(&this->actor) == ENGO_F_8) && (limbIndex == 10)) {
+ limbIndex = limbIndex;
+ Matrix_GetStateTranslation(&sp30);
+ sp30.y = this->actor.world.pos.y;
+ Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp30);
+ }
+
+ switch (limbIndex) {
+ case 10:
+ idx = 0;
+ break;
+
+ case 11:
+ idx = 1;
+ break;
+
+ case 14:
+ idx = 2;
+ break;
+
+ default:
+ idx = 9;
+ break;
+ }
+
+ if ((this->unk_390 & 0x80) && (idx < 9)) {
+ rot->y += (s16)(Math_SinS(this->unk_3CE[idx]) * 200.0f);
+ rot->z += (s16)(Math_CosS(this->unk_3C8[idx]) * 200.0f);
+ }
+ return false;
+}
+
+void EnGo_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) {
+ EnGo* this = THIS;
+ u16 temp_v0;
+ s32 phi_v1;
+ s32 phi_v0;
+
+ if (this->unk_390 & 0x40) {
+ phi_v1 = false;
+ } else {
+ phi_v1 = true;
+ }
+
+ if (this->unk_390 & 0x10) {
+ phi_v0 = true;
+ } else {
+ phi_v0 = false;
+ }
+
+ if (!phi_v1) {
+ phi_v0 = false;
+ }
+
+ switch (limbIndex) {
+ case 17:
+ func_8013AD9C(this->unk_3B0 + this->unk_3B4 + 0x4000,
+ this->unk_3B2 + this->unk_3B6 + this->actor.shape.rot.y + 0x4000, &this->unk_290,
+ &this->unk_2A8, phi_v1, phi_v0);
+ Matrix_StatePop();
+ Matrix_InsertTranslation(this->unk_290.x, this->unk_290.y, this->unk_290.z, MTXMODE_NEW);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ Matrix_RotateY(this->unk_2A8.y, MTXMODE_APPLY);
+ Matrix_InsertXRotation_s(this->unk_2A8.x, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(this->unk_2A8.z, MTXMODE_APPLY);
+ Matrix_StatePush();
+ break;
+
+ case 10:
+ func_8013AD9C(this->unk_3B4 + 0x4000, this->unk_3B6 + this->actor.shape.rot.y + 0x4000, &this->unk_29C,
+ &this->unk_2AE, phi_v1, phi_v0);
+ Matrix_StatePop();
+ Matrix_InsertTranslation(this->unk_29C.x, this->unk_29C.y, this->unk_29C.z, MTXMODE_NEW);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ Matrix_RotateY(this->unk_2AE.y, MTXMODE_APPLY);
+ Matrix_InsertXRotation_s(this->unk_2AE.x, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(this->unk_2AE.z, MTXMODE_APPLY);
+ Matrix_StatePush();
+ break;
+ }
+}
+
+void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx) {
+ static UNK_TYPE D_80A1670C[] = {
+ &object_oF1d_map_Tex_010438, &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_011038,
+ &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_010838,
+ };
+ EnGo* this = THIS;
+
+ if (!(this->unk_390 & 0x300)) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A1670C[this->unk_3BE]));
+
+ if (this->unk_3DC == 14) {
+ Matrix_InsertTranslation(0.0f, 0.0f, -4000.0f, MTXMODE_APPLY);
+ }
+ func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ EnGo_OverrideLimbDraw, NULL, EnGo_UnkDraw, &this->actor);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ } else {
+ func_80A15B80(this, globalCtx);
+ }
+ func_80A137C0(this, globalCtx, this->unk_39C, this->unk_3A0);
+ func_80A1213C(this, globalCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.h b/src/overlays/actors/ovl_En_Go/z_en_go.h
index 08363e822..ab7f068e1 100644
--- a/src/overlays/actors/ovl_En_Go/z_en_go.h
+++ b/src/overlays/actors/ovl_En_Go/z_en_go.h
@@ -7,11 +7,98 @@ struct EnGo;
typedef void (*EnGoActionFunc)(struct EnGo*, GlobalContext*);
+#define ENGO_GET_F(thisx) (((thisx)->params & 0xF) & 0xFF)
+#define ENGO_GET_70(thisx) ((((thisx)->params & 0x70) >> 4) & 0xFF)
+#define ENGO_GET_7F80(thisx) ((((thisx)->params & 0x7F80) >> 7) & 0xFF)
+
+enum {
+ /* 0 */ ENGO_F_0,
+ /* 1 */ ENGO_F_1,
+ /* 2 */ ENGO_F_2,
+ /* 3 */ ENGO_F_3,
+ /* 4 */ ENGO_F_4,
+ /* 5 */ ENGO_F_5,
+ /* 6 */ ENGO_F_6,
+ /* 7 */ ENGO_F_7,
+ /* 8 */ ENGO_F_8,
+};
+
+enum {
+ /* 0 */ ENGO_70_0,
+ /* 1 */ ENGO_70_1,
+ /* 2 */ ENGO_70_2,
+ /* 3 */ ENGO_70_3,
+ /* 4 */ ENGO_70_4,
+ /* 5 */ ENGO_70_5,
+};
+
+typedef struct {
+ /* 0x00 */ u8 unk_00;
+ /* 0x01 */ u8 unk_01;
+ /* 0x02 */ u8 unk_02;
+ /* 0x04 */ Vec3s unk_04;
+ /* 0x0A */ Vec3s unk_0A;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ Vec3f unk_1C;
+ /* 0x28 */ Vec3f unk_28;
+ /* 0x34 */ f32 unk_34;
+ /* 0x38 */ f32 unk_38;
+} EnGoStruct; // size = 0x3C;
+
typedef struct EnGo {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x44];
+ /* 0x0144 */ SkelAnime skelAnime;
/* 0x0188 */ EnGoActionFunc actionFunc;
- /* 0x018C */ char unk_18C[0x9EC];
+ /* 0x018C */ EnGoActionFunc unk_18C;
+ /* 0x0190 */ EnGoActionFunc unk_190;
+ /* 0x0194 */ ColliderCylinder colliderCylinder;
+ /* 0x01E0 */ UNK_TYPE1 unk1E0[0x4C];
+ /* 0x022C */ ColliderSphere colliderSphere;
+ /* 0x0284 */ Path* unk_284;
+ /* 0x0288 */ s8 unk_288;
+ /* 0x0289 */ s8 unk_289;
+ /* 0x028C */ s32 unk_28C;
+ /* 0x0290 */ Vec3f unk_290;
+ /* 0x029C */ Vec3f unk_29C;
+ /* 0x02A8 */ Vec3s unk_2A8;
+ /* 0x02AE */ Vec3s unk_2AE;
+ /* 0x02B4 */ Vec3s jointTable[18];
+ /* 0x0320 */ Vec3s morphTable[18];
+ /* 0x038C */ Actor* unk_38C;
+ /* 0x0390 */ u16 unk_390;
+ /* 0x0392 */ u16 unk_392;
+ /* 0x0394 */ u8 unk_394;
+ /* 0x0398 */ f32 unk_398;
+ /* 0x039C */ f32 unk_39C;
+ /* 0x03A0 */ f32 unk_3A0;
+ /* 0x03A4 */ f32 unk_3A4;
+ /* 0x03A8 */ f32 unk_3A8;
+ /* 0x03AC */ UNK_TYPE1 unk3AC[0x2];
+ /* 0x03AE */ s16 unk_3AE;
+ /* 0x03B0 */ s16 unk_3B0;
+ /* 0x03B2 */ s16 unk_3B2;
+ /* 0x03B4 */ s16 unk_3B4;
+ /* 0x03B6 */ s16 unk_3B6;
+ /* 0x03B8 */ s16 unk_3B8;
+ /* 0x03BA */ s16 unk_3BA;
+ /* 0x03BC */ s16 unk_3BC;
+ /* 0x03BE */ s16 unk_3BE;
+ /* 0x03C0 */ s16 unk_3C0;
+ /* 0x03C2 */ s16 unk_3C2;
+ /* 0x03C4 */ s16 unk_3C4;
+ /* 0x03C6 */ s16 unk_3C6;
+ /* 0x03C8 */ s16 unk_3C8[3];
+ /* 0x03CE */ s16 unk_3CE[3];
+ /* 0x03D4 */ s16 unk_3D4;
+ /* 0x03D8 */ void* unk_3D8;
+ /* 0x03DC */ s32 unk_3DC;
+ /* 0x03E0 */ UNK_TYPE1 unk3E0[0x4];
+ /* 0x03E4 */ s32 unk_3E4;
+ /* 0x03E8 */ s32 unk_3E8;
+ /* 0x03EC */ s32 unk_3EC;
+ /* 0x03F0 */ s32 unk_3F0;
+ /* 0x03F4 */ s32 unk_3F4;
+ /* 0x03F8 */ EnGoStruct unk_3F8[32];
} EnGo; // size = 0xB78
extern const ActorInit En_Go_InitVars;
diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.c b/src/overlays/actors/ovl_En_Gs/z_en_gs.c
index b2ea32a7e..189664368 100644
--- a/src/overlays/actors/ovl_En_Gs/z_en_gs.c
+++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.c
@@ -35,7 +35,7 @@ s32 func_809995A4(EnGs* this, GlobalContext* globalCtx);
void func_80999A8C(EnGs* this, GlobalContext* globalCtx);
void func_80999AC0(EnGs* this);
-extern Gfx D_0407D590[];
+extern Gfx gGameplayKeepDrawFlameDL[];
extern Gfx D_06000950[];
extern Gfx D_060009D0[];
extern Gfx D_06000A60[];
@@ -363,7 +363,7 @@ void func_809984F4(EnGs* this, GlobalContext* globalCtx) {
EnGs* gossipStone = NULL;
do {
- gossipStone = (EnGs*)func_ActorCategoryIterateById(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS);
+ gossipStone = (EnGs*)SubS_FindActor(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS);
if (gossipStone != NULL) {
if ((this != gossipStone) && (this->unk_194 == gossipStone->unk_194)) {
gossipStone->unk_19A |= 1;
@@ -396,8 +396,7 @@ void func_809985B8(EnGs* this, GlobalContext* globalCtx) {
gossipStone = NULL;
do {
- gossipStone =
- (EnGs*)func_ActorCategoryIterateById(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS);
+ gossipStone = (EnGs*)SubS_FindActor(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS);
if (gossipStone != NULL) {
if ((gossipStone != this) && (gossipStone->actor.params == ENGS_2) &&
(gossipStone->unk_198 == this->unk_198)) {
@@ -1103,7 +1102,7 @@ void EnGs_Draw(Actor* thisx, GlobalContext* globalCtx) {
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, -frames * 20, 0x20, 0x80));
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
- gSPDisplayList(POLY_XLU_DISP++, D_0407D590);
+ gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c
index 664905624..8f6d0f0fa 100644
--- a/src/overlays/actors/ovl_En_In/z_en_in.c
+++ b/src/overlays/actors/ovl_En_In/z_en_in.c
@@ -370,7 +370,7 @@ void func_808F38F8(EnIn* this, GlobalContext* globalCtx) {
this->unk4A4 = NULL;
while (true) {
//! @bug: Infinite loop if there is only one ACTOR_EN_IN
- this->unk4A4 = (EnIn*)func_ActorCategoryIterateById(globalCtx, &this->unk4A4->actor, ACTORCAT_NPC, ACTOR_EN_IN);
+ this->unk4A4 = (EnIn*)SubS_FindActor(globalCtx, &this->unk4A4->actor, ACTORCAT_NPC, ACTOR_EN_IN);
if (this->unk4A4 != NULL && this->unk4A4 != this) {
break;
}
diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
index a7ed2025a..e1ce0892f 100644
--- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
+++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
@@ -5,6 +5,9 @@
*/
#include "z_en_ishi.h"
+#include "objects/gameplay_field_keep/gameplay_field_keep.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
+#include "objects/object_ishi/object_ishi.h"
#define FLAGS 0x00800010
@@ -14,14 +17,31 @@ void EnIshi_Init(Actor* thisx, GlobalContext* globalCtx);
void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx);
+void func_8095D804(Actor* thisx, GlobalContext* globalCtx);
+void func_8095DABC(Actor* thisx, GlobalContext* globalCtx);
+void func_8095DDA8(EnIshi* this, GlobalContext* globalCtx);
+void func_8095DE9C(EnIshi* this, GlobalContext* globalCtx);
+void func_8095E5AC(EnIshi* this);
void func_8095E5C0(EnIshi* this, GlobalContext* globalCtx);
+void func_8095E64C(EnIshi* this);
void func_8095E660(EnIshi* this, GlobalContext* globalCtx);
+void func_8095E934(EnIshi* this);
void func_8095E95C(EnIshi* this, GlobalContext* globalCtx);
+void func_8095EA70(EnIshi* this);
void func_8095EBDC(EnIshi* this, GlobalContext* globalCtx);
+void func_8095F060(EnIshi* this);
void func_8095F0A4(EnIshi* this, GlobalContext* globalCtx);
+void func_8095F180(EnIshi* this);
void func_8095F194(EnIshi* this, GlobalContext* globalCtx);
+void func_8095F210(EnIshi* this, GlobalContext* globalCtx);
+void func_8095F36C(EnIshi* this, GlobalContext* globalCtx);
+void func_8095F61C(Actor* thisx, GlobalContext* globalCtx);
+void func_8095F654(Actor* thisx, GlobalContext* globalCtx);
+
+static s16 D_8095F690 = 0;
+
+static s16 D_8095F694 = 0;
-#if 0
const ActorInit En_Ishi_InitVars = {
ACTOR_EN_ISHI,
ACTORCAT_PROP,
@@ -34,109 +54,702 @@ const ActorInit En_Ishi_InitVars = {
(ActorFunc)NULL,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_8095F6EC = {
- { COLTYPE_HARD, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x01C37FBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
- { 10, 18, -2, { 0, 0, 0 } },
+static f32 D_8095F6B8[] = { 0.1f, 0.4f };
+
+static f32 D_8095F6C0[] = { 58.0f, 80.0f };
+
+static f32 D_8095F6C8[] = { 0.0f, 0.005f };
+
+static u16 D_8095F6D0[] = { NA_SE_EV_ROCK_BROKEN, NA_SE_EV_WALL_BROKEN };
+
+static u8 D_8095F6D4[] = { 25, 40 };
+
+static EnIshiUnkFunc2 D_8095F6D8[] = { func_8095D804, func_8095DABC };
+
+static EnIshiUnkFunc D_8095F6E0[] = { func_8095DDA8, func_8095DE9C };
+
+static s16 D_8095F6E8[] = { GAMEPLAY_FIELD_KEEP, OBJECT_ISHI };
+
+static ColliderCylinderInit sCylinderInit[] = {
+ {
+ {
+ COLTYPE_HARD,
+ AT_ON | AT_TYPE_PLAYER,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00400000, 0x00, 0x02 },
+ { 0x01C37FBE, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 10, 18, -2, { 0, 0, 0 } },
+ },
+ {
+ {
+ COLTYPE_HARD,
+ AT_ON | AT_TYPE_PLAYER,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00400000, 0x00, 0x02 },
+ { 0x01C37BB6, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 55, 70, 0, { 0, 0, 0 } },
+ },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_8095F718 = {
- { COLTYPE_HARD, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
- { 55, 70, 0, { 0, 0, 0 } },
+static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE };
+
+static s16 D_8095F74C[] = { 16, 13, 11, 9, 7, 5 };
+
+static s16 D_8095F758[] = { 145, 135, 120, 100, 70, 50, 45, 40, 35 };
+
+static s16 D_8095F76C[] = { -1, 1, 2, 20, 8, 0 };
+
+static Vec3f D_8095F778 = { 0.0f, 1.0f, 0.0f };
+
+static InitChainEntry sInitChain[][5] = {
+ {
+ ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE),
+ ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
+ },
+ {
+ ICHAIN_F32_DIV1000(gravity, -2500, ICHAIN_CONTINUE),
+ ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
+ },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit D_8095F744 = { 0, 12, 60, MASS_IMMOVABLE };
+static u16 D_8095F7AC[] = { NA_SE_PL_PULL_UP_ROCK, NA_SE_PL_PULL_UP_BIGROCK };
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8095F784[] = {
- ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE),
- ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
-};
+static EnIshiUnkFunc D_8095F7B0[] = { func_8095F210, func_8095F36C };
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8095F798[] = {
- ICHAIN_F32_DIV1000(gravity, -2500, ICHAIN_CONTINUE),
- ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
-};
+void func_8095D6E0(Actor* thisx, GlobalContext* globalCtx) {
+ EnIshi* this = THIS;
-#endif
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit[ENISHI_GET_1(&this->actor)]);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+}
-extern ColliderCylinderInit D_8095F6EC;
-extern ColliderCylinderInit D_8095F718;
-extern CollisionCheckInfoInit D_8095F744;
-extern InitChainEntry D_8095F784[];
-extern InitChainEntry D_8095F798[];
+s32 func_8095D758(EnIshi* this, GlobalContext* globalCtx, f32 arg2) {
+ Vec3f sp24;
+ s32 sp20;
-extern UNK_TYPE D_060009B0;
+ sp24.x = this->actor.world.pos.x;
+ sp24.y = this->actor.world.pos.y + 30.0f;
+ sp24.z = this->actor.world.pos.z;
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp20, &this->actor, &sp24);
+ if (this->actor.floorHeight > BGCHECK_Y_MIN) {
+ this->actor.world.pos.y = this->actor.floorHeight + arg2;
+ Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
+ return true;
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D6E0.s")
+void func_8095D804(Actor* thisx, GlobalContext* globalCtx) {
+ EnIshi* this = THIS;
+ s32 i;
+ s16 temp;
+ Gfx* phi_s4;
+ Vec3f spC4;
+ Vec3f spB8;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D758.s")
+ if (!ENISHI_GET_8(&this->actor)) {
+ phi_s4 = gameplay_field_keep_DL_0066B0;
+ } else {
+ phi_s4 = object_ishi_DL_0009B0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D804.s")
+ temp = D_8095F6E8[ENISHI_GET_8(&this->actor)];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DABC.s")
+ for (i = 0; i < ARRAY_COUNT(D_8095F74C); i++) {
+ spB8.x = ((Rand_ZeroOne() - 0.5f) * 8.0f) + this->actor.world.pos.x;
+ spB8.y = (Rand_ZeroOne() * 5.0f) + this->actor.world.pos.y + 5.0f;
+ spB8.z = ((Rand_ZeroOne() - 0.5f) * 8.0f) + this->actor.world.pos.z;
+ Math_Vec3f_Copy(&spC4, &this->actor.velocity);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DDA8.s")
+ if (this->actor.bgCheckFlags & 1) {
+ spC4.x *= 0.6f;
+ spC4.y *= -0.3f;
+ spC4.z *= 0.6f;
+ } else if (this->actor.bgCheckFlags & 8) {
+ spC4.x *= -0.5f;
+ spC4.y *= 0.5f;
+ spC4.z *= -0.5f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DE9C.s")
+ spC4.x += (Rand_ZeroOne() - 0.5f) * 11.0f;
+ spC4.y += (Rand_ZeroOne() * 7.0f) + 6.0f;
+ spC4.z += (Rand_ZeroOne() - 0.5f) * 11.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DF90.s")
+ EffectSsKakera_Spawn(globalCtx, &spB8, &spC4, &spB8, -420, (Rand_Next() > 0) ? 65 : 33, 30, 5, 0, D_8095F74C[i],
+ 3, 10, 40, -1, temp, phi_s4);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DFF0.s")
+void func_8095DABC(Actor* thisx, GlobalContext* globalCtx) {
+ EnIshi* this = THIS;
+ Vec3f spD8;
+ Vec3f spCC;
+ f32 temp_f20;
+ s16 temp_s1 = 0x1000;
+ s32 i;
+ s16 phi_v0;
+ s16 phi_v1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E14C.s")
+ for (i = 0; i < ARRAY_COUNT(D_8095F758); i++) {
+ temp_s1 += 0x4E20;
+ temp_f20 = Rand_ZeroOne() * 10.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E180.s")
+ spCC.x = (Math_SinS(temp_s1) * temp_f20) + this->actor.world.pos.x;
+ spCC.y = (Rand_ZeroOne() * 40.0f) + this->actor.world.pos.y + 5.0f;
+ spCC.z = (Math_CosS(temp_s1) * temp_f20) + this->actor.world.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E204.s")
+ Math_Vec3f_Copy(&spD8, &this->actor.velocity);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E2B0.s")
+ if (this->actor.bgCheckFlags & 1) {
+ spD8.x *= 0.9f;
+ spD8.y *= -0.8f;
+ spD8.z *= 0.9f;
+ } else if (this->actor.bgCheckFlags & 8) {
+ spD8.x *= -0.9f;
+ spD8.y *= 0.8f;
+ spD8.z *= -0.9f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Init.s")
+ temp_f20 = Rand_ZeroOne() * 10.0f;
+ spD8.x += temp_f20 * Math_SinS(temp_s1);
+ spD8.y += (Rand_ZeroOne() * 4.0f) + (Rand_ZeroOne() * i * 0.7f);
+ spD8.z += temp_f20 * Math_CosS(temp_s1);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Destroy.s")
+ if (i == 0) {
+ phi_v0 = 41;
+ phi_v1 = -450;
+ } else if (i < 4) {
+ phi_v0 = 37;
+ phi_v1 = -380;
+ } else {
+ phi_v0 = 69;
+ phi_v1 = -320;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E5AC.s")
+ EffectSsKakera_Spawn(globalCtx, &spCC, &spD8, &this->actor.world.pos, phi_v1, phi_v0, 30, 5, 0, D_8095F758[i],
+ 5, 2, 70, 0, 2, gameplay_field_keep_DL_006420);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E5C0.s")
+void func_8095DDA8(EnIshi* this, GlobalContext* globalCtx) {
+ Vec3f sp2C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E64C.s")
+ Math_Vec3f_Copy(&sp2C, &this->actor.world.pos);
+ if (this->actor.bgCheckFlags & 1) {
+ sp2C.x += 2.0f * this->actor.velocity.x;
+ sp2C.y -= 2.0f * this->actor.velocity.y;
+ sp2C.z += 2.0f * this->actor.velocity.z;
+ } else if (this->actor.bgCheckFlags & 8) {
+ sp2C.x -= 2.0f * this->actor.velocity.x;
+ sp2C.y += 2.0f * this->actor.velocity.y;
+ sp2C.z -= 2.0f * this->actor.velocity.z;
+ }
+ func_800BBFB0(globalCtx, &sp2C, 60.0f, 3, 80, 60, 1);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E660.s")
+void func_8095DE9C(EnIshi* this, GlobalContext* globalCtx) {
+ Vec3f sp2C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E934.s")
+ Math_Vec3f_Copy(&sp2C, &this->actor.world.pos);
+ if (this->actor.bgCheckFlags & 1) {
+ sp2C.x += 2.0f * this->actor.velocity.x;
+ sp2C.y -= 2.0f * this->actor.velocity.y;
+ sp2C.z += 2.0f * this->actor.velocity.z;
+ } else if (this->actor.bgCheckFlags & 8) {
+ sp2C.x -= 2.0f * this->actor.velocity.x;
+ sp2C.y += 2.0f * this->actor.velocity.y;
+ sp2C.z -= 2.0f * this->actor.velocity.z;
+ }
+ func_800BBFB0(globalCtx, &sp2C, 140.0f, 10, 180, 90, 1);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E95C.s")
+void func_8095DF90(EnIshi* this, GlobalContext* globalCtx) {
+ if (!ENISHI_GET_1(&this->actor) && !ENISHI_GET_100(&this->actor)) {
+ Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, ENISHI_GET_F0(&this->actor) * 0x10);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095EA70.s")
+void func_8095DFF0(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 temp = D_8095F76C[ENISHI_GET_70(&this->actor)];
+ Actor* sp3C;
+ Vec3f sp30;
+ f32 sp2C;
+ f32 temp_f2;
+ s16 temp_v1_2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095EBDC.s")
+ if (temp >= 0) {
+ sp3C = Item_DropCollectible(globalCtx, &this->actor.world.pos, temp | (ENISHI_GET_FE00(&this->actor) << 8));
+ if (sp3C != NULL) {
+ Matrix_StatePush();
+ Matrix_RotateY(this->actor.shape.rot.y, 0);
+ Matrix_InsertXRotation_s(this->actor.shape.rot.x, 1);
+ Matrix_InsertZRotation_s(this->actor.shape.rot.z, 1);
+ Matrix_GetStateTranslationAndScaledY(1.0f, &sp30);
+ sp2C = Math3D_Parallel(&sp30, &D_8095F778);
+ if (sp2C < 0.707f) {
+ temp_v1_2 = Math_FAtan2F(sp30.z, sp30.x) - sp3C->world.rot.y;
+ if (ABS_ALT(temp_v1_2) > 0x4000) {
+ sp3C->world.rot.y = BINANG_ROT180(sp3C->world.rot.y);
+ }
+ temp_f2 = sp2C + 0.5f;
+ if (temp_f2 < 0.5f) {
+ temp_f2 = 0.5f;
+ }
+ sp3C->velocity.y *= temp_f2;
+ }
+ Matrix_StatePop();
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F060.s")
+void func_8095E14C(EnIshi* this) {
+ this->actor.velocity.y += this->actor.gravity;
+ if (this->actor.velocity.y < this->actor.minVelocityY) {
+ this->actor.velocity.y = this->actor.minVelocityY;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F0A4.s")
+void func_8095E180(Vec3f* arg0, f32 arg1) {
+ arg1 += ((Rand_ZeroOne() * 0.2f) - 0.1f) * arg1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F180.s")
+ arg0->x -= arg0->x * arg1;
+ arg0->y -= arg0->y * arg1;
+ arg0->z -= arg0->z * arg1;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F194.s")
+void func_8095E204(EnIshi* this, GlobalContext* globalCtx) {
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Update.s")
+ for (i = 0; i < 3; i++) {
+ if (Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INSECT, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 1,
+ this->actor.cutscene, this->actor.unk20, NULL) == NULL) {
+ break;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F210.s")
+s32 func_8095E2B0(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ WaterBox* sp30;
+ f32 sp2C;
+ s32 sp28;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F36C.s")
+ if (WaterBox_GetSurfaceImpl(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp2C,
+ &sp30, &sp28) &&
+ (this->actor.world.pos.y < sp2C)) {
+ return true;
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F61C.s")
+void EnIshi_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnIshi* this = THIS;
+ s32 sp34 = ENISHI_GET_1(&this->actor);
+ s32 sp30 = ENISHI_GET_4(&this->actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F654.s")
+ if ((sp34 == 0) && (sp30 != 0)) {
+ this->unk_197 |= 2;
+ }
+
+ Actor_ProcessInitChain(&this->actor, sInitChain[sp34]);
+
+ if (globalCtx->csCtx.state != 0) {
+ this->actor.uncullZoneForward += 1000.0f;
+ }
+
+ if ((this->actor.shape.rot.y == 0) && !(this->unk_197 & 2)) {
+ this->actor.shape.rot.y = this->actor.world.rot.y = (u32)Rand_Next() >> 0x10;
+ }
+
+ Actor_SetScale(&this->actor, D_8095F6B8[sp34]);
+ func_8095D6E0(&this->actor, globalCtx);
+
+ if ((sp34 == 1) && Flags_GetSwitch(globalCtx, ENISHI_GET_FE00(&this->actor))) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
+
+ if (sp34 == 1) {
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ this->actor.shape.shadowScale = 2.3f;
+ } else {
+ this->actor.shape.shadowScale = 2.4f;
+ this->actor.shape.shadowAlpha = 160;
+ }
+
+ this->actor.shape.yOffset = D_8095F6C0[sp34];
+
+ if ((sp30 == 0) && !func_8095D758(this, globalCtx, 0)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if (func_8095E2B0(this, globalCtx)) {
+ this->unk_197 |= 1;
+ }
+
+ this->unk_196 = Object_GetIndex(&globalCtx->objectCtx, D_8095F6E8[ENISHI_GET_8(&this->actor)]);
+ if (this->unk_196 < 0) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ func_8095E5AC(this);
+}
+
+void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ Collider_DestroyCylinder(globalCtx, &THIS->collider);
+}
+
+void func_8095E5AC(EnIshi* this) {
+ this->actionFunc = func_8095E5C0;
+}
+
+void func_8095E5C0(EnIshi* this, GlobalContext* globalCtx) {
+ if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_196)) {
+ this->actor.objBankIndex = this->unk_196;
+ this->actor.flags &= ~0x10;
+ if (!ENISHI_GET_8(&this->actor)) {
+ this->actor.draw = func_8095F61C;
+ } else {
+ this->actor.draw = func_8095F654;
+ }
+ func_8095E64C(this);
+ }
+}
+
+void func_8095E64C(EnIshi* this) {
+ this->actionFunc = func_8095E660;
+}
+
+void func_8095E660(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 sp38 = ENISHI_GET_1(&this->actor);
+ s32 sp34 = (this->collider.base.acFlags & AC_HIT) != 0;
+ s32 sp30 = this->unk_197 & 2;
+
+ if (sp34) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ }
+
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ func_8095E934(this);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, D_8095F7AC[sp38]);
+ if (ENISHI_GET_2(&this->actor)) {
+ func_8095E204(this, globalCtx);
+ }
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ return;
+ }
+
+ if (sp34 && (sp38 == 0) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x508)) {
+ if (sp30 != 0) {
+ func_8095DFF0(this, globalCtx);
+ func_8095F060(this);
+ return;
+ }
+ func_8095DF90(this, globalCtx);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp38], D_8095F6D0[sp38]);
+ D_8095F6D8[sp38](&this->actor, globalCtx);
+ D_8095F6E0[sp38](this, globalCtx);
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if (sp34) {
+ this->unk_195 = 5;
+ }
+
+ if ((this->actor.xzDistToPlayer < 600.0f) || (sp30 != 0)) {
+ if (this->unk_195 > 0) {
+ this->unk_195--;
+ if (this->unk_195 == 0) {
+ this->collider.base.colType = sCylinderInit[sp38].base.colType;
+ } else {
+ this->collider.base.colType = COLTYPE_NONE;
+ }
+ }
+
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+
+ if ((this->actor.xzDistToPlayer < 90.0f) && (sp30 == 0)) {
+ if (sp38 == 1) {
+ func_800B8A1C(&this->actor, globalCtx, 0, 80.0f, 20.0f);
+ } else {
+ func_800B8A1C(&this->actor, globalCtx, 0, 50.0f, 10.0f);
+ }
+ }
+ }
+}
+
+void func_8095E934(EnIshi* this) {
+ this->actionFunc = func_8095E95C;
+ this->actor.room = -1;
+ this->actor.flags |= 0x10;
+}
+
+void func_8095E95C(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Vec3f sp30;
+ s32 sp2C;
+
+ if (Actor_HasNoParent(&this->actor, globalCtx)) {
+ this->actor.room = globalCtx->roomCtx.currRoom.num;
+ if (ENISHI_GET_1(&this->actor) == 1) {
+ Actor_SetSwitchFlag(globalCtx, ENISHI_GET_FE00(&this->actor));
+ }
+ func_8095EA70(this);
+ func_8095E14C(this);
+ func_8095E180(&this->actor.velocity, D_8095F6C8[ENISHI_GET_1(&this->actor)]);
+ Actor_ApplyMovement(&this->actor);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
+ } else {
+ sp30.x = this->actor.world.pos.x;
+ sp30.y = this->actor.world.pos.y + 20.0f;
+ sp30.z = this->actor.world.pos.z;
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30);
+ }
+}
+
+void func_8095EA70(EnIshi* this) {
+ f32 sp24;
+
+ this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ;
+ this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ;
+ if (!ENISHI_GET_1(&this->actor)) {
+ sp24 = Rand_ZeroOne() - 0.9f;
+ D_8095F690 = sp24 * 11000.0f;
+ D_8095F694 = ((Rand_ZeroOne() - 0.5f) * 3000.0f) * (fabsf(sp24) + 0.1f);
+ } else {
+ sp24 = Rand_ZeroOne() - 0.5f;
+ D_8095F690 = sp24 * 6000.0f;
+ D_8095F694 = ((Rand_ZeroOne() - 0.5f) * 1200.0f) * (fabsf(sp24) + 0.5f);
+ }
+ this->actor.colChkInfo.mass = 200;
+ this->unk_194 = 100;
+ this->actionFunc = func_8095EBDC;
+}
+
+void func_8095EBDC(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 sp70 = ENISHI_GET_1(&this->actor);
+ s16 temp_s0;
+ s32 i;
+ s16 phi_s0;
+ Vec3f sp58;
+ s32 temp_v0 = (this->collider.base.atFlags & AT_HIT) != 0;
+
+ if (temp_v0) {
+ this->collider.base.atFlags &= ~AT_HIT;
+ }
+
+ this->unk_194--;
+
+ if ((this->actor.bgCheckFlags & 9) || temp_v0 || (this->unk_194 <= 0)) {
+ func_8095DF90(this, globalCtx);
+ D_8095F6D8[sp70](&this->actor, globalCtx);
+
+ if (!(this->actor.bgCheckFlags & 0x20)) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp70], D_8095F6D0[sp70]);
+ D_8095F6E0[sp70](this, globalCtx);
+ }
+
+ if (sp70 == 1) {
+ s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3);
+
+ Quake_SetSpeed(quake, 0x4350);
+ Quake_SetQuakeValues(quake, 3, 0, 0, 0);
+ Quake_SetCountdown(quake, 7);
+ func_8013ECE0(this->actor.xyzDistToPlayerSq, 255, 20, 150);
+ }
+
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if (this->actor.bgCheckFlags & 0x40) {
+ if (sp70 == 0) {
+ sp58.x = this->actor.world.pos.x;
+ sp58.y = this->actor.world.pos.y + this->actor.depthInWater;
+ sp58.z = this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 350);
+ EffectSsGRipple_Spawn(globalCtx, &sp58, 150, 650, 0);
+ } else {
+ sp58.y = this->actor.world.pos.y + this->actor.depthInWater;
+
+ for (phi_s0 = 0, i = 0; i < 11; i++, phi_s0 += 0x1746) {
+ sp58.x = (Math_SinS((s32)(Rand_ZeroOne() * 2000.0f) + phi_s0) * 50.0f) + this->actor.world.pos.x;
+ sp58.z = (Math_CosS((s32)(Rand_ZeroOne() * 2000.0f) + phi_s0) * 50.0f) + this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 350);
+ }
+
+ sp58.x = this->actor.world.pos.x;
+ sp58.z = this->actor.world.pos.z;
+ EffectSsGRipple_Spawn(globalCtx, &sp58, 500, 900, 4);
+ }
+
+ this->actor.minVelocityY = -6.0f;
+ this->actor.velocity.x *= 0.12f;
+ this->actor.velocity.y *= 0.4f;
+ this->actor.velocity.z *= 0.12f;
+ this->actor.gravity *= 0.5f;
+
+ D_8095F690 >>= 2;
+ D_8095F694 >>= 2;
+
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
+ this->actor.bgCheckFlags &= ~0x40;
+ }
+
+ Math_StepToF(&this->actor.shape.yOffset, 0.0f, 2.0f);
+ func_8095E14C(this);
+ func_8095E180(&this->actor.velocity, D_8095F6C8[sp70]);
+ Actor_ApplyMovement(&this->actor);
+ this->actor.shape.rot.x += D_8095F690;
+ this->actor.shape.rot.y += D_8095F694;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+void func_8095F060(EnIshi* this) {
+ this->actor.flags |= 0x10;
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ this->actionFunc = func_8095F0A4;
+}
+
+void func_8095F0A4(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 sp28 = ENISHI_GET_1(&this->actor);
+
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp28], D_8095F6D0[sp28]);
+ D_8095F6D8[sp28](&this->actor, globalCtx);
+ D_8095F6E0[sp28](this, globalCtx);
+ this->actor.draw = NULL;
+ func_8095F180(this);
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
+
+void func_8095F180(EnIshi* this) {
+ this->actionFunc = func_8095F194;
+}
+
+void func_8095F194(EnIshi* this, GlobalContext* globalCtx) {
+ if (this->actor.cutscene < 0) {
+ Actor_MarkForDeath(&this->actor);
+ } else if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnIshi* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+}
+
+void func_8095F210(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 sp28;
+
+ if ((this->actor.projectedPos.z <= 1200.0f) || ((this->unk_197 & 1) && (this->actor.projectedPos.z < 1300.0f))) {
+ func_800BDFC0(globalCtx, gameplay_field_keep_DL_0066B0);
+ return;
+ }
+
+ if (this->actor.projectedPos.z < 1300.0f) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ sp28 = (1300.0f - this->actor.projectedPos.z) * 2.55f;
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s32)sp28);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_field_keep_DL_006760);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+}
+
+void func_8095F36C(EnIshi* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if ((this->actor.projectedPos.z <= 2150.0f) || ((this->unk_197 & 1) && (this->actor.projectedPos.z < 2250.0f))) {
+ this->actor.shape.shadowAlpha = 160;
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
+ gSPDisplayList(POLY_OPA_DISP++, gameplay_field_keep_DL_0061E8);
+ } else if (this->actor.projectedPos.z < 2250.0f) {
+ f32 sp20 = (2250.0f - this->actor.projectedPos.z) * 2.55f;
+
+ this->actor.shape.shadowAlpha = sp20 * 0.627451f;
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s32)sp20);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_field_keep_DL_0061E8);
+ } else {
+ this->actor.shape.shadowAlpha = 0;
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_8095F61C(Actor* thisx, GlobalContext* globalCtx) {
+ EnIshi* this = THIS;
+
+ D_8095F7B0[ENISHI_GET_1(&this->actor)](this, globalCtx);
+}
+
+void func_8095F654(Actor* thisx, GlobalContext* globalCtx) {
+ func_800BDFC0(globalCtx, object_ishi_DL_0009B0);
+}
diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h
index f68667c7d..404fec2b1 100644
--- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h
+++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h
@@ -6,12 +6,26 @@
struct EnIshi;
typedef void (*EnIshiActionFunc)(struct EnIshi*, GlobalContext*);
+typedef void (*EnIshiUnkFunc)(struct EnIshi*, GlobalContext*);
+typedef void (*EnIshiUnkFunc2)(Actor*, GlobalContext*);
+
+#define ENISHI_GET_1(thisx) ((thisx)->params & 1)
+#define ENISHI_GET_2(thisx) (((thisx)->params >> 1) & 1)
+#define ENISHI_GET_4(thisx) (((thisx)->params >> 2) & 1)
+#define ENISHI_GET_8(thisx) (((thisx)->params >> 3) & 1)
+#define ENISHI_GET_70(thisx) (((thisx)->params >> 4) & 7)
+#define ENISHI_GET_F0(thisx) (((thisx)->params >> 4) & 0xF)
+#define ENISHI_GET_100(thisx) (((thisx)->params >> 8) & 1)
+#define ENISHI_GET_FE00(thisx) (((thisx)->params >> 9) & 0x7F)
typedef struct EnIshi {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x4C];
+ /* 0x0144 */ ColliderCylinder collider;
/* 0x0190 */ EnIshiActionFunc actionFunc;
- /* 0x0194 */ char unk_194[0x4];
+ /* 0x0194 */ s8 unk_194;
+ /* 0x0195 */ s8 unk_195;
+ /* 0x0196 */ s8 unk_196;
+ /* 0x0197 */ u8 unk_197;
} EnIshi; // size = 0x198
extern const ActorInit En_Ishi_InitVars;
diff --git a/src/overlays/actors/ovl_En_Kame/z_en_kame.c b/src/overlays/actors/ovl_En_Kame/z_en_kame.c
index c8cceba61..71482f79f 100644
--- a/src/overlays/actors/ovl_En_Kame/z_en_kame.c
+++ b/src/overlays/actors/ovl_En_Kame/z_en_kame.c
@@ -5,6 +5,7 @@
*/
#include "z_en_kame.h"
+#include "objects/object_tl/object_tl.h"
#define FLAGS 0x00000405
@@ -15,21 +16,31 @@ void EnKame_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnKame_Update(Actor* thisx, GlobalContext* globalCtx);
void EnKame_Draw(Actor* thisx, GlobalContext* globalCtx);
+void func_80AD70A0(EnKame* this);
void func_80AD70EC(EnKame* this, GlobalContext* globalCtx);
+void func_80AD71B4(EnKame* this);
void func_80AD7254(EnKame* this, GlobalContext* globalCtx);
+void func_80AD73A8(EnKame* this);
void func_80AD7424(EnKame* this, GlobalContext* globalCtx);
+void func_80AD76CC(EnKame* this);
void func_80AD7798(EnKame* this, GlobalContext* globalCtx);
+void func_80AD792C(EnKame* this);
void func_80AD7948(EnKame* this, GlobalContext* globalCtx);
+void func_80AD7B18(EnKame* this);
void func_80AD7B90(EnKame* this, GlobalContext* globalCtx);
void func_80AD7D40(EnKame* this, GlobalContext* globalCtx);
+void func_80AD7DA4(EnKame* this);
void func_80AD7E0C(EnKame* this, GlobalContext* globalCtx);
+void func_80AD7EC0(EnKame* this);
void func_80AD7F10(EnKame* this, GlobalContext* globalCtx);
void func_80AD7FF8(EnKame* this, GlobalContext* globalCtx);
void func_80AD810C(EnKame* this, GlobalContext* globalCtx);
+void func_80AD8148(EnKame* this, GlobalContext* globalCtx);
void func_80AD825C(EnKame* this, GlobalContext* globalCtx);
+void func_80AD8364(EnKame* this);
void func_80AD8388(EnKame* this, GlobalContext* globalCtx);
+void func_80AD8D64(Actor* thisx, GlobalContext* globalCtx);
-#if 0
const ActorInit En_Kame_InitVars = {
ACTOR_EN_KAME,
ACTORCAT_ENEMY,
@@ -42,18 +53,29 @@ const ActorInit En_Kame_InitVars = {
(ActorFunc)EnKame_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80AD8DE0 = {
- { COLTYPE_HARD, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CF7FFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_HARD,
+ AT_NONE | AT_TYPE_ENEMY,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x04 },
+ { 0xF7CF7FFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON | BUMP_HOOKABLE,
+ OCELEM_ON,
+ },
{ 35, 40, 0, { 0, 0, 0 } },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit D_80AD8E0C = { 3, 15, 30, 80 };
+static CollisionCheckInfoInit sColChkInfoInit = { 3, 15, 30, 80 };
-// static DamageTable sDamageTable = {
-static DamageTable D_80AD8E14 = {
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x1),
/* Deku Stick */ DMG_ENTRY(1, 0x0),
/* Horse trample */ DMG_ENTRY(1, 0x0),
@@ -88,107 +110,733 @@ static DamageTable D_80AD8E14 = {
/* Powder Keg */ DMG_ENTRY(1, 0xF),
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80AD8E44[] = {
+static TexturePtr D_80AD8E34[] = { object_tl_Tex_0055A0, object_tl_Tex_0057A0, object_tl_Tex_0059A0,
+ object_tl_Tex_0057A0 };
+
+static InitChainEntry sInitChain[] = {
ICHAIN_S8(hintId, 1, ICHAIN_CONTINUE),
ICHAIN_F32(gravity, -1, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 3500, ICHAIN_STOP),
};
-#endif
+static s32 D_80AD8E50 = false;
-extern ColliderCylinderInit D_80AD8DE0;
-extern CollisionCheckInfoInit D_80AD8E0C;
-extern DamageTable D_80AD8E14;
-extern InitChainEntry D_80AD8E44[];
+void EnKame_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnKame* this = THIS;
-extern UNK_TYPE D_060008B4;
-extern UNK_TYPE D_06000AF4;
-extern UNK_TYPE D_06001C68;
-extern UNK_TYPE D_06002510;
-extern UNK_TYPE D_060027D8;
-extern UNK_TYPE D_06002F88;
-extern UNK_TYPE D_060031DC;
-extern UNK_TYPE D_060035EC;
-extern UNK_TYPE D_06004210;
-extern UNK_TYPE D_0600823C;
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime1, &object_tl_Skel_007C70, &object_tl_Anim_004210, this->jointTable1,
+ this->morphTable1, 13);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime2, &object_tl_Skel_001A50, &object_tl_Anim_000B30, this->jointTable2,
+ this->morphTable2, 4);
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 55.0f);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Init.s")
+ if (!D_80AD8E50) {
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Destroy.s")
+ for (i = 0; i < ARRAY_COUNT(D_80AD8E34); i++) {
+ D_80AD8E34[i] = Lib_SegmentedToVirtual(D_80AD8E34[i]);
+ }
+ D_80AD8E50 = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD6F34.s")
+ func_80AD70A0(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD6F9C.s")
+void EnKame_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnKame* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7018.s")
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD70A0.s")
+void func_80AD6F34(EnKame* this) {
+ if (this->unk_29C != 0) {
+ this->unk_29C++;
+ if (this->unk_29C == 4) {
+ this->unk_29C = 0;
+ }
+ } else if (Rand_ZeroOne() < 0.05f) {
+ this->unk_29C = 1;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD70EC.s")
+void func_80AD6F9C(EnKame* this) {
+ this->unk_29D = 10;
+ this->unk_2B4 = 0.6f;
+ this->unk_2B8 = 0.90000004f;
+ this->unk_2B0 = 1.0f;
+ this->collider.base.colType = COLTYPE_HIT3;
+ this->unk_2A2 = 80;
+ this->actor.flags &= ~0x400;
+ func_800BCB70(&this->actor, 0x4000, 255, 0, 80);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD71B4.s")
+void func_80AD7018(EnKame* this, GlobalContext* globalCtx) {
+ if (this->unk_29D == 10) {
+ this->unk_29D = 0;
+ this->collider.base.colType = COLTYPE_HIT6;
+ this->unk_2B0 = 0.0f;
+ func_800BF7CC(globalCtx, &this->actor, this->unk_2C8, 10, 2, 0.3f, 0.2f);
+ this->actor.flags |= 0x400;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7254.s")
+void func_80AD70A0(EnKame* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_004210, -5.0f);
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = func_80AD70EC;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD73A8.s")
+void func_80AD70EC(EnKame* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7424.s")
+ if (Animation_OnFrame(&this->skelAnime1, 10.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_VOICE);
+ this->unk_2A0 = 40;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7568.s")
+ if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) &&
+ (this->actor.xzDistToPlayer < 240.0f)) {
+ func_80AD73A8(this);
+ } else if (SkelAnime_Update(&this->skelAnime1)) {
+ func_80AD71B4(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD75A8.s")
+void func_80AD71B4(EnKame* this) {
+ Animation_MorphToLoop(&this->skelAnime1, &object_tl_Anim_00823C, -5.0f);
+ this->actor.speedXZ = 0.5f;
+ this->unk_29E = Animation_GetLastFrame(&object_tl_Anim_00823C) * ((s32)Rand_ZeroFloat(5.0f) + 3);
+ this->unk_2A4 = this->actor.shape.rot.y;
+ this->collider.base.acFlags |= (AC_HARD | AC_ON);
+ this->collider.base.colType = COLTYPE_HARD;
+ this->actionFunc = func_80AD7254;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD76CC.s")
+void func_80AD7254(EnKame* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7798.s")
+ if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) &&
+ (this->actor.xzDistToPlayer < 240.0f)) {
+ func_80AD73A8(this);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD792C.s")
+ SkelAnime_Update(&this->skelAnime1);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7948.s")
+ if (this->unk_2A4 != this->actor.shape.rot.y) {
+ Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_2A4, 0x100);
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 40.0f) {
+ this->unk_2A4 = Actor_YawToPoint(&this->actor, &this->actor.home.pos) + (Rand_Next() >> 0x14);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7B18.s")
+ this->unk_29E--;
+ if (this->unk_29E == 0) {
+ func_80AD70A0(this);
+ } else if (Animation_OnFrame(&this->skelAnime1, 0.0f) || Animation_OnFrame(&this->skelAnime1, 15.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_WALK);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7B90.s")
+void func_80AD73A8(EnKame* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_001C68, -3.0f);
+ this->unk_29E = 0;
+ this->unk_2AC = 1.0f;
+ this->unk_2A8 = 1.0f;
+ this->actor.speedXZ = 0.0f;
+ if (this->unk_2A0 == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_VOICE);
+ }
+ this->actionFunc = func_80AD7424;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7C54.s")
+void func_80AD7424(EnKame* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7D40.s")
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) &&
+ ((this->unk_29E == 0) || (this->actor.xzDistToPlayer < 120.0f))) {
+ func_80AD76CC(this);
+ } else {
+ this->unk_29E--;
+ if (this->unk_29E == 0) {
+ func_80AD7B18(this);
+ }
+ }
+ } else if (this->skelAnime1.curFrame > 2.0f) {
+ this->unk_2AC = 1.5f - ((this->skelAnime1.curFrame - 2.0f) * (7.0f / 30));
+ this->unk_2A8 = 1.5f - ((this->skelAnime1.curFrame - 2.0f) * (1.0f / 12));
+ } else {
+ f32 frame = this->skelAnime1.curFrame;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7DA4.s")
+ this->unk_2AC = (0.25f * frame) + 1.0f;
+ this->unk_2A8 = (0.25f * frame) + 1.0f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7E0C.s")
+void func_80AD7568(EnKame* this) {
+ this->actor.speedXZ = this->unk_2A6 * (5.0f / 7552);
+ this->actor.shape.rot.z = this->unk_2A6 * 0.11016949f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7EC0.s")
+void func_80AD75A8(EnKame* this, GlobalContext* globalCtx) {
+ static Color_RGBA8 D_80AD8E54 = { 250, 250, 250, 255 };
+ static Color_RGBA8 D_80AD8E58 = { 180, 180, 180, 255 };
+ static Vec3f D_80AD8E5C = { 0.0f, 0.75f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7F10.s")
+ if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ >= 3.0f)) {
+ if ((globalCtx->gameplayFrames % 2) == 0) {
+ u32 temp_v0 = func_800C9BB8(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7FA4.s")
+ if ((temp_v0 == 0) || (temp_v0 == 1)) {
+ func_800B1210(globalCtx, &this->actor.world.pos, &D_80AD8E5C, &gZeroVec3f, 550, 100);
+ } else if (temp_v0 == 14) {
+ func_800B0DE0(globalCtx, &this->actor.world.pos, &D_80AD8E5C, &gZeroVec3f, &D_80AD8E54, &D_80AD8E58,
+ 550, 100);
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7FF8.s")
+ if (this->unk_2A6 > 0x1200) {
+ func_800B9010(&this->actor, NA_SE_EN_PAMET_ROLL - SFX_FLAG);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8060.s")
+void func_80AD76CC(EnKame* this) {
+ if (this->actor.draw == EnKame_Draw) {
+ this->actor.draw = func_80AD8D64;
+ this->unk_2A6 = 0x3B00;
+ this->unk_2AC = 0.5f;
+ func_80AD7568(this);
+ this->unk_29E = 15;
+ this->actor.speedXZ = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_CUTTER_ON);
+ this->unk_2BC.y = this->actor.home.pos.y - 100.0f;
+ } else {
+ this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
+ Math_Vec3f_Copy(&this->unk_2BC, &this->actor.home.pos);
+ this->unk_29E = 0;
+ }
+ this->actor.flags |= 0x10;
+ this->actionFunc = func_80AD7798;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD810C.s")
+void func_80AD7798(EnKame* this, GlobalContext* globalCtx) {
+ if (this->unk_29E == 15) {
+ this->unk_2AC += 0.2f;
+ if (this->unk_2AC > 1.1f) {
+ this->unk_29E--;
+ this->collider.base.atFlags |= AT_ON;
+ this->unk_2AC = 1.0f;
+ }
+ } else if (this->unk_29E > 0) {
+ this->unk_29E--;
+ } else if (Math_ScaledStepToS(&this->unk_2A6, 0x3B00, (s32)(this->unk_2A6 * 0.09f) + 45)) {
+ if (this->unk_2BC.y < this->actor.home.pos.y) {
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ this->unk_2BC.x = (Math_SinS(this->actor.world.rot.y) * 360.0f) + this->actor.world.pos.x;
+ this->unk_2BC.z = (Math_CosS(this->actor.world.rot.y) * 360.0f) + this->actor.world.pos.z;
+ }
+ func_80AD792C(this);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8148.s")
+ this->actor.shape.rot.y += this->unk_2A6;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD825C.s")
+ if (!(this->unk_2BC.y < this->actor.home.pos.y) || (this->actionFunc != func_80AD7798)) {
+ func_80AD7568(this);
+ }
+ func_80AD75A8(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8364.s")
+void func_80AD792C(EnKame* this) {
+ this->unk_29E = -1;
+ this->actionFunc = func_80AD7948;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8388.s")
+void func_80AD7948(EnKame* this, GlobalContext* globalCtx) {
+ s32 temp_v1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD84C0.s")
+ this->actor.shape.rot.y += this->unk_2A6;
+ func_80AD75A8(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Update.s")
+ if (this->unk_29E == -1) {
+ s16 temp_v0 = Actor_YawToPoint(&this->actor, &this->unk_2BC) - this->actor.world.rot.y;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8A48.s")
+ temp_v1 = ABS_ALT(temp_v0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8AF8.s")
+ if ((this->actor.bgCheckFlags & 8) || (temp_v1 > 0x3000) ||
+ (Actor_XZDistanceToPoint(&this->actor, &this->unk_2BC) < 50.0f)) {
+ s8 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Draw.s")
+ if (this->unk_2BC.y < this->actor.home.pos.y) {
+ this->unk_29E = 0x300;
+ } else {
+ this->unk_29E = 0;
+ }
+ }
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8CEC.s")
+ if (Math_ScaledStepToS(&this->unk_2A6, this->unk_29E, (s32)(this->unk_2A6 * 0.09f) + 45)) {
+ if (this->unk_29E == 0) {
+ if (this->unk_2AC >= 1.0f) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_CUTTER_OFF);
+ }
+ this->unk_2AC -= 0.1f;
+ this->collider.base.atFlags &= ~AT_ON;
+ if (this->unk_2AC < 0.5f) {
+ this->actor.flags &= ~0x10;
+ func_80AD7B18(this);
+ }
+ } else {
+ func_80AD76CC(this);
+ }
+ }
+ func_80AD7568(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8D64.s")
+void func_80AD7B18(EnKame* this) {
+ this->actor.draw = EnKame_Draw;
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0031DC, -3.0f);
+ this->actor.speedXZ = 0.0f;
+ this->unk_2AC = 0.1f;
+ this->unk_2A8 = 1.0f;
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ this->actionFunc = func_80AD7B90;
+}
+
+void func_80AD7B90(EnKame* this, GlobalContext* globalCtx) {
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ func_80AD71B4(this);
+ } else if (this->skelAnime1.curFrame > 7.0f) {
+ this->unk_2AC = 1.5f - ((this->skelAnime1.curFrame - 7.0f) * (1.0f / 6));
+ this->unk_2A8 = 1.5f - ((this->skelAnime1.curFrame - 7.0f) * (1.0f / 6));
+ } else {
+ f32 frame = this->skelAnime1.curFrame;
+
+ this->unk_2AC = (0.2f * frame) + 0.1f;
+ this->unk_2A8 = ((1.0f / 14) * frame) + 1.0f;
+ }
+}
+
+void func_80AD7C54(EnKame* this) {
+ if (this->actionFunc == func_80AD7E0C) {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0035EC, -3.0f);
+ this->unk_29E = 1;
+ this->collider.info.bumper.dmgFlags &= ~0x8000;
+ } else {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0039C0, -3.0f);
+ this->unk_29E = 0;
+ this->collider.info.bumper.dmgFlags |= 0x8000;
+ }
+
+ this->actor.draw = EnKame_Draw;
+ this->actor.speedXZ = 0.0f;
+ this->collider.base.acFlags &= ~AC_ON;
+ this->collider.base.atFlags &= ~AT_ON;
+ this->collider.base.atFlags &= ~(AT_BOUNCED | AT_HIT);
+ this->actor.flags &= ~0x10;
+ this->actor.shape.rot.z = 0;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_REVERSE);
+ this->actionFunc = func_80AD7D40;
+}
+
+void func_80AD7D40(EnKame* this, GlobalContext* globalCtx) {
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ if (this->unk_29E == 1) {
+ func_80AD71B4(this);
+ } else {
+ this->unk_29E = 200;
+ func_80AD7DA4(this);
+ }
+ }
+}
+
+void func_80AD7DA4(EnKame* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0027D8, -3.0f);
+ this->collider.base.acFlags |= AC_ON;
+ this->collider.base.acFlags &= ~AC_HARD;
+ this->collider.base.colType = COLTYPE_HIT6;
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = func_80AD7E0C;
+}
+
+void func_80AD7E0C(EnKame* this, GlobalContext* globalCtx) {
+ if (this->unk_29E > 0) {
+ this->unk_29E--;
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ if (Rand_ZeroOne() > 0.5f) {
+ Animation_PlayOnce(&this->skelAnime1, &object_tl_Anim_0027D8);
+ } else {
+ Animation_PlayOnce(&this->skelAnime1, &object_tl_Anim_002F88);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_ROAR);
+ }
+ }
+ } else {
+ func_80AD7EC0(this);
+ }
+}
+
+void func_80AD7EC0(EnKame* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_002510, -3.0f);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_WAKEUP);
+ this->actionFunc = func_80AD7F10;
+}
+
+void func_80AD7F10(EnKame* this, GlobalContext* globalCtx) {
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ func_80AD71B4(this);
+ } else if (this->skelAnime1.curFrame >= 10.0f) {
+ this->actor.shape.shadowDraw = NULL;
+ this->collider.base.acFlags &= ~AC_ON;
+ this->collider.info.bumper.dmgFlags &= ~0x8000;
+ }
+}
+
+void func_80AD7FA4(EnKame* this) {
+ this->actor.speedXZ = 0.0f;
+ if (this->actor.velocity.y > 0.0f) {
+ this->actor.velocity.y = 0.0f;
+ }
+ func_800BE504(&this->actor, &this->collider);
+ this->actionFunc = func_80AD7FF8;
+}
+
+void func_80AD7FF8(EnKame* this, GlobalContext* globalCtx) {
+ if (this->unk_2A2 != 0) {
+ this->unk_2A2--;
+ }
+
+ if (this->unk_2A2 == 0) {
+ func_80AD7018(this, globalCtx);
+ if (this->actor.colChkInfo.health == 0) {
+ func_80AD8148(this, NULL);
+ } else {
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ func_80AD7DA4(this);
+ }
+ }
+}
+
+void func_80AD8060(EnKame* this) {
+ s16 sp36 = Animation_GetLastFrame(&object_tl_Anim_0008B4);
+
+ Animation_Change(&this->skelAnime1, &object_tl_Anim_0008B4, 1.0f, 0.0f, sp36, 2, -3.0f);
+ func_800BCB70(&this->actor, 0x4000, 255, 0, sp36);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_DAMAGE);
+ this->collider.base.acFlags &= ~AC_ON;
+ this->actionFunc = func_80AD810C;
+}
+
+void func_80AD810C(EnKame* this, GlobalContext* globalCtx) {
+ if (SkelAnime_Update(&this->skelAnime1)) {
+ func_80AD7DA4(this);
+ }
+}
+
+void func_80AD8148(EnKame* this, GlobalContext* globalCtx) {
+ Animation_PlayLoop(&this->skelAnime1, &object_tl_Anim_000AF4);
+ func_800BCB70(&this->actor, 0x4000, 255, 0, 20);
+ this->collider.base.acFlags &= ~AC_ON;
+ this->collider.base.atFlags &= ~AT_ON;
+ this->collider.base.atFlags &= ~(AC_HARD | AC_HIT);
+ this->actor.velocity.y = 15.0f;
+ this->actor.speedXZ = 1.5f;
+ if (globalCtx != NULL) {
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ if (this->actor.draw == func_80AD8D64) {
+ this->actor.draw = EnKame_Draw;
+ } else {
+ func_800BE504(&this->actor, &this->collider);
+ }
+ }
+ this->actor.bgCheckFlags &= ~0x1;
+ this->actor.flags &= ~0x1;
+ this->actor.flags |= 0x10;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_DEAD);
+ this->unk_29E = 0;
+ this->actionFunc = func_80AD825C;
+}
+
+void func_80AD825C(EnKame* this, GlobalContext* globalCtx) {
+ SkelAnime_Update(&this->skelAnime1);
+ if ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_HIPLOOP_LAND);
+ func_80AD8364(this);
+ } else {
+ if (this->unk_29E == 1) {
+ this->actor.colorFilterTimer = 100;
+ } else if (this->actor.colorFilterTimer == 0) {
+ func_800BCB70(&this->actor, 0xC000, 255, 0, 100);
+ }
+ this->actor.shape.rot.x += Rand_S16Offset(0x700, 0x1400);
+ this->actor.shape.rot.y += (s16)Rand_ZeroFloat(5120.0f);
+ this->actor.shape.rot.z += Rand_S16Offset(0x700, 0x1400);
+ }
+}
+
+void func_80AD8364(EnKame* this) {
+ this->unk_29E = 20;
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = func_80AD8388;
+}
+
+void func_80AD8388(EnKame* this, GlobalContext* globalCtx) {
+ Vec3f sp34;
+
+ SkelAnime_Update(&this->skelAnime1);
+ this->actor.colorFilterTimer = 100;
+ if (this->unk_29E > 0) {
+ this->unk_29E--;
+ if (this->unk_29E == 0) {
+ func_800F0590(globalCtx, &this->actor.world.pos, 21, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG);
+ }
+ } else {
+ this->actor.scale.x -= 0.001f;
+ if (this->actor.scale.x <= 0.0f) {
+ Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60);
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ this->actor.scale.y = this->actor.scale.x;
+ this->actor.scale.z = this->actor.scale.x;
+ }
+ sp34.x = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.x;
+ sp34.y = this->actor.world.pos.y + 15.0f;
+ sp34.z = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.z;
+ func_800B3030(globalCtx, &sp34, &gZeroVec3f, &gZeroVec3f, 100, 0, 2);
+ }
+}
+
+void func_80AD84C0(EnKame* this, GlobalContext* globalCtx) {
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->collider.base.acFlags &= ~AC_HIT;
+
+ func_800BE258(&this->actor, &this->collider.info);
+ if ((this->unk_29D == 10) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
+ return;
+ }
+
+ func_80AD7018(this, globalCtx);
+ if (this->actor.colChkInfo.damageEffect == 13) {
+ return;
+ }
+
+ if (this->actor.colChkInfo.damageEffect == 14) {
+ func_80AD8148(this, globalCtx);
+ } else if (this->actor.colChkInfo.damageEffect == 15) {
+ if (this->collider.base.acFlags & AC_HARD) {
+ func_80AD7C54(this);
+ } else if (!Actor_ApplyDamage(&this->actor)) {
+ func_80AD8148(this, globalCtx);
+ } else {
+ func_80AD8060(this);
+ }
+ } else if ((this->actionFunc == func_80AD70EC) || (this->actionFunc == func_80AD7254)) {
+ func_80AD73A8(this);
+ this->unk_29E = 21;
+ } else if (!(this->collider.base.acFlags & AC_HARD)) {
+ if (this->actor.colChkInfo.damageEffect == 5) {
+ this->unk_2A2 = 40;
+ func_800BCB70(&this->actor, 0, 255, 0, 40);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ this->unk_2B4 = 0.6f;
+ this->unk_2B0 = 2.0f;
+ this->unk_29D = 30;
+ func_80AD7FA4(this);
+ } else if (this->actor.colChkInfo.damageEffect == 1) {
+ this->unk_2A2 = 40;
+ func_800BCB70(&this->actor, 0, 255, 0, 40);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ func_80AD7FA4(this);
+ } else if (this->actor.colChkInfo.damageEffect == 3) {
+ func_80AD6F9C(this);
+ if (!Actor_ApplyDamage(&this->actor)) {
+ this->unk_2A2 = 3;
+ this->collider.base.acFlags &= ~AC_ON;
+ }
+ func_80AD7FA4(this);
+ } else {
+ if (this->actor.colChkInfo.damageEffect == 2) {
+ this->unk_2B4 = 0.6f;
+ this->unk_2B0 = 4.0f;
+ this->unk_29D = 0;
+ } else if (this->actor.colChkInfo.damageEffect == 4) {
+ this->unk_2B4 = 0.6f;
+ this->unk_2B0 = 4.0f;
+ this->unk_29D = 20;
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG,
+ this->collider.info.bumper.hitPos.x, this->collider.info.bumper.hitPos.y,
+ this->collider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS);
+ }
+
+ if (!Actor_ApplyDamage(&this->actor)) {
+ func_80AD8148(this, globalCtx);
+ } else {
+ func_80AD8060(this);
+ }
+ }
+ }
+ }
+
+ if ((globalCtx->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < 40000.0f) &&
+ (this->collider.base.acFlags & AC_ON)) {
+ func_80AD7018(this, globalCtx);
+ func_80AD7C54(this);
+ }
+}
+
+void EnKame_Update(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnKame* this = THIS;
+
+ func_80AD6F34(this);
+
+ if (this->unk_2A0 != 0) {
+ this->unk_2A0--;
+ }
+
+ func_80AD84C0(this, globalCtx);
+
+ if ((this->collider.base.atFlags & AT_HIT) && (this->collider.base.atFlags & AT_BOUNCED)) {
+ this->collider.base.atFlags &= ~(AT_BOUNCED | AT_HIT);
+ func_80AD76CC(this);
+ if (Actor_XZDistanceToPoint(&this->actor, &this->unk_2BC) < 50.0f) {
+ this->collider.base.atFlags &= ~AT_ON;
+ }
+ this->unk_2A6 = 0x3B00;
+ func_80AD7568(this);
+ }
+
+ this->actionFunc(this, globalCtx);
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 60.0f, 40.0f, 0x1F);
+
+ if (this->actor.shape.shadowDraw != NULL) {
+ Actor_SetHeight(&this->actor, 25.0f);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ }
+
+ if (this->collider.base.atFlags & AT_ON) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+
+ if (this->collider.base.acFlags & AC_ON) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+
+ if (this->unk_2B0 > 0.0f) {
+ if (this->unk_29D != 10) {
+ Math_StepToF(&this->unk_2B0, 0.0f, 0.05f);
+ this->unk_2B4 = (this->unk_2B0 + 1.0f) * 0.3f;
+ if (this->unk_2B4 > 0.6f) {
+ this->unk_2B4 = 0.6f;
+ } else {
+ this->unk_2B4 = this->unk_2B4;
+ }
+ } else if (!Math_StepToF(&this->unk_2B8, 0.6f, 0.015000001f)) {
+ func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+ }
+}
+
+s32 func_80AD8A48(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnKame* this = THIS;
+
+ if ((this->actionFunc == func_80AD7424) || (this->actionFunc == func_80AD7B90)) {
+ if (limbIndex == 2) {
+ Matrix_Scale(this->unk_2A8, this->unk_2AC, this->unk_2A8, MTXMODE_APPLY);
+ } else if ((limbIndex == 11) || (limbIndex == 9) || (limbIndex == 7) || (limbIndex == 5)) {
+ Matrix_Scale(this->unk_2A8, this->unk_2AC, this->unk_2AC, MTXMODE_APPLY);
+ }
+ }
+ return false;
+}
+
+void func_80AD8AF8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f D_80AD8E68[] = {
+ { 1500.0f, 0.0f, -2000.0f }, { 1500.0f, 0.0f, 2000.0f }, { 1500.0f, 2000.0f, 0.0f },
+ { 1500.0f, -2000.0f, 0.0f }, { 2500.0f, 0.0f, 0.0f },
+ };
+ static s8 D_80AD8EA4[] = { -1, -1, -1, 0, -1, -1, 1, -1, 2, -1, 3, -1, 4 };
+ EnKame* this = THIS;
+
+ if (D_80AD8EA4[limbIndex] != -1) {
+ Matrix_GetStateTranslation(&this->unk_2C8[D_80AD8EA4[limbIndex]]);
+ }
+
+ if (limbIndex == 1) {
+ s32 i;
+ Vec3f* ptr;
+ Vec3f* ptr2;
+
+ if (this->actor.shape.shadowDraw == NULL) {
+ Matrix_GetStateTranslation(&this->actor.world.pos);
+ }
+
+ ptr2 = D_80AD8E68;
+ ptr = &this->unk_2C8[5];
+ for (i = 0; i < ARRAY_COUNT(D_80AD8E68); i++) {
+ Matrix_MultiplyVector3fByState(ptr2, ptr);
+ ptr2++;
+ ptr++;
+ }
+ }
+}
+
+void EnKame_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnKame* this = THIS;
+ Vec3f sp40;
+
+ if (this->actor.shape.shadowDraw == 0) {
+ Math_Vec3f_Copy(&sp40, &this->actor.world.pos);
+ }
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, D_80AD8E34[this->unk_29C]);
+
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime1.skeleton, this->skelAnime1.jointTable,
+ this->skelAnime1.dListCount, func_80AD8A48, func_80AD8AF8, &this->actor);
+ func_800BE680(globalCtx, &this->actor, this->unk_2C8, 10, this->unk_2B4, this->unk_2B8, this->unk_2B0,
+ this->unk_29D);
+
+ if (this->actor.shape.shadowDraw == NULL) {
+ func_800B3FC0(&this->actor, NULL, globalCtx);
+ Actor_SetHeight(&this->actor, 25.0f);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ Math_Vec3f_Copy(&this->actor.world.pos, &sp40);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+s32 Enkame_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnKame* this = THIS;
+
+ if (limbIndex == 1) {
+ pos->y -= 700.0f;
+ }
+
+ if ((this->unk_2AC != 1.0f) && (limbIndex == 3)) {
+ Matrix_Scale(1.0f, this->unk_2AC, this->unk_2AC, MTXMODE_APPLY);
+ }
+ return false;
+}
+
+void func_80AD8D64(Actor* thisx, GlobalContext* globalCtx) {
+ EnKame* this = THIS;
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime2.skeleton, this->skelAnime2.jointTable,
+ this->skelAnime2.dListCount, Enkame_OverrideLimbDraw, NULL, &this->actor);
+}
diff --git a/src/overlays/actors/ovl_En_Kame/z_en_kame.h b/src/overlays/actors/ovl_En_Kame/z_en_kame.h
index efdff3812..115bf137f 100644
--- a/src/overlays/actors/ovl_En_Kame/z_en_kame.h
+++ b/src/overlays/actors/ovl_En_Kame/z_en_kame.h
@@ -9,9 +9,28 @@ typedef void (*EnKameActionFunc)(struct EnKame*, GlobalContext*);
typedef struct EnKame {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x154];
+ /* 0x0144 */ SkelAnime skelAnime1;
+ /* 0x0188 */ Vec3s jointTable1[13];
+ /* 0x01D6 */ Vec3s morphTable1[13];
+ /* 0x0224 */ SkelAnime skelAnime2;
+ /* 0x0268 */ Vec3s jointTable2[4];
+ /* 0x0280 */ Vec3s morphTable2[4];
/* 0x0298 */ EnKameActionFunc actionFunc;
- /* 0x029C */ char unk_29C[0xF0];
+ /* 0x029C */ u8 unk_29C;
+ /* 0x029D */ u8 unk_29D;
+ /* 0x029E */ s16 unk_29E;
+ /* 0x02A0 */ s16 unk_2A0;
+ /* 0x02A2 */ s16 unk_2A2;
+ /* 0x02A4 */ s16 unk_2A4;
+ /* 0x02A6 */ s16 unk_2A6;
+ /* 0x02A8 */ f32 unk_2A8;
+ /* 0x02AC */ f32 unk_2AC;
+ /* 0x02B0 */ f32 unk_2B0;
+ /* 0x02B4 */ f32 unk_2B4;
+ /* 0x02B8 */ f32 unk_2B8;
+ /* 0x02BC */ Vec3f unk_2BC;
+ /* 0x02C8 */ Vec3f unk_2C8[10];
+ /* 0x0340 */ ColliderCylinder collider;
} EnKame; // size = 0x38C
extern const ActorInit En_Kame_InitVars;
diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h
index 1ac436704..40eeb1060 100644
--- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h
+++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h
@@ -10,6 +10,8 @@ typedef struct EnKanban {
/* 0x144 */ char unk_144[0xAC];
} EnKanban; // size = 0x1F0
+#define ENKANBAN_FISHING 0x300
+
extern const ActorInit En_Kanban_InitVars;
#endif // Z_EN_KANBAN_H
diff --git a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
index 1b4d04e42..df691b0df 100644
--- a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
+++ b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
@@ -15,18 +15,42 @@ void EnKusa2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnKusa2_Update(Actor* thisx, GlobalContext* globalCtx);
void EnKusa2_Draw(Actor* thisx, GlobalContext* globalCtx);
+void func_80A5C70C(EnKusa2UnkBssSubStruct* arg0);
+void func_80A5CF44(EnKusa2* this);
+void func_80A5D5E0(EnKusa2* this);
void func_80A5D5F4(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5D618(EnKusa2* this);
void func_80A5D62C(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5D6B0(EnKusa2* this);
void func_80A5D6C4(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5D754(EnKusa2* this);
void func_80A5D794(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5D7A4(EnKusa2* this);
void func_80A5D7C4(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5D964(EnKusa2* this);
void func_80A5D9C8(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5DC70(EnKusa2* this);
void func_80A5DC98(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5DE18(EnKusa2* this);
void func_80A5DEB4(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5E1D8(EnKusa2* this);
void func_80A5E210(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5E418(EnKusa2* this);
void func_80A5E4BC(EnKusa2* this, GlobalContext* globalCtx);
+void func_80A5E604(Actor* thisx, GlobalContext* globalCtx);
+void func_80A5E6F0(Actor* thisx, GlobalContext* globalCtx);
+void func_80A5E9B4(Actor* thisx, GlobalContext* globalCtx);
+void func_80A5EA48(Actor* thisx, GlobalContext* globalCtx);
+
+static EnKusa2UnkBssStruct D_80A5F1C0;
+static u32 D_80A60900;
+static MtxF D_80A60908[8];
+static s16 D_80A60B08;
+static s16 D_80A60B0A;
+static s16 D_80A60B0C;
+static s16 D_80A60B0E;
+static s16 D_80A60B10;
-#if 0
const ActorInit En_Kusa2_InitVars = {
ACTOR_EN_KUSA2,
ACTORCAT_PROP,
@@ -39,146 +63,1320 @@ const ActorInit En_Kusa2_InitVars = {
(ActorFunc)EnKusa2_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A5EAC0 = {
- { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x0580C71C, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x0580C71C, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 6, 44, 0, { 0, 0, 0 } },
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80A5EB50[] = {
- ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE),
- ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE),
- ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
+static u8 D_80A5EAEC = 1;
+static s16 D_80A5EAF0 = 0;
+static Vec3s D_80A5EAF4 = { 0, 0, 0 };
+static Vec3s D_80A5EAFC = { 0, 0, 0 };
+static Vec3s D_80A5EB04 = { 0, 0, 0 };
+
+void func_80A5B160(EnKusa2* this, GlobalContext* globalCtx) {
+ s32 i;
+ s16 temp_s1;
+ EnKusa2** ptr;
+ EnKusa2* actor;
+
+ if (this->unk_194[0] == NULL) {
+ ptr = this->unk_194;
+ actor = (EnKusa2*)Actor_SpawnAsChildAndCutscene(
+ &globalCtx->actorCtx, globalCtx, ACTOR_EN_KUSA2, this->actor.world.pos.x, this->actor.world.pos.y,
+ this->actor.world.pos.z, 0, (u32)Rand_Next() >> 0x10, 0, 1, this->actor.cutscene, this->actor.unk20, NULL);
+ *ptr = actor;
+
+ if (*ptr != NULL) {
+ (*ptr)->actor.room = this->actor.room;
+ (*ptr)->unk_1C0 = this;
+ }
+ }
+
+ for (i = 1; i < ARRAY_COUNT(this->unk_194); i++) {
+ temp_s1 = (i << 0xD) - 0x2000;
+ if (this->unk_194[i] == NULL) {
+ ptr = &this->unk_194[i];
+ actor = (EnKusa2*)Actor_SpawnAsChildAndCutscene(
+ &globalCtx->actorCtx, globalCtx, ACTOR_EN_KUSA2, (Math_SinS(temp_s1) * 80.0f) + this->actor.world.pos.x,
+ this->actor.world.pos.y, (Math_CosS(temp_s1) * 80.0f) + this->actor.world.pos.z, 0,
+ (u32)Rand_Next() >> 0x10, 0, 1, this->actor.cutscene, this->actor.unk20, NULL);
+ *ptr = actor;
+ if (*ptr != NULL) {
+ (*ptr)->actor.room = this->actor.room;
+ (*ptr)->unk_1C0 = this;
+ }
+ }
+ }
+}
+
+void func_80A5B334(EnKusa2* this, GlobalContext* globalCtx) {
+ s32 i;
+ EnKusa2** ptr;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) {
+ ptr = &this->unk_194[i];
+
+ if (*ptr != NULL) {
+ if (!Actor_HasParent(&(*ptr)->actor, globalCtx)) {
+ Actor_MarkForDeath(&(*ptr)->actor);
+ }
+ *ptr = NULL;
+ }
+ }
+}
+
+void func_80A5B3BC(EnKusa2* this) {
+ s32 i;
+ EnKusa2** ptr;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) {
+ ptr = &this->unk_194[i];
+ if ((*ptr != NULL) && ((*ptr)->actor.update == NULL)) {
+ *ptr = NULL;
+ }
+ }
+}
+
+void func_80A5B490(EnKusa2* this, GlobalContext* globalCtx) {
+ Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_KITAN, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0,
+ ENKUSA2_GET_7F00(&this->actor) << 9, this->actor.cutscene, this->actor.unk20, NULL);
+}
+
+void func_80A5B508(void) {
+ s32 i;
+ s32 pad;
+ f32 spB4;
+ f32* ptr;
+ f32 spAC;
+ f32 spA8;
+ f32 tempf1;
+ f32 tempf2;
+ f32 tempf3;
+ f32 tempf4;
+ f32 tempf5;
+ f32 sp74[8];
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f24;
+ f32 temp_f26;
+ f32 temp_f28;
+ f32 temp_f2;
+ f32 temp_f30;
+
+ D_80A60B08 += 70;
+ D_80A60B0A += 300;
+ D_80A60B0C += 700;
+ D_80A60B0E += 1300;
+ D_80A60B10 += 8900;
+ temp_f28 = Math_SinS(D_80A60B08);
+ spB4 = Math_SinS(D_80A60B0A);
+ temp_f30 = Math_SinS(D_80A60B0C);
+ spAC = Math_SinS(D_80A60B0E) * 1.2f;
+ spA8 = Math_SinS(D_80A60B10) * 1.5f;
+ temp_f26 = Math_CosS(D_80A60B08);
+ temp_f20 = Math_CosS(D_80A60B0A);
+ temp_f22 = Math_CosS(D_80A60B0C);
+ temp_f24 = Math_CosS(D_80A60B0E) * 1.3f;
+ temp_f2 = Math_CosS(D_80A60B10) * 1.7f;
+
+ sp74[0] = (temp_f28 - temp_f20) * temp_f30 * temp_f26 * temp_f28;
+ sp74[1] = (spB4 - temp_f22) * spAC * temp_f20 * temp_f28;
+ sp74[2] = (temp_f30 - temp_f24) * temp_f22 * temp_f28 * temp_f26;
+ sp74[3] = (spAC - temp_f20) * temp_f24 * spB4 * temp_f26;
+ sp74[4] = (temp_f28 - temp_f22) * temp_f28 * spB4 * spA8;
+ sp74[5] = (spB4 - temp_f24) * temp_f30 * spAC * spA8;
+ sp74[6] = (temp_f30 - temp_f26) * temp_f26 * temp_f20 * temp_f2;
+ sp74[7] = (spAC - temp_f20) * temp_f22 * temp_f24 * temp_f2;
+
+ for (i = 0; i < ARRAY_COUNT(D_80A60908); i++) {
+ ptr = (f32*)&D_80A60908[i].mf[0];
+
+ tempf1 = sp74[(i + 0) & 7];
+ tempf2 = sp74[(i + 1) & 7];
+ tempf3 = sp74[(i + 2) & 7];
+ tempf4 = sp74[(i + 3) & 7];
+ tempf5 = sp74[(i + 4) & 7];
+
+ ptr[0] = sp74[1] * 0.2f;
+ ptr[1] = tempf1;
+ ptr[2] = tempf2;
+ ptr[3] = 0.0f;
+
+ ptr[4] = tempf3;
+ ptr[5] = sp74[0];
+ ptr[6] = tempf3;
+ ptr[7] = 0.0f;
+
+ ptr[8] = tempf4;
+ ptr[9] = tempf5;
+ ptr[10] = sp74[3] * 0.2f;
+ ptr[11] = 0.0f;
+
+ ptr[12] = 0.0f;
+ ptr[13] = 0.0f;
+ ptr[14] = 0.0f;
+ ptr[15] = 0.0f;
+ }
+}
+
+void func_80A5B954(MtxF* matrix, f32 arg1) {
+ s32 i;
+ MtxF* temp = Matrix_GetCurrentState();
+ f32* tmp = (f32*)&temp->mf[0];
+ f32* tmp2 = (f32*)&matrix->mf[0];
+
+ for (i = 0; i < 16; i++) {
+ *tmp++ += *tmp2++ * arg1;
+ }
+}
+
+s32 func_80A5BA58(EnKusa2* this, GlobalContext* globalCtx) {
+ Vec3f sp24;
+ s32 sp20;
+
+ sp24.x = this->actor.world.pos.x;
+ sp24.y = this->actor.world.pos.y + 30.0f;
+ sp24.z = this->actor.world.pos.z;
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp20, &this->actor, &sp24);
+ if (this->actor.floorHeight > BGCHECK_Y_MIN) {
+ this->actor.floorBgId = sp20;
+ this->actor.world.pos.y = this->actor.floorHeight;
+ Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
+ return true;
+ }
+ return false;
+}
+
+void func_80A5BAFC(EnKusa2* this, GlobalContext* globalCtx) {
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 35.0f, 0.0f, 0x45);
+}
+
+void func_80A5BB40(EnKusa2* this, GlobalContext* globalCtx, s32 arg2) {
+ static Vec3f D_80A5EB0C = { 0.0f, 0.3f, 0.0f };
+ static Vec3f D_80A5EB18 = { 0.0f, 0.0f, 0.0f };
+ s32 pad;
+ s32 i;
+ Vec3f sp84;
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f24;
+ s16 temp_s0;
+
+ if (this->actor.flags & 0x40) {
+ for (i = 0; i <= arg2; i++) {
+ temp_s0 = Rand_S16Offset(-16000, 32000) + this->actor.world.rot.y;
+ temp_f20 = Math_SinS(temp_s0);
+ temp_f22 = Math_CosS(temp_s0);
+ temp_f24 = Rand_ZeroOne() * -12.0f;
+
+ sp84.x = (temp_f20 * temp_f24) + this->actor.world.pos.x;
+ sp84.y = (Rand_ZeroOne() * 8.0f) + 2.0f + this->actor.world.pos.y;
+ sp84.z = (temp_f22 * temp_f24) + this->actor.world.pos.z;
+
+ D_80A5EB18.x = temp_f20 * -0.9f;
+ D_80A5EB18.z = temp_f22 * -0.9f;
+
+ D_80A5EB0C.x = D_80A5EB18.x * -0.09f;
+ D_80A5EB0C.z = D_80A5EB18.z * -0.09f;
+
+ func_800B1210(globalCtx, &sp84, &D_80A5EB18, &D_80A5EB0C, 10, 50);
+ }
+ }
+}
+
+void func_80A5BD14(EnKusa2* this, GlobalContext* globalCtx, s32 arg2) {
+ static s32 D_80A5EB24[] = {
+ ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN,
+ ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_RED,
+ };
+ EnKusa2* kusa2 = this->unk_1C0;
+
+ if (kusa2 != NULL) {
+ if (kusa2->unk_1BC > 8) {
+ kusa2->unk_1BC = 8;
+ }
+ Item_DropCollectible(globalCtx, &this->actor.world.pos, D_80A5EB24[kusa2->unk_1BC]);
+ kusa2->unk_1BC += arg2;
+ }
+}
+
+void func_80A5BD94(EnKusa2* this) {
+ if (this->unk_1C0 != NULL) {
+ this->unk_1C0->unk_1BE = 1;
+ }
+}
+
+void func_80A5BDB0(EnKusa2* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+ s32 i;
+ Vec3f sp50;
+ s16 phi_s0;
+
+ sp50.y = this->actor.world.pos.y + this->actor.depthInWater;
+
+ for (phi_s0 = 0, i = 0; i < 4; i++, phi_s0 += 0x4000) {
+ sp50.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.x;
+ sp50.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &sp50, NULL, NULL, 0, 190);
+ }
+
+ sp50.x = this->actor.world.pos.x;
+ sp50.z = this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &sp50, NULL, NULL, 0, 280);
+ EffectSsGRipple_Spawn(globalCtx, &sp50, 300, 700, 0);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
+}
+
+void func_80A5BF38(EnKusa2* this, s32 arg1) {
+ this->actor.shape.shadowAlpha += (u8)arg1;
+ if (this->actor.shape.shadowAlpha > 60) {
+ this->actor.shape.shadowAlpha = 60;
+ }
+}
+
+void func_80A5BF60(EnKusa2* this, s32 arg1) {
+ s32 alpha = this->actor.shape.shadowAlpha;
+
+ alpha -= arg1;
+ if (alpha > 0) {
+ this->actor.shape.shadowAlpha = alpha;
+ } else {
+ this->actor.shape.shadowAlpha = 0;
+ }
+}
+
+void func_80A5BF84(EnKusa2* this, GlobalContext* globalCtx) {
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+s32 func_80A5BFD8(EnKusa2* this, GlobalContext* globalCtx) {
+ if (this->collider.base.acFlags & 2) {
+ s32 pad;
+
+ func_80A5CF44(this);
+ func_80A5BD14(this, globalCtx, (this->collider.info.acHitInfo->toucher.dmgFlags & 0x1000000) ? 1 : 0);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
+ func_80A5BD94(this);
+ Actor_MarkForDeath(&this->actor);
+ return true;
+ }
+ return false;
+}
+
+EnKusa2UnkBssSubStruct* func_80A5C074(EnKusa2UnkBssStruct* arg0) {
+ s32 i;
+ EnKusa2UnkBssSubStruct* phi_v1 = &arg0->unk_0000[0];
+
+ for (i = 1; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) {
+ if (!(phi_v1->unk_26 <= arg0->unk_0000[i].unk_26)) {
+ phi_v1 = &arg0->unk_0000[i];
+ if (phi_v1->unk_26 <= 0) {
+ break;
+ }
+ }
+ }
+
+ return phi_v1;
+}
+
+EnKusa2UnkBssSubStruct2* func_80A5C0B8(EnKusa2UnkBssStruct* arg0) {
+ s32 i;
+ EnKusa2UnkBssSubStruct2* phi_v1 = &arg0->unk_0480[0];
+
+ for (i = 1; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) {
+ if (!(phi_v1->unk_2C <= arg0->unk_0480[i].unk_2C)) {
+ phi_v1 = &arg0->unk_0480[i];
+ if (1) {}
+ if (phi_v1->unk_2C <= 0) {
+ break;
+ }
+ }
+ }
+
+ return phi_v1;
+}
+
+EnKusa2UnkBssSubStruct* func_80A5C104(EnKusa2UnkBssStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, s16 arg4, s16 arg5) {
+ static s32 D_80A5EB48 = 0;
+ EnKusa2UnkBssSubStruct* ptr = func_80A5C074(arg0);
+ f32 sp20;
+ f32 temp_f6;
+
+ Math_Vec3f_Copy(&ptr->unk_00, arg1);
+ Math_Vec3f_Copy(&ptr->unk_0C, &gZeroVec3f);
+
+ ptr->unk_18 = arg2;
+ ptr->unk_1C = arg3;
+ ptr->unk_20 = arg4;
+ ptr->unk_22 = arg5;
+
+ D_80A5EB48++;
+ if (D_80A5EB48 >= 3) {
+ D_80A5EB48 = 0;
+ ptr->unk_26 = Rand_S16Offset(40, 40);
+ } else {
+ ptr->unk_26 = Rand_S16Offset(30, 20);
+ }
+
+ ptr->unk_24 = ptr->unk_26 - 20;
+ sp20 = 1.0f / ptr->unk_24;
+ ptr->unk_28 = func_80A5C70C;
+ ptr->unk_2C = 0.0f;
+ ptr->unk_30 = 0.0f;
+ temp_f6 = Rand_ZeroOne() * 60.0f;
+ ptr->unk_34 = (temp_f6 + 20.0f) * 0.05f;
+ ptr->unk_38 = (temp_f6 + 20.0f) * sp20;
+ ptr->unk_3C = 40.0f;
+ ptr->unk_40 = -1.5f;
+ ptr->unk_44 = -50.0f * sp20;
+ ptr->unk_48 = 140.0f;
+ ptr->unk_4C = SQ(140.0f);
+ ptr->unk_50 = 819.2f;
+ ptr->unk_54 = 327.68f;
+ ptr->unk_58 = 2.5f;
+ ptr->unk_5C = 0.05f;
+ ptr->unk_60 = 3.5f * sp20;
+ ptr->unk_64 = 0.35f;
+ ptr->unk_68 = 0.0875f;
+ ptr->unk_6C = 160.0f;
+ ptr->unk_70 = SQ(160.0f);
+ ptr->unk_74 = 204.8f;
+ ptr->unk_78 = 100.0f;
+ ptr->unk_7C = 327.68f;
+ return ptr;
+}
+
+EnKusa2UnkBssSubStruct2* func_80A5C2FC(EnKusa2UnkBssStruct* arg0, f32 arg1, Vec3f* arg2, Vec3f* arg3, Vec3s* arg4,
+ Vec3s* arg5) {
+ Vec3f* temp_a0;
+ EnKusa2UnkBssSubStruct2* temp_s0;
+ f32 phi_f8;
+
+ temp_s0 = func_80A5C0B8(arg0);
+ temp_s0->unk_00 = arg1;
+ Math_Vec3f_Copy(&temp_s0->unk_04, arg2);
+ Math_Vec3f_Copy(&temp_s0->unk_10, arg3);
+
+ if (arg1 >= 0.35f) {
+ temp_s0->unk_1C = (6.0f / 7);
+ } else if (arg1 <= 0.1f) {
+ temp_s0->unk_1C = 1.0f;
+ } else {
+ temp_s0->unk_1C = (0.02f / arg1) + 0.8f;
+ }
+
+ temp_s0->unk_20 = *arg4;
+ temp_s0->unk_26 = *arg5;
+ temp_s0->unk_2C = Rand_S16Offset(65, 30);
+
+ return temp_s0;
+}
+
+void func_80A5C410(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct2* arg1, Vec3f* arg2) {
+ s32 i;
+ Vec3f sp98;
+ EnKusa2UnkBssSubStruct* s;
+ s32 pad;
+
+ Math_Vec3f_Copy(arg2, &gZeroVec3f);
+
+ for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) {
+ s = &arg0->unk_0000[i];
+
+ if (s->unk_26 > 0) {
+ f32 temp_f0;
+ s32 phi_v0 = true;
+ s32 phi_s2 = true;
+
+ Math_Vec3f_Diff(&arg1->unk_04, &s->unk_00, &sp98);
+ temp_f0 = Math3D_LengthSquared(&sp98);
+
+ phi_v0 = false;
+ if (temp_f0 <= s->unk_4C) {
+ phi_v0 = true;
+ }
+
+ phi_s2 = false;
+ if (temp_f0 <= s->unk_70) {
+ phi_s2 = true;
+ }
+
+ if (phi_v0 || phi_s2) {
+ f32 phi_f22;
+
+ if (temp_f0 < SQ(0.01f)) {
+ phi_f22 = 0.0f;
+ } else {
+ phi_f22 = sqrtf(temp_f0);
+ }
+
+ if (phi_v0) {
+ f32 phi_f2;
+ f32 phi_f20;
+
+ if (phi_f22 > 1.0f) {
+ phi_f20 = 1.0f / phi_f22;
+ } else {
+ phi_f20 = 1.0f;
+ }
+
+ if (phi_f22 < s->unk_3C) {
+ phi_f2 = Math_SinS(s->unk_50 * phi_f22) * -s->unk_2C;
+ } else {
+ phi_f2 = (Math_CosS(s->unk_54 * (phi_f22 - s->unk_3C)) + 1.0f) * s->unk_30;
+ }
+
+ arg2->x += sp98.x * -(phi_f20 * phi_f2);
+ arg2->z += sp98.z * -(phi_f20 * phi_f2);
+
+ if (phi_s2) {
+ arg2->x += phi_f20 * sp98.z * s->unk_58;
+ arg2->z -= phi_f20 * sp98.x * s->unk_58;
+ }
+ }
+
+ if (phi_s2 && (fabsf(sp98.y) < s->unk_78)) {
+ arg2->y +=
+ s->unk_68 * (Math_CosS(s->unk_74 * phi_f22) + 1.0f) * (Math_CosS(s->unk_7C * sp98.y) + 1.0f);
+ }
+ }
+ }
+ }
+
+ arg2->y -= 0.5f;
+}
+
+void func_80A5C70C(EnKusa2UnkBssSubStruct* arg0) {
+}
+
+void func_80A5C718(EnKusa2UnkBssSubStruct* arg0) {
+ Math_ScaledStepToS(&arg0->unk_20, arg0->unk_22, 1200);
+
+ if ((arg0->unk_1C > 0.0f) && (Rand_ZeroOne() < 0.05f)) {
+ arg0->unk_1C = -arg0->unk_1C;
+ }
+
+ arg0->unk_0C.x = Math_SinS(arg0->unk_22) * arg0->unk_18;
+ arg0->unk_0C.y += arg0->unk_1C;
+ arg0->unk_0C.z = Math_CosS(arg0->unk_22) * arg0->unk_18;
+
+ arg0->unk_00.x += arg0->unk_0C.x;
+ arg0->unk_00.y += arg0->unk_0C.y;
+ arg0->unk_00.z += arg0->unk_0C.z;
+}
+
+void func_80A5C7F0(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct* arg1) {
+ if (arg1->unk_26 > 0) {
+ arg1->unk_26--;
+ arg1->unk_28(arg1);
+ if (arg1->unk_26 >= arg1->unk_24) {
+ arg1->unk_2C += arg1->unk_34;
+ arg1->unk_3C += arg1->unk_40;
+ arg1->unk_58 += arg1->unk_5C;
+ } else {
+ arg1->unk_2C -= arg1->unk_38;
+ if (arg1->unk_2C < 0.0f) {
+ arg1->unk_2C = 0.0f;
+ }
+ arg1->unk_3C -= arg1->unk_44;
+ arg1->unk_58 -= arg1->unk_60;
+ if (arg1->unk_58 < 0.0f) {
+ arg1->unk_58 = 0.0f;
+ }
+ }
+ arg1->unk_30 = arg1->unk_2C * 0.5f;
+ arg1->unk_50 = 0x8000 / arg1->unk_3C;
+ arg1->unk_54 = 0x8000 / (arg1->unk_48 - arg1->unk_3C);
+ }
+}
+
+void func_80A5C918(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct2* arg1) {
+ Vec3f sp4C;
+ s32 pad;
+ s32 pad2;
+ Vec3f sp38;
+ Vec3f sp2C;
+ f32 phi_f0;
+
+ if (arg1->unk_2C > 0) {
+ arg1->unk_2C--;
+
+ func_80A5C410(arg0, arg1, &sp4C);
+
+ arg1->unk_10.x += sp4C.x;
+ arg1->unk_10.y += sp4C.y;
+ arg1->unk_10.z += sp4C.z;
+
+ sp38.x = arg1->unk_10.x * (arg1->unk_1C * 0.06f);
+ sp38.x = arg1->unk_10.x * (arg1->unk_1C * 0.06f);
+ sp38.y = arg1->unk_10.y * (arg1->unk_1C * 0.06f);
+ sp38.z = arg1->unk_10.z * (arg1->unk_1C * 0.06f);
+
+ sp2C.x = SQ(arg1->unk_10.x) * (arg1->unk_1C * 0.004f);
+ sp2C.y = SQ(arg1->unk_10.y) * (arg1->unk_1C * 0.004f);
+ sp2C.z = SQ(arg1->unk_10.z) * (arg1->unk_1C * 0.004f);
+
+ if (arg1->unk_10.x > 0.0f) {
+ phi_f0 = sp2C.x;
+ } else {
+ phi_f0 = -sp2C.x;
+ }
+ arg1->unk_10.x -= sp38.x + phi_f0;
+
+ if (arg1->unk_10.y > 0.0f) {
+ phi_f0 = sp2C.y;
+ } else {
+ phi_f0 = -sp2C.y;
+ }
+ arg1->unk_10.y -= sp38.y + phi_f0;
+
+ if (arg1->unk_10.z > 0.0f) {
+ phi_f0 = sp2C.z;
+ } else {
+ phi_f0 = -sp2C.z;
+ }
+ arg1->unk_10.z -= sp38.z + phi_f0;
+
+ arg1->unk_04.x += arg1->unk_10.x;
+ arg1->unk_04.y += arg1->unk_10.y;
+ arg1->unk_04.z += arg1->unk_10.z;
+ arg1->unk_20.x += arg1->unk_26.x;
+ arg1->unk_20.y += arg1->unk_26.y;
+ arg1->unk_20.z += arg1->unk_26.z;
+ }
+}
+
+void func_80A5CAD4(EnKusa2UnkBssStruct* arg0) {
+ bzero(arg0, sizeof(EnKusa2UnkBssStruct));
+}
+
+void func_80A5CAF4(EnKusa2UnkBssStruct* arg0) {
+ s32 i;
+
+ for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) {
+ func_80A5C7F0(arg0, &arg0->unk_0000[i]);
+ }
+
+ for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) {
+ func_80A5C918(arg0, &arg0->unk_0480[i]);
+ }
+}
+
+void func_80A5CB74(EnKusa2* this) {
+ static s8 D_80A5EB4C = 0;
+ s32 pad;
+ Vec3f sp40;
+ s16 sp3E;
+ s16 sp3C;
+ f32 sp38;
+ s16 sp36;
+ f32 temp_f0;
+
+ sp40.x = this->actor.world.pos.x;
+ sp40.y = this->actor.world.pos.y + 20.0f;
+ sp40.z = this->actor.world.pos.z;
+ sp3E = Rand_S16Offset(-10000, 20000) + this->actor.world.rot.y;
+
+ if (this->unk_1C0 != NULL) {
+ sp36 = Actor_YawBetweenActors(&this->actor, &this->unk_1C0->actor);
+ sp3C = Rand_S16Offset(-4000, 8000) + sp36;
+ } else {
+ sp3C = 0;
+ }
+
+ D_80A5EB4C++;
+label:
+ D_80A5EB4C &= 0x7;
+
+ temp_f0 = Rand_ZeroOne();
+ if (D_80A5EB4C == 0) {
+ sp38 = temp_f0 * 0.70000005f;
+ } else {
+ sp38 = SQ(temp_f0) * 0.4f;
+ }
+ this->unk_1B8 = func_80A5C104(&D_80A5F1C0, &sp40, (Rand_ZeroOne() * 3.5f) + 4.0f, sp38, sp3E, sp3C);
+}
+
+void func_80A5CCD4(EnKusa2* this) {
+ if (this->unk_1B8 != NULL) {
+ EnKusa2UnkBssSubStruct* ptr = this->unk_1B8;
+
+ ptr->unk_00.x = this->actor.world.pos.x;
+ ptr->unk_00.y = this->actor.world.pos.y + 20.0f;
+ ptr->unk_00.z = this->actor.world.pos.z;
+ }
+}
+
+void func_80A5CD0C(EnKusa2* this) {
+ s32 i;
+ Vec3f spA8;
+ Vec3f sp9C;
+ Vec3s sp94;
+ Vec3s sp8C;
+ f32 temp_f20;
+ s16 temp_s0;
+ s32 pad;
+
+ for (i = 0; i < 2; i++) {
+ temp_s0 = (u32)Rand_Next() & 0xFFFF;
+ temp_f20 = Rand_ZeroOne() * 30.0f;
+
+ spA8.x = Math_SinS(temp_s0) * temp_f20;
+ spA8.y = Rand_ZeroOne() * 30.0f;
+ spA8.z = Math_CosS(temp_s0) * temp_f20;
+
+ sp9C.x = ((Rand_ZeroOne() * 4.0f) - 2.0f) + (spA8.x * 0.18f);
+ sp9C.y = (Rand_ZeroOne() * 8.0f) + 3.0f;
+ sp9C.z = ((Rand_ZeroOne() * 4.0f) - 2.0f) + (spA8.z * 0.18f);
+
+ spA8.x += this->actor.world.pos.x;
+ spA8.y += this->actor.world.pos.y;
+ spA8.z += this->actor.world.pos.z;
+
+ sp94.x = (u32)Rand_Next() & 0xFFFF;
+ sp94.y = (u32)Rand_Next() & 0xFFFF;
+ sp94.z = (u32)Rand_Next() & 0xFFFF;
+
+ sp8C.x = ((u32)Rand_Next() % 0x4000) - 0x1FFF;
+ sp8C.y = ((u32)Rand_Next() % 0x2000) - 0xFFF;
+ sp8C.z = ((u32)Rand_Next() % 0x4000) - 0x1FFF;
+
+ func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.4f) + 0.02f, &spA8, &sp9C, &sp94, &sp8C);
+ }
+}
+
+void func_80A5CF44(EnKusa2* this) {
+ s32 i;
+ Vec3f spA8;
+ Vec3f sp9C;
+ Vec3s sp94;
+ Vec3s sp8C;
+ f32 temp_f20;
+ s16 temp_s0;
+ s32 phi_s2;
+
+ for (i = 0, phi_s2 = 0; i < 8; i++, phi_s2 += 0x2000) {
+ temp_s0 = ((u32)Rand_Next() % 0x2000) + phi_s2;
+ temp_f20 = Rand_ZeroOne() * 30.0f;
+
+ spA8.x = Math_SinS(temp_s0) * temp_f20;
+ spA8.y = Rand_ZeroOne() * 30.0f;
+ spA8.z = Math_CosS(temp_s0) * temp_f20;
+
+ sp9C.x = ((Rand_ZeroOne() * 6.0f) - 3.0f) + (spA8.x * 0.19f);
+ sp9C.y = (Rand_ZeroOne() * 9.0f) + 3.0f;
+ sp9C.z = ((Rand_ZeroOne() * 6.0f) - 3.0f) + (spA8.z * 0.19f);
+
+ spA8.x += this->actor.world.pos.x;
+ spA8.y += this->actor.world.pos.y;
+ spA8.z += this->actor.world.pos.z;
+
+ sp94.x = Rand_Next() & 0xFFFF;
+ sp94.y = Rand_Next() & 0xFFFF;
+ sp94.z = Rand_Next() & 0xFFFF;
+
+ sp8C.x = ((u32)Rand_Next() % 0x4000) - 0x1FFF;
+ sp8C.y = ((u32)Rand_Next() % 0x2000) - 0xFFF;
+ sp8C.z = ((u32)Rand_Next() % 0x4000) - 0x1FFF;
+
+ func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.45f) + 0.04f, &spA8, &sp9C, &sp94, &sp8C);
+ }
+}
+
+void func_80A5D178(EnKusa2* this) {
+ s32 i;
+ Vec3f spB0;
+ Vec3f spA4;
+ Vec3s sp9C;
+ Vec3s sp94;
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f24;
+ s16 temp_s0;
+ s32 pad;
+
+ for (i = 0; i < 8; i++) {
+ temp_s0 = (u32)Rand_Next();
+ temp_f22 = Math_SinS(temp_s0);
+ temp_f20 = Math_CosS(temp_s0);
+ temp_f24 = (Rand_ZeroOne() * 40.0f) + 10.0f;
+
+ spB0.x = temp_f24 * temp_f22;
+ spB0.y = Rand_ZeroOne() * 30.0f;
+ spB0.z = temp_f24 * temp_f20;
+
+ spA4.x = ((Rand_ZeroOne() * 6.0f) - 3.0f) + ((temp_f20 * 6.0f) + (spB0.x * 0.1f));
+ spA4.y = (Rand_ZeroOne() * 3.0f) + 1.0f;
+ spA4.z = ((Rand_ZeroOne() * 6.0f) - 3.0f) + ((temp_f22 * -6.0f) + (spB0.z * 0.1f));
+
+ spB0.x += this->actor.world.pos.x;
+ spB0.y += this->actor.world.pos.y;
+ spB0.z += this->actor.world.pos.z;
+
+ sp9C.x = (u32)Rand_Next() & 0xFFFF;
+ sp9C.y = (u32)Rand_Next() & 0xFFFF;
+ sp9C.z = (u32)Rand_Next() & 0xFFFF;
+
+ sp94.x = Rand_S16Offset(-12000, 24000);
+ sp94.y = ((u32)Rand_Next() % 0x4000) - 0x1FFF;
+ sp94.z = Rand_S16Offset(-12000, 24000);
+ func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.38f) + 0.02f, &spB0, &spA4, &sp9C, &sp94);
+ }
+}
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE),
+ ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
};
-#endif
+void EnKusa2_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnKusa2* this = THIS;
-extern ColliderCylinderInit D_80A5EAC0;
-extern InitChainEntry D_80A5EB50[];
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ if (!ENKUSA2_GET_1(&this->actor)) {
+ this->actor.update = func_80A5E604;
+ this->actor.draw = NULL;
+ this->actor.flags |= 0x20;
+ func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 1);
+ this->unk_1BE = 0;
+ if (D_80A5EAEC != 0) {
+ D_80A5EAEC = 0;
+ D_80A60900 = globalCtx->gameplayFrames;
+ func_80A5CAD4(&D_80A5F1C0);
+ D_80A60B08 = (u32)Rand_Next() >> 0x10;
+ D_80A60B0A = (u32)Rand_Next() >> 0x10;
+ D_80A60B0C = (u32)Rand_Next() >> 0x10;
+ D_80A60B0E = (u32)Rand_Next() >> 0x10;
+ D_80A60B10 = (u32)Rand_Next() >> 0x10;
+ func_80A5B508();
+ }
+ func_80A5D5E0(this);
+ } else {
+ Collider_InitCylinder(globalCtx, &this->collider);
+ if (!func_80A5BA58(this, globalCtx)) {
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ this->unk_1CE = D_80A5EAF0 & 7;
+ D_80A5EAF0++;
+ this->actor.shape.shadowAlpha = 0;
+ this->unk_1CF = 255;
+ this->actor.shape.shadowScale = 1.0f;
+ func_80A5D7A4(this);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B160.s")
+void EnKusa2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnKusa2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B334.s")
+ if (ENKUSA2_GET_1(&this->actor) == 1) {
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B3BC.s")
+void func_80A5D5E0(EnKusa2* this) {
+ this->actionFunc = func_80A5D5F4;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B490.s")
+void func_80A5D5F4(EnKusa2* this, GlobalContext* globalCtx) {
+ func_80A5D618(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B508.s")
+void func_80A5D618(EnKusa2* this) {
+ this->actionFunc = func_80A5D62C;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B954.s")
+void func_80A5D62C(EnKusa2* this, GlobalContext* globalCtx) {
+ if (this->unk_1BE != 0) {
+ func_80A5B490(this, globalCtx);
+ func_80A5D754(this);
+ } else if (Math3D_XZLengthSquared(this->actor.projectedPos.x, this->actor.projectedPos.z) < SQ(1600.0f)) {
+ func_80A5B160(this, globalCtx);
+ func_80A5D6B0(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BA58.s")
+void func_80A5D6B0(EnKusa2* this) {
+ this->actionFunc = func_80A5D6C4;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BAFC.s")
+void func_80A5D6C4(EnKusa2* this, GlobalContext* globalCtx) {
+ func_80A5B3BC(this);
+ if (this->unk_1BE != 0) {
+ func_80A5B490(this, globalCtx);
+ func_80A5D754(this);
+ } else if (Math3D_XZLengthSquared(this->actor.projectedPos.x, this->actor.projectedPos.z) > SQ(1750.0f)) {
+ func_80A5B334(this, globalCtx);
+ func_80A5D618(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BB40.s")
+void func_80A5D754(EnKusa2* this) {
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BD14.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) {
+ this->unk_194[i] = NULL;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BD94.s")
+ this->actionFunc = func_80A5D794;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BDB0.s")
+void func_80A5D794(EnKusa2* this, GlobalContext* globalCtx) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF38.s")
+void func_80A5D7A4(EnKusa2* this) {
+ this->actor.draw = EnKusa2_Draw;
+ this->actionFunc = func_80A5D7C4;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF60.s")
+void func_80A5D7C4(EnKusa2* this, GlobalContext* globalCtx) {
+ EnKusa2* this2 = this;
+ s16 sp2A;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF84.s")
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT);
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ this->actor.shape.shadowAlpha = 60;
+ this->actor.room = -1;
+ func_80A5BD94(this);
+ func_80A5D964(this);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BFD8.s")
+ if (!func_80A5BFD8(this, globalCtx)) {
+ if ((this->unk_1C0 != NULL) && (this->unk_1C0->unk_1BE != 0)) {
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ if (this2->unk_1C0 != NULL) {
+ sp2A = Actor_YawBetweenActors(&this->unk_1C0->actor, &this->actor);
+ this->actor.home.rot.y = Rand_S16Offset(-1500, 3000) + sp2A;
+ }
+ this->unk_1C8 = Rand_S16Offset(72, 16);
+ this->actor.velocity.y = 8.8f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK);
+ func_80A5DC70(this);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C074.s")
+ if (this->actor.xzDistToPlayer < 600.0f) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ if (this->actor.xzDistToPlayer < 400.0f) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ if (this->actor.xzDistToPlayer < 100.0f) {
+ func_800B8BB0(&this->actor, globalCtx);
+ }
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C0B8.s")
+void func_80A5D964(EnKusa2* this) {
+ this->actor.draw = func_80A5E9B4;
+ this->actionFunc = func_80A5D9C8;
+ D_80A5EAF4.x = 0;
+ D_80A5EAF4.y = 0;
+ D_80A5EAF4.z = 0;
+ D_80A5EAFC.x = 0;
+ D_80A5EAFC.y = 0;
+ D_80A5EAFC.z = 0;
+ D_80A5EB04.x = 0;
+ D_80A5EB04.y = 0;
+ D_80A5EB04.z = 0;
+ this->unk_1D0 = 30;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C104.s")
+void func_80A5D9C8(EnKusa2* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Vec3f sp30;
+ s32 sp2C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C2FC.s")
+ D_80A5EAF4.x += 11000;
+ D_80A5EAF4.y += 17000;
+ D_80A5EAF4.z += 9000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C410.s")
+ this->actor.scale.x = (Math_SinS(D_80A5EAF4.x) * 0.020000001f) + 0.4f;
+ this->actor.scale.y = (Math_SinS(D_80A5EAF4.y) * 0.020000001f) + 0.4f;
+ this->actor.scale.z = (Math_SinS(D_80A5EAF4.z) * 0.020000001f) + 0.4f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C70C.s")
+ D_80A5EB04.x += 18000;
+ D_80A5EB04.y += 17000;
+ D_80A5EB04.z += 16000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C718.s")
+ D_80A5EAFC.x = Math_SinS(D_80A5EB04.x) * 1000.0f;
+ D_80A5EAFC.y = Math_SinS(D_80A5EB04.y) * 1000.0f;
+ D_80A5EAFC.z = Math_SinS(D_80A5EB04.z) * 1000.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C7F0.s")
+ if (Actor_HasNoParent(&this->actor, globalCtx)) {
+ this->actor.room = globalCtx->roomCtx.currRoom.num;
+ this->actor.colChkInfo.mass = 80;
+ this->actor.home.rot.y = this->actor.world.rot.y;
+ this->actor.velocity.y = 12.5f;
+ this->actor.speedXZ += 3.0f;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A5BAFC(this, globalCtx);
+ func_80A5CD0C(this);
+ this->unk_1C8 = 30;
+ func_80A5DC70(this);
+ } else {
+ sp30.x = this->actor.world.pos.x;
+ sp30.y = this->actor.world.pos.y + 20.0f;
+ sp30.z = this->actor.world.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C918.s")
+ if ((u32)Rand_Next() < 0xFFFFFFF) {
+ func_80A5CD0C(this);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CAD4.s")
+ this->unk_1D0--;
+ if (this->unk_1D0 <= 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE);
+ this->unk_1D0 = ((u32)Rand_Next() >> 0x1D) + 14;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CAF4.s")
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CB74.s")
+void func_80A5DC70(EnKusa2* this) {
+ this->actionFunc = func_80A5DC98;
+ this->actor.draw = func_80A5EA48;
+ this->unk_1CA = 80;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CCD4.s")
+void func_80A5DC98(EnKusa2* this, GlobalContext* globalCtx) {
+ if (!func_80A5BFD8(this, globalCtx)) {
+ if (this->actor.velocity.y > 1.0f) {
+ Math_StepToF(&this->actor.scale.y, 0.3f, 0.060000002f);
+ Math_StepToF(&this->actor.scale.x, 0.328f, 0.040000003f);
+ } else {
+ Math_StepToF(&this->actor.scale.y, 0.48000002f, 0.080000006f);
+ Math_StepToF(&this->actor.scale.x, 0.28f, 0.032f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CD0C.s")
+ this->actor.scale.z = this->actor.scale.x;
+ Math_StepToF(&this->actor.gravity, -7.0f, 1.8f);
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A5BAFC(this, globalCtx);
+ func_80A5BF38(this, 4);
+ func_80A5BF84(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CF44.s")
+ if (this->actor.bgCheckFlags & 1) {
+ func_80A5CD0C(this);
+ func_80A5BB40(this, globalCtx, 1);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK);
+ func_80A5DE18(this);
+ } else if (this->actor.bgCheckFlags & 0x20) {
+ func_80A5BDB0(this, globalCtx);
+ func_80A5E418(this);
+ } else if (this->unk_1CA > 0) {
+ this->unk_1CA--;
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D178.s")
+void func_80A5DE18(EnKusa2* this) {
+ this->actionFunc = func_80A5DEB4;
+ this->actor.draw = func_80A5EA48;
+ this->actor.gravity = -2.0f;
+ this->unk_1D0 = (s32)(Rand_ZeroOne() * 3.0f);
+ this->unk_1D1 = (s32)(Rand_ZeroOne() * 8.0f) + 7;
+ this->unk_1CA = Rand_S16Offset(19, 2);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Init.s")
+void func_80A5DEB4(EnKusa2* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 pad2;
+ s16 sp24;
+ s32 sp20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Destroy.s")
+ if (!func_80A5BFD8(this, globalCtx)) {
+ if (this->unk_1D0 > 0) {
+ this->unk_1D0--;
+ if (this->unk_1D0 == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D5E0.s")
+ if (this->unk_1D1 > 0) {
+ this->unk_1D1--;
+ if (this->unk_1D1 == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D5F4.s")
+ Math_StepToF(&this->actor.scale.y, 0.4f, 0.032f);
+ Math_StepToF(&this->actor.scale.x, 0.4f, 0.032f);
+ this->unk_1C4 += 0x4650;
+ this->actor.scale.z = this->actor.scale.x;
+ this->actor.speedXZ = fabsf(Math_CosS(this->unk_1C4) + 0.5f) * 1.5f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D618.s")
+ if (this->actor.speedXZ < 0.0f) {
+ this->actor.speedXZ = 0.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D62C.s")
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D6B0.s")
+ this->actor.world.rot.y = (s32)(Math_SinS(this->unk_1C4) * 3000.0f) + this->actor.home.rot.y;
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->actor.shape.rot.x = (s32)(fabsf(Math_SinS(this->unk_1C4)) * 4000.0f) - 0x6A4;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D6C4.s")
+ func_80A5BAFC(this, globalCtx);
+ func_80A5BF38(this, 4);
+ func_80A5BF84(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D754.s")
+ if ((u32)Rand_Next() < 0xFFFFFFF) {
+ func_80A5CD0C(this);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D794.s")
+ if (this->actor.bgCheckFlags & 0x20) {
+ func_80A5BDB0(this, globalCtx);
+ func_80A5E418(this);
+ } else {
+ this->unk_1C8--;
+ if (this->unk_1C8 <= 0) {
+ func_80A5CD0C(this);
+ func_80A5BB40(this, globalCtx, 4);
+ this->actor.speedXZ += 4.0f;
+ this->actor.velocity.y = (Rand_ZeroOne() * 4.0f) + 15.0f;
+ func_80A5E1D8(this);
+ } else if (this->actor.bgCheckFlags & 1) {
+ this->unk_1CA--;
+ if (this->unk_1CA <= 0) {
+ func_80A5CD0C(this);
+ func_80A5BB40(this, globalCtx, 2);
+ this->actor.velocity.y = (Rand_ZeroOne() * 6.0f) + 7.0f;
+ this->actor.speedXZ += 2.0f;
+ if (this->actor.yawTowardsPlayer < this->actor.world.rot.y) {
+ sp20 = 10000;
+ } else {
+ sp20 = -10000;
+ }
+ sp24 = sp20 + Rand_S16Offset(-3000, 6000);
+ this->actor.home.rot.y += sp24;
+ this->actor.world.rot.y = this->actor.home.rot.y;
+ func_80A5DC70(this);
+ }
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D7A4.s")
+void func_80A5E1D8(EnKusa2* this) {
+ this->actionFunc = func_80A5E210;
+ this->actor.draw = func_80A5EA48;
+ this->unk_1CC = 0;
+ func_80A5CB74(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D7C4.s")
+void func_80A5E210(EnKusa2* this, GlobalContext* globalCtx) {
+ Math_StepToF(&this->actor.gravity, -4.0f, 0.5f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D964.s")
+ if (this->actor.bgCheckFlags & 1) {
+ this->actor.speedXZ *= 0.4f;
+ if (this->actor.bgCheckFlags & 2) {
+ func_80A5D178(this);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_KUSAMUSHI_HIDE);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D9C8.s")
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A5BAFC(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DC70.s")
+ if (this->actor.velocity.y > 0.01f) {
+ func_80A5BF38(this, 4);
+ this->unk_1CC += 1000;
+ } else {
+ func_80A5BF60(this, 10);
+ this->unk_1CF -= 20;
+ this->unk_1CC += 5000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DC98.s")
+ if (this->unk_1CC > 20000) {
+ this->unk_1CC = 20000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DE18.s")
+ this->actor.shape.rot.y += this->unk_1CC;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DEB4.s")
+ if (this->actor.velocity.y > 1.0f) {
+ Math_StepToF(&this->actor.scale.y, 0.24000001f, 0.080000006f);
+ Math_StepToF(&this->actor.scale.x, 0.32000002f, 0.040000003f);
+ } else if (this->actor.bgCheckFlags & 1) {
+ Math_StepToF(&this->actor.scale.y, 0.0f, 0.120000005f);
+ Math_StepToF(&this->actor.scale.x, 0.48000002f, 0.120000005f);
+ } else {
+ Math_StepToF(&this->actor.scale.y, 0.56f, 0.1f);
+ Math_StepToF(&this->actor.scale.x, 0.24000001f, 0.1f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E1D8.s")
+ this->actor.scale.z = this->actor.scale.x;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E210.s")
+ if (this->unk_1CF <= 20) {
+ if (this->unk_1B8 != NULL) {
+ this->unk_1B8->unk_28 = func_80A5C718;
+ }
+ Actor_MarkForDeath(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E418.s")
+void func_80A5E418(EnKusa2* this) {
+ this->actor.minVelocityY = -4.0f;
+ this->actor.velocity.x *= 0.1f;
+ this->actor.velocity.y *= 0.25f;
+ this->actor.velocity.z *= 0.1f;
+ this->actor.draw = func_80A5EA48;
+ this->actor.speedXZ *= 0.1f;
+ this->actor.gravity *= 0.25f;
+ this->unk_1CC = Rand_S16Offset(-800, 1600);
+ this->actionFunc = func_80A5E4BC;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E4BC.s")
+void func_80A5E4BC(EnKusa2* this, GlobalContext* globalCtx) {
+ Math_StepToF(&this->actor.scale.y, 0.4f, 0.032f);
+ Math_StepToF(&this->actor.scale.x, 0.4f, 0.032f);
+ this->actor.scale.z = this->actor.scale.x;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A5BAFC(this, globalCtx);
+ func_80A5BF60(this, 6);
+ this->actor.shape.rot.x -= 0x5DC;
+ this->actor.shape.rot.y += this->unk_1CC;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E604.s")
+ if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 5.0f) && (Rand_ZeroOne() < 0.8f)) {
+ EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 20.0f, 10.0f, 20.0f, (Rand_ZeroOne() * 0.08f) + 0.04f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Update.s")
+ this->unk_1CF -= 15;
+ if (this->unk_1CF <= 15) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E6F0.s")
+void func_80A5E604(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnKusa2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E80C.s")
+ this->actionFunc(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Draw.s")
+ if (D_80A60900 == globalCtx->gameplayFrames) {
+ this->actor.draw = NULL;
+ } else {
+ this->actor.draw = func_80A5E6F0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E9B4.s")
+ if (globalCtx->roomCtx.currRoom.unk3 == 0) {
+ func_80A5B508();
+ }
+ func_80A5CAF4(&D_80A5F1C0);
+ D_80A60900 = globalCtx->gameplayFrames;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5EA48.s")
+void EnKusa2_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnKusa2* this = THIS;
+
+ if ((this->unk_1C0 != NULL) && (this->unk_1C0->actor.update == NULL)) {
+ this->unk_1C0 = NULL;
+ }
+
+ this->actionFunc(this, globalCtx);
+
+ func_80A5CCD4(this);
+}
+
+void func_80A5E6F0(Actor* thisx, GlobalContext* globalCtx) {
+ static Gfx* D_80A5EB68[] = {
+ D_040528B0,
+ D_040527F0,
+ };
+ EnKusa2* this = THIS;
+ s32 i;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) {
+ EnKusa2UnkBssSubStruct2* s = &D_80A5F1C0.unk_0480[i];
+
+ if (s->unk_2C > 0) {
+ Matrix_SetStateRotationAndTranslation(s->unk_04.x, s->unk_04.y, s->unk_04.z, &s->unk_20);
+ Matrix_Scale(s->unk_00, s->unk_00, s->unk_00, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, D_80A5EB68[i & 1]);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A5E80C(GlobalContext* globalCtx, s32 arg1) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, arg1);
+ gSPDisplayList(POLY_XLU_DISP++, D_05007938);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnKusa2_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnKusa2* this = THIS;
+
+ if (this->actor.projectedPos.z <= 1200.0f) {
+ if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actor.projectedPos.z > -150.0f) &&
+ (this->actor.projectedPos.z < 400.0f)) {
+ func_80A5B954(&D_80A60908[this->unk_1CE], 0.0015f);
+ }
+ func_800BDFC0(globalCtx, D_050078A0);
+ } else if (this->actor.projectedPos.z < 1300.0f) {
+ func_80A5E80C(globalCtx, (1300.0f - this->actor.projectedPos.z) * 2.55f);
+ }
+}
+
+void func_80A5E9B4(Actor* thisx, GlobalContext* globalCtx) {
+ Vec3s sp18;
+
+ sp18.x = thisx->shape.rot.x + D_80A5EAFC.x;
+ sp18.y = thisx->shape.rot.y + D_80A5EAFC.y;
+ sp18.z = thisx->shape.rot.z + D_80A5EAFC.z;
+ Matrix_SetStateRotationAndTranslation(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, &sp18);
+ Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY);
+ func_800BDFC0(globalCtx, D_050078A0);
+}
+
+void func_80A5EA48(Actor* thisx, GlobalContext* globalCtx) {
+ EnKusa2* this = THIS;
+
+ if (this->unk_1CF == 0xFF) {
+ func_800BDFC0(globalCtx, D_050078A0);
+ } else {
+ func_80A5E80C(globalCtx, this->unk_1CF);
+ }
+}
diff --git a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h
index 409c0c813..f18c1a6a7 100644
--- a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h
+++ b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h
@@ -4,14 +4,81 @@
#include "global.h"
struct EnKusa2;
+struct EnKusa2UnkBssSubStruct;
typedef void (*EnKusa2ActionFunc)(struct EnKusa2*, GlobalContext*);
+typedef void (*EnKusa2BssFunc)(struct EnKusa2UnkBssSubStruct*);
+
+#define ENKUSA2_GET_1(thisx) (((thisx)->params) & 1)
+#define ENKUSA2_GET_7F00(thisx) (u8)((((thisx)->params) >> 8) & 0x7F)
+
+typedef struct EnKusa2UnkBssSubStruct {
+ /* 0x00 */ Vec3f unk_00;
+ /* 0x0C */ Vec3f unk_0C;
+ /* 0x18 */ f32 unk_18;
+ /* 0x1C */ f32 unk_1C;
+ /* 0x20 */ s16 unk_20;
+ /* 0x22 */ s16 unk_22;
+ /* 0x24 */ s16 unk_24;
+ /* 0x26 */ s16 unk_26;
+ /* 0x28 */ EnKusa2BssFunc unk_28;
+ /* 0x2C */ f32 unk_2C;
+ /* 0x30 */ f32 unk_30;
+ /* 0x34 */ f32 unk_34;
+ /* 0x38 */ f32 unk_38;
+ /* 0x3C */ f32 unk_3C;
+ /* 0x40 */ f32 unk_40;
+ /* 0x44 */ f32 unk_44;
+ /* 0x48 */ f32 unk_48;
+ /* 0x4C */ f32 unk_4C;
+ /* 0x50 */ f32 unk_50;
+ /* 0x54 */ f32 unk_54;
+ /* 0x58 */ f32 unk_58;
+ /* 0x5C */ f32 unk_5C;
+ /* 0x60 */ f32 unk_60;
+ /* 0x64 */ f32 unk_64;
+ /* 0x68 */ f32 unk_68;
+ /* 0x6C */ f32 unk_6C;
+ /* 0x70 */ f32 unk_70;
+ /* 0x74 */ f32 unk_74;
+ /* 0x78 */ f32 unk_78;
+ /* 0x7C */ f32 unk_7C;
+} EnKusa2UnkBssSubStruct; // size = 0x80
+
+typedef struct {
+ /* 0x00 */ f32 unk_00;
+ /* 0x04 */ Vec3f unk_04;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ f32 unk_1C;
+ /* 0x20 */ Vec3s unk_20;
+ /* 0x26 */ Vec3s unk_26;
+ /* 0x2C */ s16 unk_2C;
+ /* 0x2C */ UNK_TYPE1 unk2E[0x2];
+} EnKusa2UnkBssSubStruct2; // size = 0x30
+
+typedef struct {
+ /* 0x0000 */ EnKusa2UnkBssSubStruct unk_0000[9];
+ /* 0x0480 */ EnKusa2UnkBssSubStruct2 unk_0480[100];
+} EnKusa2UnkBssStruct; // size = 0x1740
typedef struct EnKusa2 {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x4C];
+ /* 0x0144 */ ColliderCylinder collider;
/* 0x0190 */ EnKusa2ActionFunc actionFunc;
- /* 0x0194 */ char unk_194[0x40];
+ /* 0x0194 */ struct EnKusa2* unk_194[9];
+ /* 0x01B8 */ EnKusa2UnkBssSubStruct* unk_1B8;
+ /* 0x01BC */ s16 unk_1BC;
+ /* 0x01BE */ s8 unk_1BE;
+ /* 0x01C0 */ struct EnKusa2* unk_1C0;
+ /* 0x01C4 */ s16 unk_1C4;
+ /* 0x01C6 */ UNK_TYPE1 unk1C6[0x2];
+ /* 0x01C8 */ s16 unk_1C8;
+ /* 0x01CA */ s16 unk_1CA;
+ /* 0x01CC */ s16 unk_1CC;
+ /* 0x01CE */ s8 unk_1CE;
+ /* 0x01CF */ u8 unk_1CF;
+ /* 0x01D0 */ s8 unk_1D0;
+ /* 0x01D1 */ s8 unk_1D1;
} EnKusa2; // size = 0x1D4
extern const ActorInit En_Kusa2_InitVars;
diff --git a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
index 69823ad0e..4bc8d8378 100644
--- a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
+++ b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
@@ -15,10 +15,9 @@ void EnMm2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnMm2_Update(Actor* thisx, GlobalContext* globalCtx);
void EnMm2_Draw(Actor* thisx, GlobalContext* globalCtx);
-void func_809A2080(EnMm2* this, GlobalContext* globalCtx);
-void func_809A20FC(EnMm2* this, GlobalContext* globalCtx);
+void EnMm2_Reading(EnMm2* this, GlobalContext* globalCtx);
+void EnMm2_WaitForRead(EnMm2* this, GlobalContext* globalCtx);
-#if 0
const ActorInit En_Mm2_InitVars = {
ACTOR_EN_MM2,
ACTORCAT_ITEMACTION,
@@ -31,16 +30,59 @@ const ActorInit En_Mm2_InitVars = {
(ActorFunc)EnMm2_Draw,
};
-#endif
+#include "overlays/ovl_En_Mm2/ovl_En_Mm2.c"
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Init.s")
+void EnMm2_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnMm2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Destroy.s")
+ Actor_SetScale(&this->actor, 0.015f);
+ this->actionFunc = EnMm2_WaitForRead;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/func_809A2080.s")
+void EnMm2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/func_809A20FC.s")
+/**
+ * Action function whilst Link is reading the letter.
+ */
+void EnMm2_Reading(EnMm2* this, GlobalContext* globalCtx) {
+ u8 talkState = func_80152498(&globalCtx->msgCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Update.s")
+ if (talkState != 2) {
+ if (talkState == 5 && func_80147624(globalCtx)) {
+ func_801477B4(globalCtx);
+ this->actionFunc = EnMm2_WaitForRead;
+ }
+ } else {
+ this->actionFunc = EnMm2_WaitForRead;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Draw.s")
+/**
+ * Action function that awaits Link to read the letter, changing the A button to "Check" when he is within range to do
+ * so (and facing the letter).
+ */
+void EnMm2_WaitForRead(EnMm2* this, GlobalContext* globalCtx) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ func_801518B0(globalCtx, 0x277B, &this->actor);
+ this->actionFunc = EnMm2_Reading;
+ } else if ((this->actor.xzDistToPlayer < 60.0f) && (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx))) {
+ func_800B8614(&this->actor, globalCtx, 110.0f);
+ }
+}
+
+void EnMm2_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnMm2* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+}
+
+void EnMm2_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, sEnMm2DL);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
index 5f51217bb..a5e8cf210 100644
--- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
+++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
@@ -5,6 +5,8 @@
*/
#include "z_en_peehat.h"
+#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+#include "objects/object_ph/object_ph.h"
#define FLAGS 0x00000015
@@ -15,7 +17,26 @@ void EnPeehat_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPeehat_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPeehat_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void func_80897498(EnPeehat* this);
+void func_80897520(EnPeehat* this, GlobalContext* globalCtx);
+void func_80897648(EnPeehat* this);
+void func_808976DC(EnPeehat* this, GlobalContext* globalCtx);
+void func_80897910(EnPeehat* this, GlobalContext* globalCtx);
+void func_80897A34(EnPeehat* this);
+void func_80897A94(EnPeehat* this, GlobalContext* globalCtx);
+void func_80897D48(EnPeehat* this, GlobalContext* globalCtx);
+void func_80897EAC(EnPeehat* this);
+void func_80897F44(EnPeehat* this, GlobalContext* globalCtx);
+void func_80898124(EnPeehat* this);
+void func_80898144(EnPeehat* this, GlobalContext* globalCtx);
+void func_808982E0(EnPeehat* this);
+void func_80898338(EnPeehat* this, GlobalContext* globalCtx);
+void func_80898454(EnPeehat* this, GlobalContext* globalCtx);
+void func_808984E0(EnPeehat* this);
+void func_80898594(EnPeehat* this, GlobalContext* globalCtx);
+void func_80898654(EnPeehat* this);
+void func_808986A4(EnPeehat* this, GlobalContext* globalCtx);
+
const ActorInit En_Peehat_InitVars = {
ACTOR_EN_PEEHAT,
ACTORCAT_ENEMY,
@@ -28,40 +49,85 @@ const ActorInit En_Peehat_InitVars = {
(ActorFunc)EnPeehat_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80899430 = {
- { COLTYPE_WOOD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_WOOD,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON | BUMP_HOOKABLE,
+ OCELEM_ON,
+ },
{ 50, 120, -20, { 0, 0, 0 } },
};
-// static ColliderSphereInit sSphereInit = {
-static ColliderSphereInit D_8089945C = {
- { COLTYPE_HIT6, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderSphereInit sSphereInit = {
+ {
+ COLTYPE_HIT6,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_SPHERE,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 40 }, 100 },
};
-// static ColliderTrisElementInit sTrisElementsInit[2] = {
-static ColliderTrisElementInit D_80899488[2] = {
+static ColliderTrisElementInit sTrisElementsInit[2] = {
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
},
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x10 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
},
};
-// static ColliderTrisInit sTrisInit = {
-static ColliderTrisInit D_80899500 = {
- { COLTYPE_METAL, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, },
- 2, D_80899488, // sTrisElementsInit,
+static ColliderTrisInit sTrisInit = {
+ {
+ COLTYPE_METAL,
+ AT_NONE | AT_TYPE_ENEMY,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_TRIS,
+ },
+ 2,
+ sTrisElementsInit,
};
-// static DamageTable sDamageTable = {
-static DamageTable D_80899510 = {
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
/* Deku Stick */ DMG_ENTRY(1, 0x0),
/* Horse trample */ DMG_ENTRY(1, 0x0),
@@ -96,98 +162,787 @@ static DamageTable D_80899510 = {
/* Powder Keg */ DMG_ENTRY(1, 0x0),
};
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_80899530 = { 15, 50, 120, -20, MASS_HEAVY };
+static CollisionCheckInfoInit2 sColChkInfoInit1 = { 15, 50, 120, -20, MASS_HEAVY };
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_8089953C = { 1, 20, 15, -5, 30 };
+static CollisionCheckInfoInit2 sColChkInfoInit2 = { 1, 20, 15, -5, 30 };
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80899548[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 4200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1800, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 700, ICHAIN_STOP),
};
-#endif
+void EnPeehat_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnPeehat* this = THIS;
-extern ColliderCylinderInit D_80899430;
-extern ColliderSphereInit D_8089945C;
-extern ColliderTrisElementInit D_80899488[2];
-extern ColliderTrisInit D_80899500;
-extern DamageTable D_80899510;
-extern CollisionCheckInfoInit2 D_80899530;
-extern CollisionCheckInfoInit2 D_8089953C;
-extern InitChainEntry D_80899548[];
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &object_ph_Skel_001C80, &object_ph_Anim_0009C4, this->jointTable,
+ this->morphTable, 24);
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 27.0f);
+ this->unk_2B0 = 0;
+ Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos);
+ this->actor.floorHeight = this->actor.world.pos.y;
+ Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit);
+ Collider_InitAndSetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit);
+ Collider_InitAndSetTris(globalCtx, &this->colliderTris, &this->actor, &sTrisInit, this->colliderTriElements);
-extern UNK_TYPE D_06000350;
-extern UNK_TYPE D_060005C4;
-extern UNK_TYPE D_06000844;
-extern UNK_TYPE D_060009C4;
+ if (this->actor.params == 0) {
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit1);
+ if (gSaveContext.save.isNight) {
+ this->actor.shape.yOffset = -1000.0f;
+ }
+ Actor_SetScale(&this->actor, 0.036f);
+ this->actor.hintId = 0x48;
+ func_80897498(this);
+ } else {
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2);
+ this->actor.scale.z = this->actor.scale.x = 0.006f;
+ this->actor.scale.y = 0.003f;
+ this->actor.velocity.y = 6.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Init.s")
+ this->colliderCylinder.dim.radius = 20;
+ this->colliderCylinder.dim.height = 15;
+ this->colliderCylinder.dim.yShift = -5;
+ this->actor.hintId = 0x49;
+ this->colliderCylinder.base.ocFlags1 &= ~OC1_ON;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Destroy.s")
+ func_80897A34(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897170.s")
+void EnPeehat_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPeehat* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808971DC.s")
+ Collider_DestroyCylinder(globalCtx, &this->colliderCylinder);
+ Collider_DestroySphere(globalCtx, &this->colliderSphere);
+ Collider_DestroyTris(globalCtx, &this->colliderTris);
+ if (this->actor.params != 0) {
+ EnPeehat* parent = (EnPeehat*)this->actor.parent;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897258.s")
+ if ((parent != NULL) && (parent->actor.update != NULL)) {
+ parent->unk_2AC--;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897390.s")
+void func_80897170(EnPeehat* this) {
+ this->unk_2AE = 10;
+ this->unk_2CC = 1.1f;
+ this->unk_2D0 = 1.6500001f;
+ this->unk_2C8 = 1.0f;
+ this->colliderSphere.base.colType = COLTYPE_HIT3;
+ this->unk_2B0 = 80;
+ func_800BCB70(&this->actor, 0x4000, 255, 0, 80);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897498.s")
+void func_808971DC(EnPeehat* this, GlobalContext* globalCtx) {
+ if (this->unk_2AE == 10) {
+ this->unk_2AE = 0;
+ this->colliderSphere.base.colType = COLTYPE_HIT6;
+ this->unk_2C8 = 0.0f;
+ func_800BF7CC(globalCtx, &this->actor, this->unk_2EC, ARRAY_COUNT(this->unk_2EC), 2, 0.5f, 0.35f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897520.s")
+void func_80897258(GlobalContext* globalCtx, EnPeehat* this, Vec3f* arg2, f32 arg3, f32 arg4) {
+ static Vec3f D_80899558 = { 0.0f, 8.0f, 0.0f };
+ static Vec3f D_80899564 = { 0.0f, -1.5f, 0.0f };
+ Vec3f sp44;
+ s16 sp42 = Rand_Next() >> 0x10;
+ s32 temp_v1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897648.s")
+ sp44.y = this->actor.floorHeight;
+ sp44.x = (Math_SinS(sp42) * arg3) + arg2->x;
+ sp44.z = (Math_CosS(sp42) * arg3) + arg2->z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808976DC.s")
+ D_80899564.x = randPlusMinusPoint5Scaled(1.05f);
+ D_80899564.z = randPlusMinusPoint5Scaled(1.05f);
+ D_80899558.y = randPlusMinusPoint5Scaled(4.0f) + 8.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897864.s")
+ EffectSsHahen_Spawn(globalCtx, &sp44, &D_80899558, &D_80899564, 0, (Rand_ZeroFloat(5.0f) + 12.0f) * arg4, -1, 10,
+ NULL);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897910.s")
+void func_80897390(EnPeehat* this, GlobalContext* globalCtx) {
+ s32 i;
+ s16 phi_s2 = BINANG_ROT180(this->actor.yawTowardsPlayer);
+ Actor* actor;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897A34.s")
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897A94.s")
+ for (i = 3 - this->unk_2AC; i > 0; i--) {
+ actor =
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PEEHAT, this->actor.world.pos.x,
+ this->actor.world.pos.y + 50.0f, this->actor.world.pos.z, 0, phi_s2, 0, 1);
+ phi_s2 += 0x5555;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897D00.s")
+ if (actor != NULL) {
+ this->unk_2AC++;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897D48.s")
+ this->unk_2B0 = 8;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_DAMAGE);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897EAC.s")
+void func_80897498(EnPeehat* this) {
+ Animation_Change(&this->skelAnime, &object_ph_Anim_0009C4, 0.0f, 3.0f,
+ Animation_GetLastFrame(&object_ph_Anim_0009C4), 2, 0.0f);
+ this->unk_2B0 = 0;
+ this->unk_2AD = 1;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
+ this->actionFunc = func_80897520;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897F44.s")
+void func_80897520(EnPeehat* this, GlobalContext* globalCtx) {
+ if (!gSaveContext.save.isNight) {
+ this->actor.flags |= 1;
+ this->colliderSphere.base.acFlags |= AC_ON;
+ if (this->actor.xzDistToPlayer < 740.0f) {
+ func_80897648(this);
+ } else {
+ Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 10.0f);
+ }
+ } else {
+ this->actor.flags &= ~1;
+ this->colliderSphere.base.acFlags &= ~AC_ON;
+ Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 50.0f);
+ if (this->unk_2B0 != 0) {
+ this->unk_2B0--;
+ if (this->unk_2B0 & 4) {
+ Math_StepToF(&this->unk_2C4, 0.205f, 0.235f);
+ } else {
+ Math_StepToF(&this->unk_2C4, 0.0f, 0.005f);
+ }
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ func_80897390(this, globalCtx);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898124.s")
+void func_80897648(EnPeehat* this) {
+ if (this->actionFunc != func_80898454) {
+ Animation_Change(&this->skelAnime, &object_ph_Anim_0009C4, 0.0f, 3.0f,
+ Animation_GetLastFrame(&object_ph_Anim_0009C4), 2, 0.0f);
+ }
+ this->unk_2B0 = 16;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_UP);
+ this->actionFunc = func_808976DC;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898144.s")
+void func_808976DC(EnPeehat* this, GlobalContext* globalCtx) {
+ Vec3f sp34;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808982E0.s")
+ Math_StepToF(&this->actor.shape.yOffset, 0.0f, 50.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898338.s")
+ if (Math_ScaledStepToS(&this->unk_2B2, 4000, 800)) {
+ if (this->unk_2B0 != 0) {
+ this->unk_2B0--;
+ if ((this->unk_2B0 == 0) && (this->skelAnime.playSpeed < 0.5f)) {
+ this->unk_2B0 = -1;
+ this->skelAnime.playSpeed = 1.0f;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898414.s")
+ if (SkelAnime_Update(&this->skelAnime) || (this->unk_2B0 == 0)) {
+ func_80897EAC(this);
+ } else {
+ this->actor.world.pos.y += 6.5f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898454.s")
+ if ((this->actor.world.pos.y - this->actor.floorHeight) < 80.0f) {
+ Math_Vec3f_Copy(&sp34, &this->actor.world.pos);
+ sp34.y = this->actor.floorHeight;
+ func_800BBFB0(globalCtx, &sp34, 90.0f, 1, 150, 100, 1);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808984E0.s")
+ func_80897258(globalCtx, this, &this->actor.world.pos, 75.0f, 2.0f);
+ Math_StepToF(&this->unk_2C4, 0.075f, 0.005f);
+ this->unk_2B4 += this->unk_2B2;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898594.s")
+void func_80897864(EnPeehat* this) {
+ Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4);
+ this->unk_2B8 = 0.0f;
+ if (this->actionFunc == func_80898338) {
+ this->unk_2AD = -this->unk_2AD;
+ } else {
+ this->unk_2AD = (Rand_ZeroOne() < 0.5f) ? 1 : -1;
+ }
+ this->colliderTris.base.atFlags |= AT_ON;
+ this->actionFunc = func_80897910;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898654.s")
+void func_80897910(EnPeehat* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808986A4.s")
+ Math_StepToF(&this->actor.speedXZ, 3.0f, 0.25f);
+ Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 80.0f, 3.0f);
+ SkelAnime_Update(&this->skelAnime);
+ if (!gSaveContext.save.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) {
+ Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1000);
+ this->actor.shape.rot.y += (s16)(this->unk_2AD * 450);
+ } else {
+ func_80898124(this);
+ }
+ Math_ScaledStepToS(&this->unk_2B2, 4000, 500);
+ this->unk_2B4 += this->unk_2B2;
+ Math_StepToF(&this->unk_2C4, 0.075f, 0.005f);
+ func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_8089874C.s")
+void func_80897A34(EnPeehat* this) {
+ Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4);
+ this->unk_2B0 = 30;
+ this->actor.speedXZ = 5.3f;
+ this->colliderTris.base.atFlags |= AT_ON;
+ this->actionFunc = func_80897A94;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Update.s")
+void func_80897A94(EnPeehat* this, GlobalContext* globalCtx) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898E74.s")
+ if ((this->actor.parent != NULL) && (this->actor.parent->update == NULL)) {
+ this->actor.parent = NULL;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80899024.s")
+ if ((this->actor.world.pos.y - this->actor.floorHeight) >= 70.0f) {
+ Math_StepToF(&this->actor.velocity.y, -1.3f, 0.5f);
+ } else {
+ Math_StepToF(&this->actor.velocity.y, -0.135f, 0.05f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Draw.s")
+ if (this->unk_2B0 > 0) {
+ this->unk_2B0--;
+ } else {
+ Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x33E);
+ this->colliderCylinder.base.ocFlags1 |= OC1_ON;
+ }
+
+ this->actor.shape.rot.y += 0x15E;
+ SkelAnime_Update(&this->skelAnime);
+ Math_ScaledStepToS(&this->unk_2B2, 4000, 500);
+ this->unk_2B4 += this->unk_2B2;
+ Math_StepToF(&this->unk_2C4, 0.075f, 0.005f);
+ func_800B9010(&this->actor, NA_SE_EN_PIHAT_SM_FLY - SFX_FLAG);
+
+ if (this->colliderTris.base.atFlags & AT_BOUNCED) {
+ this->colliderTris.base.atFlags &= ~(AT_BOUNCED | AT_ON);
+ this->actor.colChkInfo.health = 0;
+ func_808982E0(this);
+ } else if ((this->colliderCylinder.base.acFlags & AC_HIT) || (this->actor.bgCheckFlags & 1)) {
+ func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 40, 7, 0);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT);
+ if (!(this->actor.bgCheckFlags & 1)) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_PIHAT_SM_DEAD);
+ }
+ Actor_MarkForDeath(&this->actor);
+ } else if (this->colliderTris.base.atFlags & AT_HIT) {
+ this->colliderTris.base.atFlags &= ~AT_HIT;
+ if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y) > 0) {
+ this->actor.world.rot.y -= 0x2000;
+ } else {
+ this->actor.world.rot.y += 0x2000;
+ }
+ this->unk_2B0 = 40;
+ } else if (this->colliderCylinder.base.ocFlags1 & OC1_HIT) {
+ this->colliderCylinder.base.ocFlags1 &= ~OC1_HIT;
+ if ((BINANG_SUB(Actor_YawBetweenActors(&this->actor, this->colliderCylinder.base.oc),
+ this->actor.world.rot.y)) > 0) {
+ this->actor.world.rot.y -= 0x2000;
+ } else {
+ this->actor.world.rot.y += 0x2000;
+ }
+ this->unk_2B0 = 10;
+ }
+}
+
+void func_80897D00(EnPeehat* this) {
+ Animation_PlayOnce(&this->skelAnime, &object_ph_Anim_000350);
+ this->colliderTris.base.atFlags &= ~AT_ON;
+ this->actionFunc = func_80897D48;
+}
+
+void func_80897D48(EnPeehat* this, GlobalContext* globalCtx) {
+ Vec3f sp34;
+
+ Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 50.0f);
+ Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 50);
+ if (SkelAnime_Update(&this->skelAnime)) {
+ func_80897498(this);
+ this->actor.world.pos.y = this->actor.floorHeight;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_LAND);
+ } else if (this->actor.floorHeight < this->actor.world.pos.y) {
+ Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.floorHeight, 0.3f, 3.5f, 0.25f);
+ if ((this->actor.world.pos.y - this->actor.floorHeight) < 60.0f) {
+ Math_Vec3f_Copy(&sp34, &this->actor.world.pos);
+ sp34.y = this->actor.floorHeight;
+ func_800BBFB0(globalCtx, &sp34, 80.0f, 1, 150, 100, 1);
+ func_80897258(globalCtx, this, &sp34, 75.0f, 2.0f);
+ }
+ }
+ Math_ScaledStepToS(&this->unk_2B2, 0, 100);
+ this->unk_2B4 += this->unk_2B2;
+}
+
+void func_80897EAC(EnPeehat* this) {
+ Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4);
+ this->actor.speedXZ = Rand_ZeroFloat(0.5f) + 2.5f;
+ this->unk_2B0 = Rand_ZeroFloat(10.0f) + 10.0f;
+ this->colliderTris.base.atFlags |= AT_ON;
+ this->colliderSphere.base.acFlags |= AC_ON;
+ this->actionFunc = func_80897F44;
+}
+
+void func_80897F44(EnPeehat* this, GlobalContext* globalCtx) {
+ s32 pad;
+ f32 cos;
+ Player* player = GET_PLAYER(globalCtx);
+
+ if ((this->actor.world.pos.y - this->actor.floorHeight) > 75.0f) {
+ this->actor.world.pos.y -= 1.0f;
+ }
+
+ cos = cos_rad(this->unk_2B8);
+ this->actor.world.pos.y += cos * 1.4f;
+ this->unk_2B8 += fabsf(cos * 0.18f) + 0.07f;
+ this->unk_2B0--;
+
+ if (this->unk_2B0 <= 0) {
+ this->actor.speedXZ = Rand_ZeroFloat(0.5f) + 2.5f;
+ this->unk_2B0 = Rand_ZeroFloat(10.0f) + 10.0f;
+ this->unk_2B6 = randPlusMinusPoint5Scaled(1000.0f);
+ }
+
+ SkelAnime_Update(&this->skelAnime);
+ this->actor.world.rot.y += this->unk_2B6;
+ this->actor.shape.rot.y += 0x15E;
+
+ if (!gSaveContext.save.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) {
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ func_80897864(this);
+ } else {
+ func_80898124(this);
+ }
+
+ Math_ScaledStepToS(&this->unk_2B2, 4000, 500);
+ this->unk_2B4 += this->unk_2B2;
+ Math_StepToF(&this->unk_2C4, 0.075f, 0.005f);
+ func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG);
+}
+
+void func_80898124(EnPeehat* this) {
+ this->actionFunc = func_80898144;
+ this->actor.speedXZ = 2.5f;
+}
+
+void func_80898144(EnPeehat* this, GlobalContext* globalCtx) {
+ s32 step;
+ f32 cos;
+ Player* player = GET_PLAYER(globalCtx);
+
+ if ((this->actor.world.pos.y - this->actor.floorHeight) > 75.0f) {
+ this->actor.world.pos.y -= 1.0f;
+ } else {
+ this->actor.world.pos.y += 1.0f;
+ }
+ cos = cos_rad(this->unk_2B8);
+ this->actor.world.pos.y += cos * 1.4f;
+
+ cos = cos_rad(this->unk_2B8);
+ this->unk_2B8 += fabsf(cos * 0.18f) + 0.07f;
+
+ step = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
+ Math_ScaledStepToS(&this->actor.world.rot.y, step, 0x258);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, 0x1194, 0x258);
+
+ this->actor.shape.rot.y += 0x15E;
+ this->unk_2B4 += this->unk_2B2;
+
+ if (Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) < 2.0f) {
+ func_80897D00(this);
+ }
+
+ if (!gSaveContext.save.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) {
+ func_80897864(this);
+ }
+ func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG);
+}
+
+void func_808982E0(EnPeehat* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime, &object_ph_Anim_000844, -4.0f);
+ this->actor.speedXZ = -9.0f;
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ this->actionFunc = func_80898338;
+}
+
+void func_80898338(EnPeehat* this, GlobalContext* globalCtx) {
+ this->unk_2B4 += this->unk_2B2;
+ SkelAnime_Update(&this->skelAnime);
+
+ if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f)) {
+ if (this->actor.params != 0) {
+ func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 40, 7, 0);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_EXTINCT);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_PIHAT_SM_DEAD);
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ func_80897864(this);
+ }
+ }
+ func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG);
+}
+
+void func_80898414(EnPeehat* this) {
+ func_800BE568(&this->actor, &this->colliderSphere);
+ this->unk_2B2 = 0;
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = func_80898454;
+}
+
+void func_80898454(EnPeehat* this, GlobalContext* globalCtx) {
+ if (this->unk_2B0 != 0) {
+ this->unk_2B0--;
+ }
+
+ Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight, 8.0f);
+
+ if (this->unk_2B0 == 0) {
+ func_808971DC(this, globalCtx);
+ if (this->actor.colChkInfo.health == 0) {
+ func_808984E0(this);
+ } else {
+ func_80897648(this);
+ }
+ }
+}
+
+void func_808984E0(EnPeehat* this) {
+ Animation_MorphToPlayOnce(&this->skelAnime, &object_ph_Anim_000844, -4.0f);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_DAMAGE);
+ this->unk_2B2 = 4000;
+ this->unk_2B0 = 14;
+ this->actor.speedXZ = 10.0f;
+ func_800BCB70(&this->actor, 0x4000, 255, 0, 14);
+ this->colliderSphere.base.acFlags &= ~AC_ON;
+ this->unk_2C4 = 0.0f;
+ if (this->actor.colChkInfo.health == 0) {
+ this->actor.velocity.y = 6.0f;
+ }
+ this->actionFunc = func_80898594;
+}
+
+void func_80898594(EnPeehat* this, GlobalContext* globalCtx) {
+ SkelAnime_Update(&this->skelAnime);
+ this->unk_2B4 += this->unk_2B2;
+ Math_ScaledStepToS(&this->unk_2B2, 4000, 250);
+ Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 88.5f, 3.0f);
+ Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f);
+ this->unk_2B0--;
+ if (this->unk_2B0 <= 0) {
+ if (this->actor.colChkInfo.health == 0) {
+ func_80898654(this);
+ } else {
+ func_80897EAC(this);
+ }
+ }
+}
+
+void func_80898654(EnPeehat* this) {
+ Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4);
+ this->unk_2B0 = 5;
+ this->unk_2B8 = 0.0f;
+ this->actionFunc = func_808986A4;
+}
+
+void func_808986A4(EnPeehat* this, GlobalContext* globalCtx) {
+ if (this->unk_2B0 == 5) {
+ EnBom* bomb = (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0x602, 0);
+
+ if (bomb != NULL) {
+ bomb->timer = 0;
+ }
+ }
+
+ this->unk_2B0--;
+
+ if (this->unk_2B0 == 0) {
+ Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xE0);
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_8089874C(EnPeehat* this, GlobalContext* globalCtx) {
+ if (this->colliderTris.base.acFlags & AC_BOUNCED) {
+ this->colliderTris.base.acFlags &= ~AC_BOUNCED;
+ this->colliderSphere.base.acFlags &= ~AC_HIT;
+ return;
+ }
+
+ if (this->colliderSphere.base.acFlags & AC_HIT) {
+ this->colliderSphere.base.acFlags &= ~AC_HIT;
+ if ((this->unk_2AE != 10) || !(this->colliderSphere.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
+ if (!Actor_ApplyDamage(&this->actor)) {
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ }
+
+ this->colliderTris.base.atFlags &= ~(AT_HIT | AT_ON);
+ func_800BE258(&this->actor, &this->colliderSphere.info);
+ func_808971DC(this, globalCtx);
+
+ if (this->actor.colChkInfo.damageEffect == 5) {
+ this->unk_2B0 = 40;
+ func_800BCB70(&this->actor, 0, 255, 0, 40);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ this->unk_2CC = 1.1f;
+ this->unk_2C8 = 2.0f;
+ this->unk_2AE = 32;
+ func_80898414(this);
+ } else if (this->actor.colChkInfo.damageEffect == 1) {
+ this->unk_2B0 = 40;
+ func_800BCB70(&this->actor, 0, 200, 0, 40);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ func_80898414(this);
+ } else if (this->actor.colChkInfo.damageEffect == 3) {
+ func_80897170(this);
+ if (this->actor.colChkInfo.health == 0) {
+ this->unk_2B0 = 3;
+ this->colliderSphere.base.acFlags &= ~AC_ON;
+ }
+ func_80898414(this);
+ } else {
+ if (this->actor.colChkInfo.damageEffect == 2) {
+ this->unk_2C8 = 4.0f;
+ this->unk_2CC = 2.1f;
+ this->unk_2AE = 0;
+ } else if (this->actor.colChkInfo.damageEffect == 4) {
+ this->unk_2C8 = 4.0f;
+ this->unk_2CC = 1.1f;
+ this->unk_2AE = 20;
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG,
+ this->colliderSphere.info.bumper.hitPos.x, this->colliderSphere.info.bumper.hitPos.y,
+ this->colliderSphere.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS);
+ }
+ func_800BE568(&this->actor, &this->colliderSphere);
+ func_808984E0(this);
+ }
+ }
+ } else if ((this->unk_2AE == 10) && (this->colliderCylinder.base.acFlags & AC_HIT) &&
+ ((this->unk_2AE != 10) || !(this->colliderCylinder.info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) {
+ func_808971DC(this, globalCtx);
+ this->actor.colorFilterTimer = 0;
+ func_80897648(this);
+ }
+}
+
+void EnPeehat_Update(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnPeehat* this = THIS;
+
+ if (thisx->params == 0) {
+ func_8089874C(this, globalCtx);
+ }
+ Actor_SetVelocityAndMoveYRotationAndGravity(thisx);
+ Actor_UpdateBgCheckInfo(globalCtx, thisx, 25.0f, 30.0f, 30.0f, 5);
+
+ this->actionFunc(this, globalCtx);
+
+ if ((globalCtx->gameplayFrames % 128) == 0) {
+ this->unk_2C0 = Rand_ZeroFloat(0.25f) + 0.5f;
+ }
+
+ this->unk_2BC += this->unk_2C0;
+ if (thisx->params == 0) {
+ if (this->actionFunc == func_80897910) {
+ Math_ScaledStepToS(&thisx->shape.rot.x, 6000, 300);
+ } else {
+ Math_ScaledStepToS(&thisx->shape.rot.x, 0, 300);
+ }
+ } else {
+ Actor_SetHeight(thisx, 0.0f);
+ }
+
+ Collider_UpdateCylinder(thisx, &this->colliderCylinder);
+ this->colliderCylinder.dim.pos.y += (s16)(thisx->shape.yOffset * thisx->scale.y);
+ if (this->colliderCylinder.base.ocFlags1 & OC1_ON) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+ }
+
+ if (thisx->params == 0) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+ if (this->colliderSphere.base.acFlags & AC_ON) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base);
+ }
+ }
+
+ if (this->colliderTris.base.atFlags & AT_HIT) {
+ this->colliderTris.base.atFlags &= ~AT_HIT;
+ func_808982E0(this);
+ }
+
+ if (this->colliderTris.base.atFlags & AT_ON) {
+ thisx->flags |= 0x1000000;
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base);
+ if (thisx->params == 0) {
+ Vec3f sp74;
+ CollisionPoly* sp70;
+ s32 sp6C;
+ s32 i;
+
+ sp70 = NULL;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base);
+
+ for (i = 1; i >= 0; i--) {
+ if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &thisx->world.pos, &this->unk_2D4[i], &sp74, &sp70, 1,
+ 1, 0, 1, &sp6C)) {
+ func_800BBFB0(globalCtx, &sp74, 0.0f, 1, 300, 150, 1);
+ func_80897258(globalCtx, this, &sp74, 0.0f, 1.5f);
+ }
+ }
+ }
+ }
+
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base);
+
+ if (this->actionFunc != func_80898454) {
+ Math_StepToF(&this->unk_2C4, 0.0f, 0.001f);
+ }
+
+ if (this->unk_2C8 > 0.0f) {
+ if (this->unk_2AE != 10) {
+ Math_StepToF(&this->unk_2C8, 0.0f, 0.05f);
+ if (this->unk_2AE == 0) {
+ this->unk_2CC = (this->unk_2C8 + 1.0f) * 1.05f;
+ this->unk_2CC = CLAMP_MAX(this->unk_2CC, 2.1f);
+ } else {
+ this->unk_2CC = (this->unk_2C8 + 1.0f) * 0.55f;
+ this->unk_2CC = CLAMP_MAX(this->unk_2CC, 1.1f);
+ }
+ } else if (!Math_StepToF(&this->unk_2D0, 1.1f, 0.0275f)) {
+ func_800B9010(thisx, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+ }
+}
+
+s32 EnPeehat_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ Actor* thisx) {
+ EnPeehat* this = THIS;
+ s32 pad;
+
+ if (limbIndex == 4) {
+ rot->x = -this->unk_2B4;
+ } else if ((limbIndex == 3) ||
+ ((limbIndex == 23) && ((this->actionFunc == func_80898594) || (this->actionFunc == func_80897520)))) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ Gfx* gfx = POLY_OPA_DISP;
+
+ Matrix_StatePush();
+ Matrix_RotateStateAroundXAxis(this->unk_2BC * 0.115f);
+ Matrix_InsertYRotation_f(this->unk_2BC * 0.13f, MTXMODE_APPLY);
+ Matrix_InsertZRotation_f(this->unk_2BC * 0.1f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f - this->unk_2C4, this->unk_2C4 + 1.0f, 1.0f - this->unk_2C4, MTXMODE_APPLY);
+ Matrix_InsertZRotation_f(-(this->unk_2BC * 0.1f), MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(-(this->unk_2BC * 0.13f), MTXMODE_APPLY);
+ Matrix_RotateStateAroundXAxis(-(this->unk_2BC * 0.115f));
+
+ gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(&gfx[1], *dList);
+
+ Matrix_StatePop();
+
+ POLY_OPA_DISP = &gfx[2];
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ return true;
+ }
+ return false;
+}
+
+void EnPeehat_PostLimbDraw(GlobalContext* globalCtx2, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f D_80899570[] = {
+ { 1300.0f, 1200.0f, 0.0f },
+ { 1300.0f, -1200.0f, 0.0f },
+ { 1300.0f, 0.0f, 1200.0f },
+ { 1300.0f, 0.0f, -1200.0f },
+ };
+ static s8 D_808995A0[] = {
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 2, -1, -1, 4, -1, -1, 6, -1, -1, 8, -1, -1, 10, -1,
+ };
+ GlobalContext* globalCtx = globalCtx2;
+ EnPeehat* this = THIS;
+ s32 i;
+ s32 index = D_808995A0[limbIndex];
+ Gfx* gfx;
+
+ if (index != -1) {
+ Matrix_GetStateTranslationAndScaledX(2000.0f, &this->unk_2EC[index]);
+ Matrix_GetStateTranslationAndScaledX(4000.0f, &this->unk_2EC[index + 1]);
+ }
+
+ if (limbIndex == 4) {
+ Matrix_GetStateTranslationAndScaledZ(5500.0f, &this->unk_2D4[0]);
+ Matrix_GetStateTranslationAndScaledZ(-5500.0f, &this->unk_2D4[1]);
+ } else if ((limbIndex == 3) && (thisx->params == 0)) {
+ Vec3f* vec = &D_80899570[0];
+ Vec3f* vec2 = &this->unk_2EC[12];
+
+ for (i = 0; i < ARRAY_COUNT(D_80899570); i++, vec++, vec2++) {
+ Matrix_MultiplyVector3fByState(vec, vec2);
+ }
+
+ Matrix_GetStateTranslationAndScaledX(3000.0f, vec2++);
+ Matrix_GetStateTranslationAndScaledX(-400.0f, vec2);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ gfx = POLY_OPA_DISP;
+
+ Matrix_InsertTranslation(-1000.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Collider_UpdateSphere(0, &this->colliderSphere);
+ Matrix_InsertTranslation(500.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(3.2f, MTXMODE_APPLY);
+ Matrix_Scale(0.3f, 0.2f, 0.2f, MTXMODE_APPLY);
+
+ gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(&gfx[1], *dList);
+
+ POLY_OPA_DISP = &gfx[2];
+ Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->colliderSphere.dim.worldSphere.center);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+}
+
+void EnPeehat_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPeehat* this = THIS;
+ Vec3f sp58;
+ Vec3f sp4C;
+ Vec3f sp40;
+ s32 i;
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnPeehat_OverrideLimbDraw,
+ (this->actor.params == 0) ? EnPeehat_PostLimbDraw : NULL, &this->actor);
+
+ if ((this->actor.speedXZ != 0.0f) || (this->actor.velocity.y != 0.0f)) {
+ Matrix_GetStateTranslationAndScaledZ(4500.0f, &sp40);
+ Matrix_GetStateTranslationAndScaledZ(-4500.0f, &sp4C);
+ Matrix_GetStateTranslationAndScaledX(4500.0f, &sp58);
+ Collider_SetTrisVertices(&this->colliderTris, 0, &sp40, &sp4C, &sp58);
+ Matrix_GetStateTranslationAndScaledX(-4500.0f, &sp58);
+ Collider_SetTrisVertices(&this->colliderTris, 1, &sp40, &sp58, &sp4C);
+ }
+
+ if (this->unk_2AE == 0) {
+ for (i = 0; i < ARRAY_COUNT(this->unk_2EC); i++) {
+ this->unk_2EC[i].y -= 50.0f;
+ }
+ }
+
+ func_800BE680(globalCtx, &this->actor, this->unk_2EC, ARRAY_COUNT(this->unk_2EC), this->unk_2CC, this->unk_2D0,
+ this->unk_2C8, this->unk_2AE);
+}
diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
index c6303311a..0aee3a742 100644
--- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
+++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
@@ -8,10 +8,31 @@ struct EnPeehat;
typedef void (*EnPeehatActionFunc)(struct EnPeehat*, GlobalContext*);
typedef struct EnPeehat {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x164];
- /* 0x02A8 */ EnPeehatActionFunc actionFunc;
- /* 0x02AC */ char unk_2AC[0x294];
+ /* 0x000 */ Actor actor;
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ Vec3s jointTable[24];
+ /* 0x188 */ Vec3s morphTable[24];
+ /* 0x2A8 */ EnPeehatActionFunc actionFunc;
+ /* 0x2AC */ u8 unk_2AC;
+ /* 0x2AD */ s8 unk_2AD;
+ /* 0x2AE */ u8 unk_2AE;
+ /* 0x2B0 */ s16 unk_2B0;
+ /* 0x2B2 */ s16 unk_2B2;
+ /* 0x2B4 */ s16 unk_2B4;
+ /* 0x2B6 */ s16 unk_2B6;
+ /* 0x2B8 */ f32 unk_2B8;
+ /* 0x2BC */ f32 unk_2BC;
+ /* 0x2C0 */ f32 unk_2C0;
+ /* 0x2C4 */ f32 unk_2C4;
+ /* 0x2C8 */ f32 unk_2C8;
+ /* 0x2CC */ f32 unk_2CC;
+ /* 0x2D0 */ f32 unk_2D0;
+ /* 0x2D4 */ Vec3f unk_2D4[2];
+ /* 0x2EC */ Vec3f unk_2EC[18];
+ /* 0x3C4 */ ColliderCylinder colliderCylinder;
+ /* 0x410 */ ColliderSphere colliderSphere;
+ /* 0x468 */ ColliderTris colliderTris;
+ /* 0x488 */ ColliderTrisElement colliderTriElements[2];
} EnPeehat; // size = 0x540
extern const ActorInit En_Peehat_InitVars;
diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c
index 0d9ebb784..0bb3e45be 100644
--- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c
+++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c
@@ -315,7 +315,7 @@ Actor* func_80AF7CB0(EnPm* this, GlobalContext* globalCtx, u8 actorCat, s16 acto
Actor* actor;
while (true) {
- actor = func_ActorCategoryIterateById(globalCtx, phi_s0, actorCat, actorId);
+ actor = SubS_FindActor(globalCtx, phi_s0, actorCat, actorId);
phi_s0 = actor;
if (actor == NULL) {
@@ -338,7 +338,7 @@ Actor* func_80AF7CB0(EnPm* this, GlobalContext* globalCtx, u8 actorCat, s16 acto
return phi_s0;
}
-Actor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) {
+EnDoor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) {
s32 phi_a1;
switch (arg1) {
@@ -367,7 +367,7 @@ Actor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) {
return NULL;
}
- return func_8013A7C0(globalCtx, phi_a1);
+ return SubS_FindDoor(globalCtx, phi_a1);
}
Actor* func_80AF7DC4(EnPm* this, GlobalContext* globalCtx, s32 arg2) {
@@ -375,7 +375,7 @@ Actor* func_80AF7DC4(EnPm* this, GlobalContext* globalCtx, s32 arg2) {
Actor* actor;
while (true) {
- actor = func_ActorCategoryIterateById(globalCtx, phi_s0, ACTORCAT_PROP, ACTOR_EN_PST);
+ actor = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_PROP, ACTOR_EN_PST);
phi_s0 = actor;
if (actor == NULL) {
@@ -942,7 +942,7 @@ s32 func_80AF8ED4(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar
s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) {
u16 sp56 = gSaveContext.save.time - 0x3FFC;
u8 sp55 = this->actor.params & 0xFF;
- Actor* sp50;
+ EnDoor* sp50;
Vec3s* sp4C;
Vec3f sp40;
Vec3f sp34;
@@ -955,7 +955,7 @@ s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar
this->unk_234 = func_8013BB34(globalCtx, sp55, D_80AFB430[arg2->unk0]);
}
- if ((sp50 != NULL) && (sp50->update != NULL)) {
+ if ((sp50 != NULL) && (sp50->actor.update != NULL)) {
if (this->unk_234 != 0) {
sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->unk_234->points);
Math_Vec3s_ToVec3f(&sp40, &sp4C[0]);
@@ -964,7 +964,7 @@ s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar
Math_Vec3f_Copy(&this->unk_278, &sp34);
this->actor.world.rot.y = Math_Vec3f_Yaw(&sp40, &sp34);
Math_Vec3f_Copy(&this->actor.world.pos, &sp40);
- temp = this->actor.world.rot.y - sp50->shape.rot.y;
+ temp = this->actor.world.rot.y - sp50->actor.shape.rot.y;
if (ABS_ALT(temp) <= 0x4000) {
this->unk_260 = -0x4B;
} else {
@@ -1409,7 +1409,7 @@ s32 func_80AF9BF8(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar
}
s32 func_80AF9D04(EnPm* this, GlobalContext* globalCtx) {
- EnDoor* sp44 = (EnDoor*)func_80AF7D60(globalCtx, this->unk_258);
+ EnDoor* sp44 = func_80AF7D60(globalCtx, this->unk_258);
Vec3f sp38;
Vec3f* sp28;
f32 temp;
diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c
index ba851d64d..a2428a809 100644
--- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c
+++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c
@@ -5,17 +5,41 @@
*/
#include "z_en_ruppecrow.h"
+#include "objects/object_crow/object_crow.h"
#define FLAGS 0x00004030
#define THIS ((EnRuppecrow*)thisx)
+enum {
+ ENRUPPECROW_EFFECT_NONE = 0,
+ ENRUPPECROW_EFFECT_ICE = 10,
+ ENRUPPECROW_EFFECT_LIGHT = 20,
+};
+
void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx);
void EnRuppecrow_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnRuppecrow_Update(Actor* thisx, GlobalContext* globalCtx);
void EnRuppecrow_Draw(Actor* thisx, GlobalContext* globalCtx);
+void EnRuppecrow_HandleSong(EnRuppecrow*, GlobalContext*);
+s32 EnRuppecrow_UpdateCollision(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_UpdateRupees(EnRuppecrow*);
+void EnRuppecrow_UpdateDamage(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_HandleDeath(EnRuppecrow*);
+void EnRuppecrow_FallToDespawn(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_ShatterIce(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_UpdatePosition(EnRuppecrow*, GlobalContext*);
+s32 EnRuppecrow_CheckPlayedMatchingSong(GlobalContext*);
+void EnRuppecrow_HandleSongCutscene(EnRuppecrow*, GlobalContext*);
+s32 EnRuppecrow_ReachedPointClockwise(EnRuppecrow*, Path*, s32);
+s32 EnRuppecrow_ReachedPointCounterClockwise(EnRuppecrow*, Path*, s32);
+f32 EnRuppecrow_GetPointDirection(Path*, s32, PosRot*, Vec3s*);
+s32 EnRuppecrow_CanSpawnBlueRupees(GlobalContext*);
+void EnRuppecrow_SpawnRupee(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_FlyWhileDroppingRupees(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_UpdateSpeed(EnRuppecrow*, GlobalContext*);
+void EnRuppecrow_FlyToDespawn(EnRuppecrow*, GlobalContext*);
-#if 0
const ActorInit En_Ruppecrow_InitVars = {
ACTOR_EN_RUPPECROW,
ACTORCAT_ENEMY,
@@ -28,25 +52,36 @@ const ActorInit En_Ruppecrow_InitVars = {
(ActorFunc)EnRuppecrow_Draw,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_80BE39B0[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 1, { { 0, 0, 0 }, 20 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_80BE39D4 = {
- { COLTYPE_HIT3, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 1, D_80BE39B0, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_HIT3,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit,
};
-// sColChkInfoInit
-static CollisionCheckInfoInit D_80BE39E4 = { 1, 15, 30, 30 };
+static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 30 };
-// static DamageTable sDamageTable = {
-static DamageTable D_80BE39EC = {
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x1),
/* Deku Stick */ DMG_ENTRY(1, 0x0),
/* Horse trample */ DMG_ENTRY(1, 0x0),
@@ -81,62 +116,558 @@ static DamageTable D_80BE39EC = {
/* Powder Keg */ DMG_ENTRY(1, 0x0),
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80BE3A0C[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP),
};
-#endif
+s32 EnRuppecrow_UpdateCollision(EnRuppecrow* this, GlobalContext* globalCtx) {
+ s32 pad;
-extern ColliderJntSphElementInit D_80BE39B0[1];
-extern ColliderJntSphInit D_80BE39D4;
-extern CollisionCheckInfoInit D_80BE39E4;
-extern DamageTable D_80BE39EC;
-extern InitChainEntry D_80BE3A0C[];
+ this->collider.elements->dim.worldSphere.center.x = this->actor.world.pos.x;
+ this->collider.elements->dim.worldSphere.center.y =
+ sJntSphInit.elements->dim.modelSphere.center.y + this->actor.world.pos.y;
+ this->collider.elements->dim.worldSphere.center.z = this->actor.world.pos.z;
-extern UNK_TYPE D_060000F0;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f, 25.0f, 50.0f, 0x07);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2260.s")
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2330.s")
+s32 EnRuppecrow_ReachedPointClockwise(EnRuppecrow* this, Path* path, s32 pointIndex) {
+ Vec3s* points = Lib_SegmentedToVirtual(path->points);
+ s32 pathCount = path->count;
+ s32 currentPoint = pointIndex;
+ s32 reached = false;
+ f32 diffX;
+ f32 diffZ;
+ f32 px;
+ f32 pz;
+ f32 d;
+ Vec3f point;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE24CC.s")
+ Math_Vec3s_ToVec3f(&point, &points[currentPoint]);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2668.s")
+ if (currentPoint == 0) {
+ diffX = points[1].x - points[0].x;
+ diffZ = points[1].z - points[0].z;
+ } else {
+ if (currentPoint == (pathCount - 1)) {
+ diffX = points[pathCount - 1].x - points[pathCount - 2].x;
+ diffZ = points[pathCount - 1].z - points[pathCount - 2].z;
+ } else {
+ diffX = points[currentPoint + 1].x - points[currentPoint - 1].x;
+ diffZ = points[currentPoint + 1].z - points[currentPoint - 1].z;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2728.s")
+ func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d);
+ if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) {
+ reached = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2794.s")
+ return reached;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2808.s")
+s32 EnRuppecrow_ReachedPointCounterClockwise(EnRuppecrow* this, Path* path, s32 pointIndex) {
+ Vec3s* points = Lib_SegmentedToVirtual(path->points);
+ s32 pathCount = path->count;
+ s32 currentPoint = pointIndex;
+ s32 reached = false;
+ f32 diffX;
+ f32 diffZ;
+ f32 px;
+ f32 pz;
+ f32 d;
+ Vec3f point;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2874.s")
+ Math_Vec3s_ToVec3f(&point, &points[currentPoint]);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2B80.s")
+ if (currentPoint == 0) {
+ diffX = points[0].x - points[1].x;
+ diffZ = points[0].z - points[1].z;
+ } else {
+ if (currentPoint == (pathCount - 1)) {
+ diffX = points[pathCount - 2].x - points[pathCount - 1].x;
+ diffZ = points[pathCount - 2].z - points[pathCount - 1].z;
+ } else {
+ diffX = points[currentPoint - 1].x - points[currentPoint + 1].x;
+ diffZ = points[currentPoint - 1].z - points[currentPoint + 1].z;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2D4C.s")
+ func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d);
+ if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) {
+ reached = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2E18.s")
+ return reached;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2F6C.s")
+f32 EnRuppecrow_GetPointDirection(Path* path, s32 pointIndex, PosRot* world, Vec3s* direction) {
+ Vec3s* points;
+ Vec3f point;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE30F4.s")
+ if (path != NULL) {
+ points = Lib_SegmentedToVirtual(path->points);
+ points = &points[pointIndex];
+ VEC_SET(point, points->x, points->y, points->z);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE3178.s")
+ direction->y = Math_Vec3f_Yaw(&world->pos, &point);
+ direction->x = Math_Vec3f_Pitch(&world->pos, &point);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE32DC.s")
+ return point.y - world->pos.y;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE3354.s")
+void EnRuppecrow_ShatterIce(EnRuppecrow* this, GlobalContext* globalCtx) {
+ if (this->currentEffect == ENRUPPECROW_EFFECT_ICE) {
+ this->currentEffect = ENRUPPECROW_EFFECT_NONE;
+ this->unk_2C8 = 0.0f;
+ func_800BF7CC(globalCtx, &this->actor, this->limbPos, ENRUPPECROW_LIMB_POS_COUNT, 0x2, 0.2f, 0.2f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE348C.s")
+s32 EnRuppecrow_CanSpawnBlueRupees(GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE35A4.s")
+ switch (player->transformation) {
+ case PLAYER_FORM_DEKU:
+ return false;
+ case PLAYER_FORM_GORON:
+ return true;
+ case PLAYER_FORM_ZORA:
+ return false;
+ case PLAYER_FORM_HUMAN:
+ if (player->stateFlags1 & 0x800000) {
+ return true;
+ } else {
+ return false;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Init.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Destroy.s")
+void EnRuppecrow_UpdateRupees(EnRuppecrow* this) {
+ EnItem00* rupee;
+ s16 rupeeIndex;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Update.s")
+ for (rupeeIndex = 0; rupeeIndex < ENRUPPECROW_RUPEE_COUNT; rupeeIndex++) {
+ rupee = this->rupees[rupeeIndex];
+ if (rupee != NULL && rupee->unk152 == 0) {
+ Actor_MarkForDeath(&rupee->actor);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Draw.s")
+void EnRuppecrow_SpawnRupee(EnRuppecrow* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ f32 xOffset;
+ EnItem00* rupee;
+ s16 rupeeIndex = this->rupeeIndex;
+
+ if (!(player->stateFlags3 & 0x1000)) {
+ xOffset = (this->rupeeIndex & 1) ? 10.0f : -10.0f;
+ } else {
+ xOffset = 0.0f;
+ }
+
+ if (EnRuppecrow_CanSpawnBlueRupees(globalCtx) && (this->rupeeIndex % 5) == 4) {
+ if (this->rupeeIndex == 19) {
+ rupee = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00,
+ this->actor.world.pos.x + xOffset, this->actor.world.pos.y,
+ this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_RED);
+ this->rupees[rupeeIndex] = rupee;
+ this->rupees[rupeeIndex]->actor.gravity = -5.0f;
+ this->rupees[rupeeIndex]->actor.velocity.y = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL);
+ rupee = this->rupees[rupeeIndex];
+ rupee->unk152 = 60;
+ this->rupees[rupeeIndex]->actor.flags |= 0x10;
+ } else {
+ rupee = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00,
+ this->actor.world.pos.x + xOffset, this->actor.world.pos.y,
+ this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_BLUE);
+ this->rupees[rupeeIndex] = rupee;
+ this->rupees[rupeeIndex]->actor.gravity = -5.0f;
+ this->rupees[rupeeIndex]->actor.velocity.y = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL);
+ rupee = this->rupees[rupeeIndex];
+ rupee->unk152 = 60;
+ this->rupees[rupeeIndex]->actor.flags |= 0x10;
+ }
+ } else if (this->rupeeIndex == 19) {
+ rupee =
+ (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, this->actor.world.pos.x + xOffset,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_RED);
+ this->rupees[rupeeIndex] = rupee;
+ this->rupees[rupeeIndex]->actor.gravity = -5.0f;
+ this->rupees[rupeeIndex]->actor.velocity.y = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL);
+ rupee = this->rupees[rupeeIndex];
+ rupee->unk152 = 60;
+ this->rupees[rupeeIndex]->actor.flags |= 0x10;
+ } else {
+ rupee =
+ (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, this->actor.world.pos.x + xOffset,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_GREEN);
+ this->rupees[rupeeIndex] = rupee;
+ this->rupees[rupeeIndex]->actor.gravity = -5.0f;
+ this->rupees[rupeeIndex]->actor.velocity.y = 0.0f;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL);
+ rupee = this->rupees[rupeeIndex];
+ rupee->unk152 = 60;
+ this->rupees[rupeeIndex]->actor.flags |= 0x10;
+ }
+
+ this->rupeeIndex++;
+}
+
+void EnRuppecrow_UpdatePosition(EnRuppecrow* this, GlobalContext* globalCtx) {
+ Vec3s nextPointDirection;
+
+ EnRuppecrow_GetPointDirection(this->path, this->currentPoint, &this->actor.world, &nextPointDirection);
+ if (this->actor.bgCheckFlags & 0x8) {
+ nextPointDirection.y = this->actor.wallYaw;
+ }
+
+ Math_SmoothStepToS(&this->actor.world.rot.y, nextPointDirection.y, 0x4, 0x3E8, 0x1);
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ Math_SmoothStepToS(&this->actor.world.rot.x, -nextPointDirection.x, 0x4, 0x3E8, 0x1);
+
+ if (this->isGoingCounterClockwise & 1) {
+ if (EnRuppecrow_ReachedPointCounterClockwise(this, this->path, this->currentPoint)) {
+ if (this->currentPoint <= 0) {
+ this->currentPoint = this->path->count - 1;
+ } else {
+ this->currentPoint--;
+ }
+
+ if (this->actionFunc == EnRuppecrow_FlyWhileDroppingRupees &&
+ (!EnRuppecrow_CanSpawnBlueRupees(globalCtx) || (this->currentPoint % -2) == 0)) {
+ EnRuppecrow_SpawnRupee(this, globalCtx);
+ }
+ }
+ } else if (EnRuppecrow_ReachedPointClockwise(this, this->path, this->currentPoint)) {
+ if (this->currentPoint >= this->path->count - 1) {
+ this->currentPoint = 0;
+ } else {
+ this->currentPoint++;
+ }
+
+ if (this->actionFunc == EnRuppecrow_FlyWhileDroppingRupees &&
+ (!EnRuppecrow_CanSpawnBlueRupees(globalCtx) || (this->currentPoint % -2) == 0)) {
+ EnRuppecrow_SpawnRupee(this, globalCtx);
+ }
+ }
+}
+
+s32 EnRuppecrow_CheckPlayedMatchingSong(GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (globalCtx->msgCtx.ocarinaMode == 3) {
+ switch (player->transformation) {
+ case PLAYER_FORM_DEKU:
+ if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_SONATA) {
+ return true;
+ }
+ break;
+ case PLAYER_FORM_GORON:
+ if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_GORON_LULLABY) {
+ return true;
+ }
+ break;
+ case PLAYER_FORM_ZORA:
+ if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_NEW_WAVE) {
+ return true;
+ }
+ break;
+ case PLAYER_FORM_HUMAN:
+ if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_SONATA) {
+ return true;
+ } else if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_GORON_LULLABY) {
+ return true;
+ } else if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_NEW_WAVE) {
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+}
+
+void EnRuppecrow_UpdateSpeed(EnRuppecrow* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ switch (player->transformation) {
+ case PLAYER_FORM_DEKU:
+ this->speedModifier = 7.0f;
+ break;
+ case PLAYER_FORM_GORON:
+ if (player->stateFlags3 & 0x1000) { // Goron Link is curled
+ this->speedModifier = 19.0f;
+ } else {
+ this->speedModifier = 7.0f;
+ }
+ break;
+ case PLAYER_FORM_ZORA:
+ this->speedModifier = 7.0f;
+ break;
+ case PLAYER_FORM_HUMAN:
+ if (player->stateFlags1 & 0x800000) {
+ this->speedModifier = 16.0f;
+ } else {
+ this->speedModifier = 7.0f;
+ }
+ break;
+ }
+
+ this->skelAnime.playSpeed = this->speedModifier / 6.0f;
+ if (this->actor.xzDistToPlayer > 800.0f) {
+ this->speedModifier *= 0.5f;
+ } else if (this->actor.xzDistToPlayer > 500.0f) {
+ this->speedModifier *= 0.8f;
+ } else if (this->actor.xzDistToPlayer < 150.0f) {
+ this->speedModifier *= 1.2f;
+ }
+}
+
+void EnRuppecrow_HandleDeath(EnRuppecrow* this) {
+ f32 scale;
+
+ this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x);
+ this->actor.velocity.y = 0.0f;
+ Animation_Change(&this->skelAnime, &object_crow_Anim_0000F0, 0.4f, 0.0f, 0.0f, 0x1, -3.0f);
+
+ this->actor.shape.yOffset = 0.0f;
+ this->actor.targetArrowOffset = 0.0f;
+ this->actor.bgCheckFlags &= ~0x1;
+
+ scale = this->actor.scale.x * 100.0f;
+ this->actor.world.pos.y += 20.0f * scale;
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_DEAD);
+
+ this->unk_2CC = 0.5f;
+ if (this->actor.colChkInfo.damageEffect == 0x3) {
+ this->currentEffect = ENRUPPECROW_EFFECT_ICE;
+ this->unk_2C8 = 1.0f;
+ this->iceSfxTimer = 0.75f;
+ } else if (this->actor.colChkInfo.damageEffect == 0x4) {
+ this->currentEffect = ENRUPPECROW_EFFECT_LIGHT;
+ this->unk_2C8 = 5.0f;
+ } else if (this->actor.colChkInfo.damageEffect == 0x2) {
+ this->currentEffect = ENRUPPECROW_EFFECT_NONE;
+ this->unk_2C8 = 5.0f;
+ }
+
+ func_800BCB70(&this->actor, 0x4000, 0xFF, 0x0, 0x28);
+ if (this->actor.flags & 0x8000) {
+ this->actor.speedXZ = 0.0f;
+ }
+
+ this->collider.base.acFlags &= ~AC_ON;
+ this->actor.flags |= 0x10;
+ this->actionFunc = EnRuppecrow_FallToDespawn;
+}
+
+void EnRuppecrow_UpdateDamage(EnRuppecrow* this, GlobalContext* globalCtx) {
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ func_800BE258(&this->actor, this->collider.elements);
+
+ if (this->actor.colChkInfo.damageEffect != 0x1) {
+ this->actor.colChkInfo.health = 0;
+ this->actor.flags &= ~0x1;
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ EnRuppecrow_HandleDeath(this);
+ }
+ }
+}
+
+void EnRuppecrow_HandleSong(EnRuppecrow* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ EnRuppecrow_UpdatePosition(this, globalCtx);
+ if (this->actor.xzDistToPlayer < 1000.0f && EnRuppecrow_CheckPlayedMatchingSong(globalCtx)) {
+ // If Link is in front, the guay will turn around and go the other way
+ if (Actor_IsActorFacingLink(&this->actor, 0x4000)) {
+ this->isGoingCounterClockwise |= 1;
+ if (this->currentPoint > 0) {
+ this->currentPoint--;
+ } else {
+ this->currentPoint = this->path->count - 1;
+ }
+ }
+
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ this->actionFunc = EnRuppecrow_HandleSongCutscene;
+ }
+
+ if (player->stateFlags2 & 0x8000000) {
+ Math_ApproachF(&this->actor.speedXZ, 0.0f, 0.1f, 1.0f);
+ } else {
+ Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.1f, 0.1f);
+ }
+
+ Actor_SetVelocityAndMoveXYRotation(&this->actor);
+ this->yOffset += 0x1000;
+ this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f;
+
+ if ((globalCtx->state.frames % 43) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY);
+ }
+}
+
+void EnRuppecrow_HandleSongCutscene(EnRuppecrow* this, GlobalContext* globalCtx) {
+ EnRuppecrow_UpdatePosition(this, globalCtx);
+
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ ActorCutscene_Start(this->actor.cutscene, &this->actor);
+ EnRuppecrow_UpdateSpeed(this, globalCtx);
+ this->actionFunc = EnRuppecrow_FlyWhileDroppingRupees;
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+
+ Actor_SetVelocityAndMoveXYRotation(&this->actor);
+}
+
+void EnRuppecrow_FlyWhileDroppingRupees(EnRuppecrow* this, GlobalContext* globalCtx) {
+ EnRuppecrow_UpdatePosition(this, globalCtx);
+
+ if (this->rupeeIndex >= ENRUPPECROW_RUPEE_COUNT) {
+ // Finished spawning rupees; fly up and then despawn
+ this->speedModifier = 6.0f;
+
+ // Source of the "Termina Field Guay Glitch"; guay will no longer fall if killed after this point
+ this->actor.gravity = 0.0f;
+
+ Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 0.5f);
+ Math_ApproachF(&this->actor.velocity.y, 3.0f, 0.2f, 0.5f);
+
+ this->actionFunc = EnRuppecrow_FlyToDespawn;
+ this->skelAnime.playSpeed = 1.0f;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ } else {
+ if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) {
+ EnRuppecrow_UpdateSpeed(this, globalCtx);
+ Math_ApproachF(&this->actor.speedXZ, this->speedModifier, 0.2f, 0.5f);
+ }
+
+ Actor_SetVelocityAndMoveXYRotation(&this->actor);
+ this->yOffset += 0x1000;
+ this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f;
+
+ if ((globalCtx->state.frames % 43) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY);
+ }
+ }
+}
+
+void EnRuppecrow_FlyToDespawn(EnRuppecrow* this, GlobalContext* globalCtx) {
+ if (this->actor.bgCheckFlags & 0x8) {
+ this->actor.world.rot.y *= -0x1;
+ }
+
+ Math_ApproachF(&this->actor.speedXZ, this->speedModifier, 0.1f, 0.1f);
+ Math_ApproachF(&this->actor.velocity.y, 3.0f, 0.2f, 0.5f);
+
+ if (this->actor.world.pos.y > 1000.0f || this->actor.xzDistToPlayer > 2000.0f) {
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ this->yOffset += 0x800;
+ this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f;
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+
+ if ((globalCtx->state.frames % 43) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY);
+ }
+ }
+}
+
+void EnRuppecrow_FallToDespawn(EnRuppecrow* this, GlobalContext* globalCtx) {
+ Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f);
+
+ if (this->currentEffect != ENRUPPECROW_EFFECT_ICE) {
+ Math_StepToF(&this->unk_2C8, 0.0f, 0.05f);
+ this->unk_2CC = (this->unk_2C8 + 1.0f) * 0.25f;
+ this->unk_2CC = CLAMP_MAX(this->unk_2CC, 0.5f);
+ } else if (!Math_StepToF(&this->iceSfxTimer, 0.5f, 0.0125f)) {
+ func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+
+ this->actor.colorFilterTimer = 40;
+ if (!(this->actor.flags & 0x8000)) {
+ if (this->currentEffect != ENRUPPECROW_EFFECT_ICE) {
+ Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200);
+ this->actor.shape.rot.z += 0x1780;
+ }
+
+ if (this->actor.bgCheckFlags & 0x1 || this->actor.floorHeight == BGCHECK_Y_MIN) {
+ EnRuppecrow_ShatterIce(this, globalCtx);
+ func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, (this->actor.scale.x * 10000.0f),
+ 0x0, 0x0);
+
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0xB, NA_SE_EN_EXTINCT);
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+ }
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+}
+
+void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx2) {
+ EnRuppecrow* this = THIS;
+ GlobalContext* globalCtx = globalCtx2;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_crow_Skel_0010C0, &object_crow_Anim_0000F0, this->joinTable,
+ this->morphTable, ENRUPPECROW_LIMB_COUNT);
+ ActorShape_Init(&this->actor.shape, 2000.0f, func_800B3FC0, 20.0f);
+
+ Collider_InitJntSph(globalCtx, &this->collider);
+ Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->colliderElement);
+ this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius;
+ CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+
+ Actor_SetScale(&this->actor, 0.01f);
+ this->actor.flags |= 0x2000000;
+
+ this->path = func_8013D648(globalCtx, ENRUPPECROW_GET_PATH(&this->actor), 0x3F);
+ if (this->path != NULL) {
+ this->actionFunc = EnRuppecrow_HandleSong;
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnRuppecrow_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnRuppecrow* this = THIS;
+
+ Collider_DestroyJntSph(globalCtx, &this->collider);
+}
+
+void EnRuppecrow_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnRuppecrow* this = THIS;
+
+ EnRuppecrow_UpdateDamage(this, globalCtx);
+ this->actionFunc(this, globalCtx);
+ EnRuppecrow_UpdateRupees(this);
+ this->actor.focus.pos = this->actor.world.pos;
+ SkelAnime_Update(&this->skelAnime);
+ EnRuppecrow_UpdateCollision(this, globalCtx);
+}
+
+void EnRuppecrow_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnRuppecrow* this = THIS;
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ NULL, NULL, &this->actor);
+}
diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h
index eeba6774d..4c9cafa67 100644
--- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h
+++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h
@@ -3,15 +3,38 @@
#include "global.h"
+#define ENRUPPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA)
+
+#define ENRUPPECROW_RUPEE_COUNT 20
+#define ENRUPPECROW_LIMB_COUNT 9
+#define ENRUPPECROW_LIMB_POS_COUNT 4
+
struct EnRuppecrow;
typedef void (*EnRuppecrowActionFunc)(struct EnRuppecrow*, GlobalContext*);
typedef struct EnRuppecrow {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x94];
- /* 0x01D8 */ EnRuppecrowActionFunc actionFunc;
- /* 0x01DC */ char unk_1DC[0x128];
+ /* 0x000 */ Actor actor;
+ /* 0x144 */ EnItem00* rupees[ENRUPPECROW_RUPEE_COUNT];
+ /* 0x194 */ SkelAnime skelAnime;
+ /* 0x1D8 */ EnRuppecrowActionFunc actionFunc;
+ /* 0x1DC */ UNK_TYPE4 unk_1DC; // unused
+ /* 0x1E0 */ Vec3s joinTable[ENRUPPECROW_LIMB_COUNT];
+ /* 0x216 */ Vec3s morphTable[ENRUPPECROW_LIMB_COUNT];
+ /* 0x24C */ Path* path;
+ /* 0x250 */ s32 currentPoint;
+ /* 0x254 */ ColliderJntSph collider;
+ /* 0x274 */ ColliderJntSphElement colliderElement;
+ /* 0x2B4 */ u16 isGoingCounterClockwise;
+ /* 0x2B8 */ f32 speedModifier;
+ /* 0x2BC */ s16 rupeeIndex;
+ /* 0x2BE */ s16 yOffset;
+ /* 0x2C0 */ UNK_TYPE4 unk_2C0; // unused
+ /* 0x2C4 */ u8 currentEffect;
+ /* 0x2C8 */ f32 unk_2C8; // set but not used
+ /* 0x2CC */ f32 unk_2CC; // set but not used
+ /* 0x2D0 */ f32 iceSfxTimer;
+ /* 0x2D4 */ Vec3f limbPos[ENRUPPECROW_LIMB_POS_COUNT];
} EnRuppecrow; // size = 0x304
extern const ActorInit En_Ruppecrow_InitVars;
diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
index 827491ee1..e1154d584 100644
--- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
+++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
@@ -5,6 +5,7 @@
*/
#include "z_en_ssh.h"
+#include "objects/object_ssh/object_ssh.h"
#define FLAGS 0x00000035
@@ -15,16 +16,15 @@ void EnSsh_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnSsh_Update(Actor* thisx, GlobalContext* globalCtx);
void EnSsh_Draw(Actor* thisx, GlobalContext* globalCtx);
-void func_809755C0(EnSsh* this, GlobalContext* globalCtx);
-void func_80975720(EnSsh* this, GlobalContext* globalCtx);
-void func_809758B0(EnSsh* this, GlobalContext* globalCtx);
-void func_80975998(EnSsh* this, GlobalContext* globalCtx);
-void func_80975A98(EnSsh* this, GlobalContext* globalCtx);
-void func_80975C14(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Wait(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Idle(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Land(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Drop(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Return(EnSsh* this, GlobalContext* globalCtx);
+void EnSsh_Start(EnSsh* this, GlobalContext* globalCtx);
-void EnSsh_SetupAction(EnSsh* this, EnSshActionFunc actionFunc);
+extern AnimationHeader D_06000304;
-#if 0
const ActorInit En_Ssh_InitVars = {
ACTOR_EN_SSH,
ACTORCAT_NPC,
@@ -37,139 +37,900 @@ const ActorInit En_Ssh_InitVars = {
(ActorFunc)EnSsh_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80976030 = {
- { COLTYPE_HIT6, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit1 = {
+ {
+ COLTYPE_HIT6,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 32, 50, -24, { 0, 0, 0 } },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_8097605C = { 1, 0, 0, 0, MASS_IMMOVABLE };
+static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE };
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80976068 = {
- { COLTYPE_HIT6, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit2 = {
+ {
+ COLTYPE_HIT6,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 20, 60, -30, { 0, 0, 0 } },
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_80976094[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x04 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 1, { { 0, -240, 0 }, 28 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_809760B8 = {
- { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, },
- 1, D_80976094, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_HIT6,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit,
};
-#endif
+void EnSsh_SetupAction(EnSsh* this, EnSshActionFunc actionFunc) {
+ this->actionFunc = actionFunc;
+}
-extern ColliderCylinderInit D_80976030;
-extern CollisionCheckInfoInit2 D_8097605C;
-extern ColliderCylinderInit D_80976068;
-extern ColliderJntSphElementInit D_80976094[1];
-extern ColliderJntSphInit D_809760B8;
+void EnSsh_SpawnShockwave(EnSsh* this, GlobalContext* globalCtx) {
+ Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ Vec3f pos;
-extern UNK_TYPE D_060000D8;
-extern UNK_TYPE D_06000304;
-extern UNK_TYPE D_06005850;
+ pos.x = this->actor.world.pos.x;
+ pos.y = this->actor.floorHeight;
+ pos.z = this->actor.world.pos.z;
+ EffectSsBlast_SpawnWhiteCustomScale(globalCtx, &pos, &zeroVec, &zeroVec, 100, 220, 8);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_SetupAction.s")
+s32 EnSsh_CreateBlureEffect(GlobalContext* globalCtx) {
+ EffectBlureInit1 blureInit;
+ u8 sP1StartColor[4] = { 255, 255, 255, 75 };
+ u8 sP2StartColor[4] = { 255, 255, 255, 75 };
+ u8 sP1EndColor[4] = { 255, 255, 255, 0 };
+ u8 sP2EndColor[4] = { 255, 255, 255, 0 };
+ s32 i;
+ s32 blureIdx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80973EFC.s")
+ for (i = 0; i < ARRAY_COUNT(blureInit.p1StartColor); i++) {
+ blureInit.p1StartColor[i] = sP1StartColor[i];
+ blureInit.p2StartColor[i] = sP2StartColor[i];
+ blureInit.p1EndColor[i] = sP1EndColor[i];
+ blureInit.p2EndColor[i] = sP2EndColor[i];
+ }
+ blureInit.elemDuration = 6;
+ blureInit.unkFlag = false;
+ blureInit.calcMode = 3;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80973F84.s")
+ Effect_Add(globalCtx, &blureIdx, 1, 0, 0, &blureInit);
+ return blureIdx;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974080.s")
+s32 EnSsh_CheckCeilingPos(EnSsh* this, GlobalContext* globalCtx) {
+ CollisionPoly* poly;
+ s32 bgId;
+ Vec3f posB;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974118.s")
+ posB.x = this->actor.world.pos.x;
+ posB.y = this->actor.world.pos.y + 1000.0f;
+ posB.z = this->actor.world.pos.z;
+ if (!BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &posB, &this->ceilingPos, &poly, 0, 0, 1,
+ 1, &bgId)) {
+ return false;
+ }
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974220.s")
+void EnSsh_AddBlureVertex(EnSsh* this) {
+ Vec3f p1Base = { 834.0f, 834.0f, 0.0f };
+ Vec3f p2Base = { 834.0f, -584.0f, 0.0f };
+ Vec3f p1;
+ Vec3f p2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097424C.s")
+ p1Base.x *= this->colliderScale;
+ p1Base.y *= this->colliderScale;
+ p1Base.z *= this->colliderScale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974374.s")
+ p2Base.x *= this->colliderScale;
+ p2Base.y *= this->colliderScale;
+ p2Base.z *= this->colliderScale;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744A8.s")
+ Matrix_StatePush();
+ Matrix_MultiplyVector3fByState(&p1Base, &p1);
+ Matrix_MultiplyVector3fByState(&p2Base, &p2);
+ Matrix_StatePop();
+ EffectBlure_AddVertex(Effect_GetByIndex(this->blureIdx), &p1, &p2);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744C8.s")
+void EnSsh_AddBlureSpace(EnSsh* this) {
+ EffectBlure_AddSpace(Effect_GetByIndex(this->blureIdx));
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744FC.s")
+void EnSsh_InitColliders(EnSsh* this, GlobalContext* globalCtx) {
+ ColliderCylinderInit* cylinders[] = {
+ &sCylinderInit1, &sCylinderInit1, &sCylinderInit1, &sCylinderInit2, &sCylinderInit2, &sCylinderInit2,
+ };
+ s32 i;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974540.s")
+ for (i = 0; i < ARRAY_COUNT(this->collider1); i++) {
+ Collider_InitAndSetCylinder(globalCtx, &this->collider1[i], &this->actor, cylinders[i]);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974590.s")
+ this->collider1[0].info.bumper.dmgFlags = 0x38A9;
+ this->collider1[1].info.bumper.dmgFlags = ~0x83038A9;
+ this->collider1[2].base.colType = COLTYPE_METAL;
+ this->collider1[2].info.bumperFlags = (BUMP_NO_AT_INFO | BUMP_HOOKABLE | BUMP_ON);
+ this->collider1[2].info.elemType = ELEMTYPE_UNK2;
+ this->collider1[2].info.bumper.dmgFlags = ~0x83038A9;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809745BC.s")
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(2), &sColChkInfoInit);
+ Collider_InitJntSph(globalCtx, &this->collider2);
+ Collider_SetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit, this->collider2Elements);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974730.s")
+f32 EnSsh_SetAnimation(EnSsh* this, s32 arg0) {
+ AnimationHeader* animation[] = { &object_ssh_Anim_006D78, &object_ssh_Anim_001494, &object_ssh_Anim_001494,
+ &object_ssh_Anim_006788, &object_ssh_Anim_001494, &object_ssh_Anim_001494,
+ &object_ssh_Anim_006D78 };
+ f32 playerbackSpeed[] = { 1.0f, 4.0f, 1.0f, 1.0f, 8.0f, 6.0f, 2.0f };
+ u8 mode[] = {
+ ANIMMODE_ONCE_INTERP, ANIMMODE_ONCE_INTERP, ANIMMODE_LOOP_INTERP, ANIMMODE_ONCE_INTERP,
+ ANIMMODE_LOOP_INTERP, ANIMMODE_LOOP_INTERP, ANIMMODE_LOOP_INTERP,
+ };
+ f32 frameCount = Animation_GetLastFrame(animation[arg0]);
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097480C.s")
+ Animation_Change(&this->skelAnime, animation[arg0], playerbackSpeed[arg0], 0.0f, frameCount, mode[arg0], -6.0f);
+ return frameCount;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809748DC.s")
+void EnSsh_SetWaitAnimation(EnSsh* this) {
+ EnSsh_SetAnimation(this, SSH_ANIM_WAIT);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097497C.s")
+void EnSsh_SetReturnAnimation(EnSsh* this) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_UP);
+ EnSsh_SetAnimation(this, SSH_ANIM_UP);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809749B8.s")
+void EnSsh_SetLandAnimation(EnSsh* this) {
+ this->actor.world.pos.y = this->floorHeightOffset + this->actor.floorHeight;
+ this->animTimer = EnSsh_SetAnimation(this, SSH_ANIM_LAND);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974A24.s")
+void EnSsh_SetDropAnimation(EnSsh* this) {
+ if (this->unkTimer == 0) {
+ this->animTimer = EnSsh_SetAnimation(this, SSH_ANIM_DROP);
+ }
+ this->actor.velocity.y = -10.0f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B0C.s")
+void EnSsh_SetStunned(EnSsh* this) {
+ if (this->stunTimer == 0) {
+ this->stateFlags |= SSH_STATE_ATTACKED;
+ this->stunTimer = 120;
+ this->actor.colorFilterTimer = 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B44.s")
+void EnSsh_SetColliderScale(EnSsh* this, f32 arg1, f32 arg2) {
+ s32 i;
+ f32 radius = this->collider2.elements[0].dim.modelSphere.radius;
+ f32 height;
+ f32 yShift;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B84.s")
+ radius *= arg1;
+ this->collider2.elements[0].dim.modelSphere.radius = radius;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974CC8.s")
+ for (i = 0; i < ARRAY_COUNT(this->collider1); i++) {
+ yShift = this->collider1[i].dim.yShift;
+ radius = this->collider1[i].dim.radius;
+ height = this->collider1[i].dim.height;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974D3C.s")
+ height *= arg1;
+ yShift *= arg1;
+ radius *= arg1 * arg2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974E44.s")
+ this->collider1[i].dim.yShift = yShift;
+ this->collider1[i].dim.radius = radius;
+ this->collider1[i].dim.height = height;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974EA0.s")
+ Actor_SetScale(&this->actor, 0.04f * arg1);
+ this->floorHeightOffset = 60.0f * arg1;
+ this->colliderScale = arg1 * 1.5f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974F78.s")
+s32 EnSsh_Damaged(EnSsh* this) {
+ if ((this->stunTimer == 120) && (this->stateFlags & SSH_STATE_STUNNED)) {
+ func_800BCB70(&this->actor, 0, 200, 0, this->stunTimer);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097502C.s")
+ if (DECR(this->stunTimer) != 0) {
+ Math_SmoothStepToS(&this->maxTurnRate, 10000, 10, 1000, 1);
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975070.s")
+ this->stunTimer = 0;
+ this->stateFlags &= ~SSH_STATE_STUNNED;
+ this->spinTimer = 0;
+ if (this->swayTimer == 0) {
+ this->spinTimer = 30;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975128.s")
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL);
+ Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_ATTACK);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975300.s")
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Init.s")
+void EnSsh_Turn(EnSsh* this, GlobalContext* globalCtx) {
+ if (this->hitTimer != 0) {
+ this->hitTimer--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Destroy.s")
+ if (DECR(this->spinTimer) != 0) {
+ this->actor.world.rot.y += (s16)(10000.0f * (this->spinTimer / 30.0f));
+ } else if ((this->swayTimer == 0) && (this->stunTimer == 0)) {
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 4, 10000, 1);
+ }
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809755C0.s")
+void EnSsh_Stunned(EnSsh* this, GlobalContext* globalCtx) {
+ if ((this->swayTimer == 0) && (this->stunTimer == 0)) {
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer ^ 0x8000, 4, this->maxTurnRate, 1);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097561C.s")
+ this->actor.shape.rot.y = this->actor.world.rot.y;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809756D0.s")
+ if (this->stunTimer < 30) {
+ if (this->stunTimer & 1) {
+ this->actor.shape.rot.y += 2000;
+ } else {
+ this->actor.shape.rot.y -= 2000;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975720.s")
+void EnSsh_UpdateYaw(EnSsh* this, GlobalContext* globalCtx) {
+ if (this->stunTimer != 0) {
+ EnSsh_Stunned(this, globalCtx);
+ } else {
+ EnSsh_Turn(this, globalCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809758B0.s")
+void EnSsh_Bob(EnSsh* this, GlobalContext* globalCtx) {
+ f32 bobVel = 0.5f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975998.s")
+ if (globalCtx->state.frames & 8) {
+ bobVel *= -1.0f;
+ }
+ Math_SmoothStepToF(&this->actor.velocity.y, bobVel, 0.4f, 1000.0f, 0.0f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975A98.s")
+s32 EnSsh_IsCloseToLink(EnSsh* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ f32 yDist;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975B6C.s")
+ if (this->stateFlags & SSH_STATE_GROUND_START) {
+ return true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975C14.s")
+ if (this->unkTimer != 0) {
+ return true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Update.s")
+ if (this->swayTimer != 0) {
+ return true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975DBC.s")
+ if (this->animTimer != 0) {
+ return true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975EB8.s")
+ if (this->actor.xzDistToPlayer > 160.0f) {
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Draw.s")
+ yDist = this->actor.world.pos.y - player->actor.world.pos.y;
+ if ((yDist < 0.0f) || (yDist > 400.0f)) {
+ return false;
+ }
+
+ if (player->actor.world.pos.y < this->actor.floorHeight) {
+ return false;
+ }
+
+ return true;
+}
+
+s32 EnSsh_IsCloseToHome(EnSsh* this) {
+ f32 vel = this->actor.velocity.y;
+ f32 nextY = this->actor.world.pos.y + vel * 2.0f;
+
+ if (this->actor.home.pos.y <= nextY) {
+ return true;
+ }
+ return false;
+}
+
+s32 EnSsh_IsCloseToGround(EnSsh* this) {
+ f32 vel = this->actor.velocity.y;
+ f32 nextY = this->actor.world.pos.y + vel * 2.0f;
+
+ if ((nextY - this->actor.floorHeight) <= this->floorHeightOffset) {
+ return true;
+ }
+ return false;
+}
+
+void EnSsh_Sway(EnSsh* this) {
+ Vec3f swayVecBase;
+ Vec3f swayVec;
+ f32 temp_f20;
+ s16 swayAngle;
+
+ if (this->swayTimer != 0) {
+ this->swayAngle += 1600;
+ this->swayTimer--;
+ if (this->swayTimer == 0) {
+ this->swayAngle = 0;
+ }
+
+ temp_f20 = (this->swayTimer * (1.0f / 6));
+ swayAngle = Math_SinS(this->swayAngle) * (temp_f20 * (0x10000 / 360.0f));
+ temp_f20 = this->actor.world.pos.y - this->ceilingPos.y;
+
+ swayVecBase.x = Math_SinS(swayAngle) * temp_f20;
+ swayVecBase.y = Math_CosS(swayAngle) * temp_f20;
+ swayVecBase.z = 0.0f;
+
+ Matrix_StatePush();
+ Matrix_InsertTranslation(this->ceilingPos.x, this->ceilingPos.y, this->ceilingPos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(this->actor.world.rot.y * (M_PI / 0x8000), MTXMODE_APPLY);
+ Matrix_MultiplyVector3fByState(&swayVecBase, &swayVec);
+ Matrix_StatePop();
+
+ this->actor.shape.rot.z = -(swayAngle * 2);
+ this->actor.world.pos.x = swayVec.x;
+ this->actor.world.pos.z = swayVec.z;
+ }
+}
+
+void EnSsh_CheckBodyStickHit(EnSsh* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ ColliderInfo* colliderInfo = &this->collider1[0].info;
+
+ if (player->unk_B28 != 0) {
+ colliderInfo->bumper.dmgFlags |= 2;
+ this->collider1[1].info.bumper.dmgFlags &= ~2;
+ this->collider1[2].info.bumper.dmgFlags &= ~2;
+ } else {
+ colliderInfo->bumper.dmgFlags &= ~2;
+ this->collider1[1].info.bumper.dmgFlags |= 2;
+ this->collider1[2].info.bumper.dmgFlags |= 2;
+ }
+}
+
+s32 EnSsh_CheckHitPlayer(EnSsh* this, GlobalContext* globalCtx) {
+ s32 i;
+ s32 hit = false;
+
+ if ((this->hitCount == 0) && (this->spinTimer == 0)) {
+ return false;
+ }
+
+ for (i = 0; i < ARRAY_COUNT(this->collider1) / 2; i++) {
+ if (this->collider1[3 + i].base.ocFlags2 & OC2_HIT_PLAYER) {
+ this->collider1[3 + i].base.ocFlags2 &= ~OC2_HIT_PLAYER;
+ hit = true;
+ }
+ }
+
+ if (!hit) {
+ return false;
+ }
+
+ this->hitTimer = 30;
+ if (this->swayTimer == 0) {
+ this->spinTimer = this->hitTimer;
+ }
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL);
+ Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_ATTACK);
+
+ globalCtx->damagePlayer(globalCtx, -8);
+
+ func_800B8D98(globalCtx, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f);
+ this->hitCount--;
+ return true;
+}
+
+s32 EnSsh_CheckHitFront(EnSsh* this) {
+ u32 acFlags;
+
+ if (this->collider1[2].base.acFlags) {}
+ acFlags = this->collider1[2].base.acFlags;
+
+ if (!!(acFlags & AC_HIT) == 0) {
+ return false;
+ }
+
+ this->collider1[2].base.acFlags &= ~AC_HIT;
+ this->invincibilityTimer = 8;
+
+ if ((this->swayTimer == 0) && (this->hitTimer == 0) && (this->stunTimer == 0)) {
+ this->swayTimer = 60;
+ }
+
+ return true;
+}
+
+s32 EnSsh_CheckHitBack(EnSsh* this, GlobalContext* globalCtx) {
+ ColliderCylinder* collider = &this->collider1[0];
+ s32 hit = false;
+
+ if (collider->base.acFlags & AC_HIT) {
+ collider->base.acFlags &= ~AC_HIT;
+ hit = true;
+ }
+
+ collider = &this->collider1[1];
+ if (collider->base.acFlags & AC_HIT) {
+ collider->base.acFlags &= ~AC_HIT;
+ hit = true;
+ }
+
+ if (!hit) {
+ return false;
+ }
+
+ this->invincibilityTimer = 8;
+ if (this->hitCount <= 0) {
+ this->hitCount++;
+ }
+
+ if (this->stunTimer == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_DAMAGE);
+ }
+
+ EnSsh_SetStunned(this);
+ this->stateFlags |= SSH_STATE_STUNNED;
+ return false;
+}
+
+s32 EnSsh_CollisionCheck(EnSsh* this, GlobalContext* globalCtx) {
+ if (this->stunTimer == 0) {
+ EnSsh_CheckHitPlayer(this, globalCtx);
+ }
+
+ if (EnSsh_CheckHitFront(this)) {
+ return false;
+ }
+
+ if (globalCtx->actorCtx.unk2 != 0) {
+ this->invincibilityTimer = 8;
+ if (this->stunTimer == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_DAMAGE);
+ }
+ EnSsh_SetStunned(this);
+ this->stateFlags |= SSH_STATE_STUNNED;
+ return false;
+ }
+
+ return EnSsh_CheckHitBack(this, globalCtx);
+}
+
+void EnSsh_SetBodyCylinderAC(EnSsh* this, GlobalContext* globalCtx) {
+ Collider_UpdateCylinder(&this->actor, &this->collider1[0]);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[0].base);
+}
+
+void EnSsh_SetLegsCylinderAC(EnSsh* this, GlobalContext* globalCtx) {
+ s16 angleTowardsLink = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y));
+
+ if (angleTowardsLink < (90 * (0x10000 / 360))) {
+ Collider_UpdateCylinder(&this->actor, &this->collider1[2]);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[2].base);
+ } else {
+ Collider_UpdateCylinder(&this->actor, &this->collider1[1]);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[1].base);
+ }
+}
+
+s32 EnSsh_SetCylinderOC(EnSsh* this, GlobalContext* globalCtx) {
+ Vec3f colliderOffsets[] = { { 40.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { -40.0f, 0.0f, 0.0f } };
+ Vec3f colliderPos;
+ s32 i;
+
+ for (i = 0; i < ARRAY_COUNT(this->collider1) / 2; i++) {
+ colliderPos = this->actor.world.pos;
+
+ colliderOffsets[i].x *= this->colliderScale;
+ colliderOffsets[i].y *= this->colliderScale;
+ colliderOffsets[i].z *= this->colliderScale;
+
+ Matrix_StatePush();
+ Matrix_InsertTranslation(colliderPos.x, colliderPos.y, colliderPos.z, MTXMODE_NEW);
+ Matrix_InsertYRotation_f(BINANG_TO_RAD(this->initialYaw), MTXMODE_APPLY);
+ Matrix_MultiplyVector3fByState(&colliderOffsets[i], &colliderPos);
+ Matrix_StatePop();
+
+ this->collider1[3 + i].dim.pos.x = colliderPos.x;
+ this->collider1[3 + i].dim.pos.y = colliderPos.y;
+ this->collider1[3 + i].dim.pos.z = colliderPos.z;
+
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1[3 + i].base);
+ }
+
+ return true;
+}
+
+void EnSsh_SetColliders(EnSsh* this, GlobalContext* globalCtx) {
+ if (this->actor.colChkInfo.health == 0) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ return;
+ }
+
+ if (this->hitTimer == 0) {
+ EnSsh_SetCylinderOC(this, globalCtx);
+ }
+
+ if (DECR(this->invincibilityTimer) == 0) {
+ EnSsh_SetBodyCylinderAC(this, globalCtx);
+ EnSsh_SetLegsCylinderAC(this, globalCtx);
+ }
+}
+
+void EnSsh_Init(Actor* thisx, GlobalContext* globalCtx) {
+ // @bug - this symbol no longer exists, reads from a random place in object_ssh_Tex_000190 instead
+ f32 frameCount = Animation_GetLastFrame(&D_06000304);
+ s32 pad;
+ EnSsh* this = THIS;
+
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &object_ssh_Skel_006470, NULL, this->jointTable, this->morphtable, 30);
+ Animation_Change(&this->skelAnime, &object_ssh_Anim_001494, 1.0f, 0.0f, frameCount, ANIMMODE_LOOP_INTERP, 0.0f);
+ this->blureIdx = EnSsh_CreateBlureEffect(globalCtx);
+ EnSsh_InitColliders(this, globalCtx);
+ this->stateFlags = 0;
+ this->hitCount = 0;
+ EnSsh_CheckCeilingPos(this, globalCtx);
+
+ if (!ENSSH_IS_CHILD(&this->actor)) {
+ this->stateFlags |= SSH_STATE_FATHER;
+ }
+
+ if (!(this->stateFlags & SSH_STATE_FATHER)) {
+ EnSsh_SetColliderScale(this, 0.5f, 1.0f);
+ } else {
+ EnSsh_SetColliderScale(this, 0.75f, 1.0f);
+ }
+
+ this->actor.gravity = 0.0f;
+ this->initialYaw = this->actor.world.rot.y;
+ EnSsh_SetupAction(this, EnSsh_Start);
+ if (func_8012F22C(globalCtx->sceneNum) >= 30) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnSsh_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnSsh* this = THIS;
+ s32 i;
+
+ Effect_Destroy(globalCtx, this->blureIdx);
+
+ for (i = 0; i < ARRAY_COUNT(this->collider1); i++) {
+ Collider_DestroyCylinder(globalCtx, &this->collider1[i]);
+ }
+
+ Collider_DestroyJntSph(globalCtx, &this->collider2);
+}
+
+void EnSsh_Wait(EnSsh* this, GlobalContext* globalCtx) {
+ if (EnSsh_IsCloseToLink(this, globalCtx)) {
+ EnSsh_SetDropAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Drop);
+ } else {
+ EnSsh_Bob(this, globalCtx);
+ }
+}
+
+void EnSsh_Talk(EnSsh* this, GlobalContext* globalCtx) {
+ EnSsh_Bob(this, globalCtx);
+
+ if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) {
+ switch (globalCtx->msgCtx.unk11F04) {
+ case 0x904:
+ case 0x905:
+ case 0x906:
+ case 0x908:
+ case 0x910:
+ case 0x911:
+ case 0x912:
+ case 0x914:
+ func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1);
+ break;
+
+ default:
+ func_801477B4(globalCtx);
+ this->actionFunc = EnSsh_Idle;
+ break;
+ }
+ }
+}
+
+void func_809756D0(EnSsh* this, GlobalContext* globalCtx) {
+ u16 phi_a1;
+
+ if (gSaveContext.save.weekEventReg[34] & 8) {
+ phi_a1 = 0x914;
+ } else {
+ phi_a1 = 0x910;
+ gSaveContext.save.weekEventReg[34] |= 8;
+ }
+ func_801518B0(globalCtx, phi_a1, &this->actor);
+}
+
+void EnSsh_Idle(EnSsh* this, GlobalContext* globalCtx) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ this->actionFunc = EnSsh_Talk;
+ func_809756D0(this, globalCtx);
+ return;
+ }
+
+ if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) {
+ EnSsh_SetAnimation(this, SSH_ANIM_WAIT);
+ }
+
+ if ((this->animTimer != 0) && (DECR(this->animTimer) == 0)) {
+ EnSsh_SetAnimation(this, SSH_ANIM_WAIT);
+ }
+
+ if (!EnSsh_IsCloseToLink(this, globalCtx)) {
+ EnSsh_SetReturnAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Return);
+ return;
+ }
+
+ if (DECR(this->sfxTimer) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_LAUGH);
+ this->sfxTimer = 64;
+ }
+
+ EnSsh_Bob(this, globalCtx);
+
+ if ((this->unkTimer == 0) && (this->animTimer == 0) && (this->actor.xzDistToPlayer < 100.0f) &&
+ Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx)) {
+ func_800B8614(&this->actor, globalCtx, 100.0f);
+ }
+}
+
+void EnSsh_Land(EnSsh* this, GlobalContext* globalCtx) {
+ if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) {
+ EnSsh_SetAnimation(this, SSH_ANIM_WAIT);
+ }
+
+ if ((this->animTimer != 0) && (DECR(this->animTimer) == 0)) {
+ EnSsh_SetAnimation(this, SSH_ANIM_WAIT);
+ }
+
+ if ((this->actor.floorHeight + this->floorHeightOffset) <= this->actor.world.pos.y) {
+ EnSsh_SetupAction(this, EnSsh_Idle);
+ } else {
+ Math_SmoothStepToF(&this->actor.velocity.y, 2.0f, 0.6f, 1000.0f, 0.0f);
+ }
+}
+
+void EnSsh_Drop(EnSsh* this, GlobalContext* globalCtx) {
+ if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) {
+ EnSsh_SetAnimation(this, SSH_ANIM_DROP);
+ }
+
+ if (!EnSsh_IsCloseToLink(this, globalCtx)) {
+ EnSsh_SetReturnAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Return);
+ } else if (EnSsh_IsCloseToGround(this)) {
+ EnSsh_SpawnShockwave(this, globalCtx);
+ EnSsh_SetLandAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Land);
+ } else if (DECR(this->sfxTimer) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_DOWN);
+ this->sfxTimer = 3;
+ }
+}
+
+void EnSsh_Return(EnSsh* this, GlobalContext* globalCtx) {
+ f32 frameRatio = this->skelAnime.curFrame / (this->skelAnime.animLength - 1.0f);
+
+ if (frameRatio == 1.0f) {
+ EnSsh_SetReturnAnimation(this);
+ }
+
+ if (EnSsh_IsCloseToLink(this, globalCtx)) {
+ EnSsh_SetDropAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Drop);
+ } else if (EnSsh_IsCloseToHome(this)) {
+ EnSsh_SetWaitAnimation(this);
+ EnSsh_SetupAction(this, EnSsh_Wait);
+ } else {
+ this->actor.velocity.y = 4.0f * frameRatio;
+ }
+}
+
+void EnSsh_UpdateColliderScale(EnSsh* this) {
+ if (this->stateFlags & SSH_STATE_SPIN) {
+ if (this->spinTimer == 0) {
+ this->stateFlags &= ~SSH_STATE_SPIN;
+ if (!(this->stateFlags & SSH_STATE_FATHER)) {
+ EnSsh_SetColliderScale(this, 0.5f, 1.0f);
+ } else {
+ EnSsh_SetColliderScale(this, 0.75f, 1.0f);
+ }
+ }
+ } else if (this->spinTimer != 0) {
+ this->stateFlags |= SSH_STATE_SPIN;
+ if (!(this->stateFlags & SSH_STATE_FATHER)) {
+ EnSsh_SetColliderScale(this, 0.5f, 2.0f);
+ } else {
+ EnSsh_SetColliderScale(this, 0.75f, 2.0f);
+ }
+ }
+}
+
+void EnSsh_Start(EnSsh* this, GlobalContext* globalCtx) {
+ if (!EnSsh_IsCloseToGround(this)) {
+ EnSsh_SetupAction(this, EnSsh_Wait);
+ EnSsh_Wait(this, globalCtx);
+ } else {
+ EnSsh_SetLandAnimation(this);
+ this->stateFlags |= SSH_STATE_GROUND_START;
+ EnSsh_SetupAction(this, EnSsh_Land);
+ EnSsh_Land(this, globalCtx);
+ }
+}
+
+void EnSsh_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnSsh* this = THIS;
+
+ EnSsh_UpdateColliderScale(this);
+
+ if (EnSsh_CollisionCheck(this, globalCtx)) {
+ return;
+ }
+
+ if (this->stunTimer != 0) {
+ EnSsh_Damaged(this);
+ } else {
+ SkelAnime_Update(&this->skelAnime);
+ Actor_ApplyMovement(&this->actor);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
+ this->actionFunc(this, globalCtx);
+ }
+
+ EnSsh_UpdateYaw(this, globalCtx);
+
+ if (DECR(this->blinkTimer) == 0) {
+ this->blinkTimer = Rand_S16Offset(60, 60);
+ }
+
+ this->blinkState = this->blinkTimer;
+ if (this->blinkState >= 3) {
+ this->blinkState = 0;
+ }
+
+ EnSsh_SetColliders(this, globalCtx);
+ Actor_SetHeight(&this->actor, 0.0f);
+}
+
+s32 EnSsh_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnSsh* this = THIS;
+
+ switch (limbIndex) {
+ case 1:
+ if ((this->spinTimer != 0) && (this->swayTimer == 0)) {
+ if (this->spinTimer >= 2) {
+ EnSsh_AddBlureVertex(this);
+ } else {
+ EnSsh_AddBlureSpace(this);
+ }
+ }
+ break;
+
+ case 4:
+ if (this->stateFlags & SSH_STATE_FATHER) {
+ *dList = object_ssh_DL_005850;
+ }
+ break;
+
+ case 5:
+ if (this->stateFlags & SSH_STATE_FATHER) {
+ *dList = object_ssh_DL_005210;
+ }
+ break;
+
+ case 8:
+ if (this->stateFlags & SSH_STATE_FATHER) {
+ *dList = object_ssh_DL_005F78;
+ }
+ break;
+ }
+ return false;
+}
+
+void EnSsh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ EnSsh* this = THIS;
+
+ if ((limbIndex == 5) && (this->stateFlags & SSH_STATE_FATHER)) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ gSPDisplayList(POLY_OPA_DISP++, object_ssh_DL_0000D8);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+ Collider_UpdateSpheres(limbIndex, &this->collider2);
+}
+
+void EnSsh_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ static TexturePtr D_80976178[] = { object_ssh_Tex_001970, object_ssh_Tex_001DF0, object_ssh_Tex_0021F0 };
+ s32 pad;
+ EnSsh* this = THIS;
+
+ EnSsh_CheckBodyStickHit(this, globalCtx);
+ EnSsh_Sway(this);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80976178[this->blinkState]));
+
+ SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnSsh_OverrideLimbDraw,
+ EnSsh_PostLimbDraw, &this->actor);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
index 7d081f88c..172ecf0a5 100644
--- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
+++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
@@ -7,11 +7,53 @@ struct EnSsh;
typedef void (*EnSshActionFunc)(struct EnSsh*, GlobalContext*);
+#define SSH_STATE_STUNNED (1 << 0)
+#define SSH_STATE_GROUND_START (1 << 2)
+#define SSH_STATE_ATTACKED (1 << 3)
+#define SSH_STATE_SPIN (1 << 4)
+#define SSH_STATE_FATHER (1 << 5)
+
+typedef enum {
+ SSH_ANIM_UNK0, // Unused animation. Possibly being knocked back?
+ SSH_ANIM_UP,
+ SSH_ANIM_WAIT,
+ SSH_ANIM_LAND,
+ SSH_ANIM_DROP,
+ SSH_ANIM_UNK5, // Slower version of ANIM_DROP
+ SSH_ANIM_UNK6 // Faster repeating version of ANIM_UNK0
+} EnSshAnimation;
+
+#define ENSSH_IS_CHILD(thisx) ((thisx)->params & 0xF)
+
typedef struct EnSsh {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x1AC];
+ /* 0x0144 */ SkelAnime skelAnime;
+ /* 0x0188 */ Vec3s jointTable[30];
+ /* 0x023C */ Vec3s morphtable[30];
/* 0x02F0 */ EnSshActionFunc actionFunc;
- /* 0x02F4 */ char unk_2F4[0x2D8];
+ /* 0x02F4 */ ColliderCylinder collider1[6];
+ /* 0x04BC */ ColliderJntSph collider2;
+ /* 0x04DC */ ColliderJntSphElement collider2Elements[1];
+ /* 0x051C */ s16 initialYaw;
+ /* 0x051E */ s16 maxTurnRate;
+ /* 0x0520 */ s16 unkTimer;
+ /* 0x0522 */ s16 spinTimer;
+ /* 0x0524 */ s16 hitTimer;
+ /* 0x0526 */ s16 invincibilityTimer;
+ /* 0x0528 */ s16 sfxTimer;
+ /* 0x052A */ s16 stunTimer;
+ /* 0x052C */ s16 animTimer;
+ /* 0x052E */ s16 swayTimer;
+ /* 0x0530 */ s32 blureIdx;
+ /* 0x0534 */ f32 colliderScale;
+ /* 0x0538 */ f32 floorHeightOffset;
+ /* 0x053C */ Vec3f ceilingPos;
+ /* 0x0548 */ UNK_TYPE1 unk_548[0x78];
+ /* 0x05C0 */ s16 swayAngle;
+ /* 0x05C2 */ u16 stateFlags;
+ /* 0x05C4 */ u8 hitCount;
+ /* 0x05C6 */ s16 blinkState;
+ /* 0x05C8 */ s16 blinkTimer;
} EnSsh; // size = 0x5CC
extern const ActorInit En_Ssh_InitVars;
diff --git a/src/overlays/actors/ovl_En_St/z_en_st.c b/src/overlays/actors/ovl_En_St/z_en_st.c
index c8335d92c..9798a9e6d 100644
--- a/src/overlays/actors/ovl_En_St/z_en_st.c
+++ b/src/overlays/actors/ovl_En_St/z_en_st.c
@@ -5,6 +5,8 @@
*/
#include "z_en_st.h"
+#include "objects/object_st/object_st.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x01004035
@@ -19,8 +21,8 @@ void func_808A6C04(EnSt* this, GlobalContext* globalCtx);
void func_808A6D84(EnSt* this, GlobalContext* globalCtx);
void func_808A6E24(EnSt* this, GlobalContext* globalCtx);
void func_808A701C(EnSt* this, GlobalContext* globalCtx);
+void func_808A7478(Actor* thisx, GlobalContext* globalCtx);
-#if 0
const ActorInit En_St_InitVars = {
ACTOR_EN_ST,
ACTORCAT_ENEMY,
@@ -33,39 +35,89 @@ const ActorInit En_St_InitVars = {
(ActorFunc)NULL,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_808A75B0 = {
- { COLTYPE_HIT2, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x800C3829, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit1 = {
+ {
+ COLTYPE_HIT2,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ { 0x800C3829, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 18, 48, -20, { 0, 0, 0 } },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_808A75DC = {
- { COLTYPE_HIT2, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x77C3C7D6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit2 = {
+ {
+ COLTYPE_HIT2,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x77C3C7D6, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 18, 48, -20, { 0, 0, 0 } },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_808A7608 = {
- { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x77C3C7D6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit3 = {
+ {
+ COLTYPE_METAL,
+ AT_NONE,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK2,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x77C3C7D6, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 18, 48, -20, { 0, 0, 0 } },
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_808A7634 = {
- { COLTYPE_HIT2, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x800C3829, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit4 = {
+ {
+ COLTYPE_HIT2,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x800C3829, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 18, 48, -20, { 0, 0, 0 } },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_808A7660 = { 2, 0, 0, 0, MASS_IMMOVABLE };
+static CollisionCheckInfoInit2 sColChkInfoInit = { 2, 0, 0, 0, MASS_IMMOVABLE };
-// static DamageTable sDamageTable = {
-static DamageTable D_808A766C = {
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x1),
/* Deku Stick */ DMG_ENTRY(1, 0x0),
/* Horse trample */ DMG_ENTRY(0, 0x0),
@@ -100,73 +152,791 @@ static DamageTable D_808A766C = {
/* Powder Keg */ DMG_ENTRY(1, 0x0),
};
-#endif
+static ActorAnimationEntryS sAnimations[] = {
+ { &object_st_Anim_000304, 1.0f, 0, -1, 0, 0 }, { &object_st_Anim_005B98, 1.0f, 0, -1, 2, -4 },
+ { &object_st_Anim_000304, 4.0f, 0, -1, 2, -4 }, { &object_st_Anim_000304, 1.0f, 0, -1, 0, -4 },
+ { &object_st_Anim_0055A8, 1.0f, 0, -1, 2, -4 }, { &object_st_Anim_000304, 8.0f, 0, -1, 0, -4 },
+ { &object_st_Anim_000304, 6.0f, 0, -1, 2, -4 }, { &object_st_Anim_005B98, 2.0f, 0, -1, 0, -4 },
+};
-extern ColliderCylinderInit D_808A75B0;
-extern ColliderCylinderInit D_808A75DC;
-extern ColliderCylinderInit D_808A7608;
-extern ColliderCylinderInit D_808A7634;
-extern CollisionCheckInfoInit2 D_808A7660;
-extern DamageTable D_808A766C;
+void func_808A5050(EnSt* this, GlobalContext* globalCtx) {
+ static Color_RGBA8 D_808A770C = { 170, 130, 90, 255 };
+ static Color_RGBA8 D_808A7710 = { 100, 60, 20, 0 };
+ s32 i;
+ Vec3f spB8;
+ Vec3f spAC;
+ Vec3f spA0;
+ Vec3f sp94;
+ s32 rand;
+ s16 temp_s0 = (Rand_ZeroOne() - 0.5f) * 0x10000;
-extern UNK_TYPE D_06005298;
+ spA0.y = this->actor.floorHeight;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5050.s")
+ for (i = 0; i < 16; i++, temp_s0 += 0xFFF) {
+ rand = (Rand_ZeroOne() * 4.0f) + 8.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A52A8.s")
+ sp94.x = 0.0f;
+ sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f;
+ sp94.z = Rand_ZeroOne() + 1.0f;
+ Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC);
+ sp94.x = 0.0f;
+ sp94.y = 1.0f;
+ sp94.z = 5.0f;
+ Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A54B0.s")
+ spA0.x = this->actor.world.pos.x + (2.0f * spB8.x);
+ spA0.z = this->actor.world.pos.z + (2.0f * spB8.z);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A576C.s")
+ func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808A770C, &D_808A7710, 100, 40, rand);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5988.s")
+ spA0.x = this->actor.world.pos.x;
+ spA0.z = this->actor.world.pos.z;
+ spA0.y = this->actor.floorHeight;
+ EffectSsBlast_SpawnWhiteCustomScale(globalCtx, &spA0, &gZeroVec3f, &gZeroVec3f, 100, 220, 8);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5AF8.s")
+void func_808A52A8(EnSt* this, GlobalContext* globalCtx) {
+ static Color_RGBA8 D_808A7714 = { 170, 130, 90, 255 };
+ static Color_RGBA8 D_808A7718 = { 100, 60, 20, 0 };
+ s32 pad;
+ Vec3f spB8;
+ Vec3f spAC;
+ Vec3f spA0;
+ Vec3f sp94;
+ s32 i;
+ s16 temp_s0 = (Rand_ZeroOne() - 0.5f) * 0x10000;
+ s32 rand;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5BEC.s")
+ spA0.y = this->actor.floorHeight;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5CCC.s")
+ for (i = 0; i < 8; i++, temp_s0 += 0x1FFE) {
+ rand = (Rand_ZeroOne() * 4.0f) + 8.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5D7C.s")
+ sp94.x = 0.0f;
+ sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f;
+ sp94.z = Rand_ZeroOne() + 1.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5DCC.s")
+ Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5F28.s")
+ sp94.x = 0.0f;
+ sp94.y = 1.0f;
+ sp94.z = 4.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6064.s")
+ Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A60E0.s")
+ spA0.x = this->actor.world.pos.x + (2.0f * spB8.x);
+ spA0.z = this->actor.world.pos.z + (2.0f * spB8.z);
+ func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808A7714, &D_808A7718, 100, 40, rand);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A61F4.s")
+void func_808A54B0(EnSt* this, GlobalContext* globalCtx) {
+ s32 pad;
+ f32 temp_f0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6220.s")
+ if ((this->unk_18C & 1) && (this->actor.colChkInfo.health != 0)) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A63E8.s")
+ gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[this->unk_2C0].segment);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6468.s")
+ gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[this->unk_2C0].segment);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A650C.s")
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ Matrix_Scale(0.06f, 0.12f, 0.06f, MTXMODE_APPLY);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6580.s")
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 195, 0, 0x40, 0x20, 1, 215, 0, 8, 8));
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6A3C.s")
+ temp_f0 = (f32)this->unk_310 / 8;
+ if (temp_f0 > 1.0f) {
+ temp_f0 = 1.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6A78.s")
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, (u8)(255 * temp_f0));
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_025850);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_025970);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6C04.s")
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6D84.s")
+s32 func_808A576C(EnSt* this) {
+ s32 i;
+ s16 phi_s2 = (s16)((s16)(Rand_ZeroOne() * 1000.0f) % 12) * 0x1555;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6E24.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++, phi_s2 += 0x1555) {
+ if (this->unk_18E != 10) {
+ this->unk_31C[i] = (Rand_ZeroOne() * 16.0f) + 8.0f;
+ } else {
+ this->unk_31C[i] = 80;
+ }
+ this->unk_334[i] = this->unk_31C[i];
+ this->unk_2DC[i] = 0.90000004f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A701C.s")
+ if ((this->unk_18E == 0) || (this->unk_18E == 1)) {
+ this->unk_358[i].y = ((Rand_ZeroOne() - 0.5f) * 40.0f) - 10.0f;
+ } else {
+ this->unk_358[i].y = ((Rand_ZeroOne() - 0.5f) * 30.0f) + 10.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Init.s")
+ this->unk_358[i].x = Math_SinS(phi_s2) * 18.0f;
+ this->unk_358[i].z = Math_CosS(phi_s2) * 18.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Destroy.s")
+ this->unk_31A = 1;
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Update.s")
+s32 func_808A5988(EnSt* this, GlobalContext* globalCtx, s32 arg2) {
+ s32 ret = false;
+ u8 sp53;
+ Vec3f sp44;
+ f32 sp40;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A73E8.s")
+ if (arg2 < this->unk_31A) {
+ if (this->unk_31C[arg2] != 0) {
+ sp40 = (f32)this->unk_31C[arg2] / this->unk_334[arg2];
+ sp53 = this->unk_18E;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A7478.s")
+ Math_ApproachF(&this->unk_2DC[arg2], 0.6f, 0.3f, 0.5f);
+ Math_Vec3f_Copy(&sp44, &this->actor.world.pos);
+
+ sp44.x += this->unk_358[arg2].x;
+ sp44.y += this->unk_358[arg2].y;
+ sp44.z += this->unk_358[arg2].z;
+
+ if (sp53 == 10) {
+ if ((this->unk_334[arg2] - this->unk_31C[arg2]) < 20) {
+ sp53 = 11;
+ }
+ sp40 = 1.0f;
+ }
+ func_800BE680(globalCtx, &this->actor, &sp44, 1, 0.6f, this->unk_2DC[arg2], sp40, sp53);
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+void func_808A5AF8(EnSt* this, GlobalContext* globalCtx) {
+ Vec3f sp54;
+ s32 i;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_358); i++) {
+ Math_Vec3f_Copy(&sp54, &this->actor.world.pos);
+ sp54.x += this->unk_358[i].x;
+ sp54.y += this->unk_358[i].y;
+ sp54.z += this->unk_358[i].z;
+ Math_Vec3f_Copy(&this->unk_358[i], &sp54);
+ }
+ func_800BF7CC(globalCtx, &this->actor, this->unk_358, 12, 3, 0.1f, 0.3f);
+}
+
+s16 func_808A5BEC(EnSt* this) {
+ s16 ret;
+
+ if (!(this->unk_18C & 4) || (this->actor.xzDistToPlayer > 180.0f)) {
+ ret = this->actor.home.rot.y;
+ } else {
+ ret = this->actor.yawTowardsPlayer;
+ if (DECR(this->unk_30E) == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL);
+ this->unk_18C ^= 2;
+ this->unk_310 = 8;
+ if (this->unk_18C & 1) {
+ this->unk_310 *= 2;
+ }
+ this->unk_30E = 30;
+ }
+
+ if (this->unk_18C & 2) {
+ ret = BINANG_ROT180(ret);
+ }
+ }
+
+ return ret;
+}
+
+void func_808A5CCC(EnSt* this) {
+ if (this->unk_310 != 0) {
+ this->unk_310--;
+ }
+
+ if (this->unk_310 < 8) {
+ Math_ApproachS(&this->actor.world.rot.y, func_808A5BEC(this), 3, 0x1FFE);
+ } else {
+ this->actor.world.rot.y += 0x2AA8;
+ }
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+
+ if (DECR(this->unk_310) == 0) {
+ this->unk_18C &= ~1;
+ }
+}
+
+void func_808A5D7C(EnSt* this) {
+ if (this->unk_2C8 > 0.0f) {
+ this->actor.world.pos.y = this->actor.home.pos.y - 10.0f;
+ } else {
+ this->actor.world.pos.y = this->actor.floorHeight + 20.0f;
+ }
+}
+
+void func_808A5DCC(EnSt* this, Color_RGB8* colour) {
+ if (this->unk_2D8 == 0.0f) {
+ Math_SmoothStepToF(&this->unk_34C, 0.0f, 0.3f, 1000.0f, 0.0f);
+ } else {
+ this->unk_34C += this->unk_2D8;
+ if (this->unk_34C >= 255.0f) {
+ this->unk_34C = 255.0f;
+ this->unk_2D8 *= -1.0f;
+ }
+
+ if (this->unk_34C <= 0.0f) {
+ this->unk_34C = 0.0f;
+ this->unk_2D8 *= -1.0f;
+ }
+ }
+
+ colour->r = this->unk_34C;
+ colour->g = 0;
+ colour->b = 0;
+}
+
+s32 func_808A5F28(EnSt* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s32 ret = false;
+
+ if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) {
+ if (this->unk_2C8 <= 0.0f) {
+ return false;
+ }
+ return true;
+ }
+
+ if ((((this->unk_2C8 > 0.0f) && (this->actor.world.pos.y < player->actor.world.pos.y)) ||
+ ((this->unk_2C8 > 0.0f) && (this->actor.xzDistToPlayer > 180.0f)) ||
+ ((this->unk_2C8 < 0.0f) && (player->actor.world.pos.y <= this->actor.world.pos.y) &&
+ (this->actor.floorHeight <= player->actor.world.pos.y) && (this->actor.xzDistToPlayer < 120.0f))) &&
+ !(this->unk_18C & 8)) {
+ ret = true;
+ }
+
+ return ret;
+}
+
+s32 func_808A6064(EnSt* this) {
+ s32 ret = false;
+
+ if (this->unk_2C8 > 0.0f) {
+ if ((this->actor.home.pos.y - 10.0f) < this->actor.world.pos.y) {
+ ret = true;
+ }
+ } else if (this->actor.world.pos.y < (this->actor.floorHeight + 20.0f)) {
+ ret = true;
+ }
+ return ret;
+}
+
+void func_808A60E0(EnSt* this) {
+ s32 idx = (this->unk_2C8 > 0.0f) ? 2 : 6;
+ f32 sp20 = (this->unk_2C8 > 0.0f) ? 4.0f : 9.0f;
+ f32 sp1C;
+ u16 sfxId = (this->unk_2C8 < 0.0f) ? NA_SE_EN_STALTU_DOWN : NA_SE_EN_STALTU_UP;
+
+ sp1C = this->skelAnime.curFrame / (this->skelAnime.animLength - 1.0f);
+
+ if (sp1C == 1.0f) {
+ func_8013BC6C(&this->skelAnime, sAnimations, idx);
+ Audio_PlayActorSound2(&this->actor, sfxId);
+ }
+
+ this->unk_2D4 = (1.0f - sp1C) * sp20 * this->unk_2C8;
+
+ if (this->unk_2C8 < 0.0f) {
+ this->unk_2D4 = this->unk_2C8 * sp20;
+ }
+}
+
+s32 func_808A61F4(EnSt* this) {
+ if (this->actor.colChkInfo.damage < this->actor.colChkInfo.health) {
+ this->actor.colChkInfo.health -= this->actor.colChkInfo.damage;
+ } else {
+ this->actor.colChkInfo.health = 0;
+ }
+ return this->actor.colChkInfo.health;
+}
+
+void func_808A6220(EnSt* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ if ((DECR(this->unk_314) == 0) && (this->actor.colChkInfo.health != 0)) {
+ Collider_UpdateCylinder(&this->actor, &this->collider2);
+ Collider_UpdateCylinder(&this->actor, &this->collider3);
+ Collider_UpdateCylinder(&this->actor, &this->collider4);
+ if ((s16)ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)) < 0x4E00) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider3.base);
+ } else {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
+ }
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider4.base);
+ }
+
+ if (this->actor.colChkInfo.health != 0) {
+ Collider_UpdateCylinder(&this->actor, &this->collider1);
+ if (((this->unk_2C8 < 0.0f) && (this->unk_18C & 0x10)) || (this->unk_18C & 1)) {
+ this->collider1.dim.yShift = -40;
+ this->collider1.dim.radius = 56;
+ this->collider1.dim.height = 80;
+ } else {
+ this->collider1.dim.yShift = -20;
+ this->collider1.dim.radius = 18;
+ this->collider1.dim.height = 48;
+ }
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base);
+ }
+}
+
+void func_808A63E8(EnSt* this) {
+ func_8013BC6C(&this->skelAnime, sAnimations, 3);
+ this->unk_2C8 = 1.0f;
+ func_808A5D7C(this);
+ this->unk_30C = 0;
+ this->unk_18C &= ~0x10;
+ this->unk_2C8 = -1.0f;
+ this->unk_2D4 = 0.0f;
+ this->unk_2CC = 0.0f;
+ this->unk_2C4 = 1.0f;
+}
+
+void func_808A6468(EnSt* this, GlobalContext* globalCtx) {
+ func_808A5050(this, globalCtx);
+ func_8013BC6C(&this->skelAnime, sAnimations, 4);
+ this->unk_18C |= (0x8 | 0x4);
+ this->unk_18C &= ~(0x10 | 0x2);
+ this->unk_2C8 = -1.0f;
+ func_808A5D7C(this);
+ this->unk_30E = 30;
+ this->unk_30C = 0;
+ this->unk_2C8 = 1.0f;
+ this->unk_2D8 = 30.0f;
+ this->unk_2D4 = 0.0f;
+ this->unk_2CC = 0.0f;
+ this->unk_2C4 = 6.0f;
+}
+
+void func_808A650C(EnSt* this) {
+ s32 idx = (this->unk_2C8 > 0.0f) ? 2 : 6;
+
+ func_8013BC6C(&this->skelAnime, sAnimations, idx);
+ this->unk_2CC = 0.0f;
+ this->unk_2D4 = 0.0f;
+ this->unk_2D8 = 0.0f;
+ this->unk_18C &= ~4;
+ this->unk_18C |= 0x10;
+}
+
+s32 func_808A6580(EnSt* this, GlobalContext* globalCtx) {
+ Player* sp3C = GET_PLAYER(globalCtx);
+ s32 ret = false;
+ s32 i;
+
+ if (this->unk_316 != 0) {
+ this->unk_316--;
+ }
+
+ if (this->collider3.base.acFlags & AC_HIT) {
+ if (this->unk_18E == 10) {
+ // clang-format off
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; }
+ // clang-format on
+
+ this->unk_318 = 0;
+ }
+
+ if (this->actor.colChkInfo.damageEffect == 4) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS);
+ }
+ this->collider3.base.acFlags &= ~AC_HIT;
+ }
+
+ if ((this->collider2.base.acFlags & AC_HIT) || (this->collider4.base.acFlags & AC_HIT)) {
+ this->collider2.base.acFlags &= ~AC_HIT;
+ this->collider4.base.acFlags &= ~AC_HIT;
+ if (this->actor.colChkInfo.damageEffect == 4) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS);
+ }
+
+ if (this->unk_18E == 10) {
+ // clang-format off
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; }
+ // clang-format on
+
+ this->unk_318 = 0;
+ } else if (func_808A61F4(this)) {
+ switch (this->actor.colChkInfo.damageEffect) {
+ case 1:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ this->unk_312 = 40;
+ func_800BCB70(&this->actor, 0, 200, 0, this->unk_312);
+ break;
+
+ case 5:
+ this->unk_18E = 30;
+ this->unk_312 = 40;
+ func_808A576C(this);
+ func_800BCB70(&this->actor, 0, 200, 0, this->unk_312);
+ break;
+
+ default:
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_DAMAGE);
+ this->unk_314 = 20;
+ this->unk_312 = 0;
+ func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_314);
+ func_8013BC6C(&this->skelAnime, sAnimations, 1);
+ this->unk_18C |= 8;
+ this->actionFunc = func_808A6D84;
+ this->unk_2C8 = -1.0f;
+ break;
+ }
+ } else {
+ if (ENST_GET_3F(&this->actor) != ENST_3F_63) {
+ Actor_SetSwitchFlag(globalCtx, ENST_GET_3F(&this->actor));
+ }
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALTU_DEAD);
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+
+ this->actor.flags &= ~1;
+
+ switch (this->actor.colChkInfo.damageEffect) {
+ case 4:
+ this->unk_18E = 20;
+ this->unk_318 = 20;
+ func_808A576C(this);
+ break;
+
+ case 3:
+ this->unk_18E = 10;
+ this->unk_318 = 0;
+ func_808A576C(this);
+ break;
+
+ case 2:
+ this->unk_18E = 0;
+ this->unk_318 = 20;
+ func_808A576C(this);
+ break;
+
+ default:
+ this->unk_18E = 1;
+ this->unk_318 = 0;
+ break;
+ }
+
+ if (this->unk_18E != 10) {
+ func_8013BC6C(&this->skelAnime, sAnimations, 7);
+ this->unk_2CC = 0.0f;
+ this->unk_2D4 = 0.0f;
+ this->actor.gravity = -1.0f;
+ }
+ this->unk_314 = 20;
+ this->unk_312 = 0;
+ func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_314);
+ ret = true;
+ }
+ this->unk_310 = 0;
+ this->unk_18C &= ~1;
+ }
+
+ if ((this->collider1.base.ocFlags2 & OC2_HIT_PLAYER) || (this->collider1.base.atFlags & AT_HIT)) {
+ if ((this->unk_316 == 0) && (this->unk_314 == 0) && (this->unk_312 == 0) &&
+ !(this->collider1.base.atFlags & AT_BOUNCED) && (this->actor.colChkInfo.health != 0)) {
+ globalCtx->damagePlayer(globalCtx, -8);
+ Audio_PlayActorSound2(&sp3C->actor, NA_SE_PL_BODY_HIT);
+ func_800B8D98(globalCtx, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f);
+ this->unk_316 = 10;
+ this->unk_18C |= 1;
+ this->unk_30E = 0;
+ }
+ this->collider1.base.ocFlags1 &= ~OC1_HIT;
+ this->collider1.base.atFlags &= ~AT_HIT;
+ }
+ return ret;
+}
+
+s32 func_808A6A3C(EnSt* this) {
+ s32 ret = false;
+
+ if ((ENST_GET_1C0(&this->actor) == ENST_1C0_1) && (this->actor.colChkInfo.health != 0)) {
+ ret = true;
+ }
+ return ret;
+}
+
+void func_808A6A78(EnSt* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+
+ if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_2C0)) {
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 8.0f);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &object_st_Skel_005298, NULL, this->jointTable, this->morphTable,
+ 30);
+ func_8013BC6C(&this->skelAnime, sAnimations, 0);
+
+ Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider3, &this->actor, &sCylinderInit3);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider4, &this->actor, &sCylinderInit4);
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
+
+ if (ENST_GET_1C0(&this->actor) == ENST_1C0_1) {
+ this->actor.flags |= 0x80;
+ }
+
+ Actor_SetScale(&this->actor, 0.04f);
+ this->actor.draw = func_808A7478;
+ this->actor.hintId = 4;
+ this->actor.gravity = 0.0f;
+ func_808A63E8(this);
+ this->unk_18C = 0;
+ this->unk_18C &= ~0x10;
+ this->actionFunc = func_808A6C04;
+ }
+}
+
+void func_808A6C04(EnSt* this, GlobalContext* globalCtx) {
+ this->unk_2CC = Math_SinS(this->unk_30C) * this->unk_2C4;
+ this->unk_30C += 0xE00;
+ Math_ApproachF(&this->unk_2C4, 1.0f, 0.1f, 0.3f);
+ this->actor.velocity.y = this->unk_2D4 + this->unk_2CC;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+
+ if ((this->unk_18C & 8) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ func_8013BC6C(&this->skelAnime, sAnimations, 3);
+ this->unk_18C &= ~8;
+ } else if ((this->unk_310 == 0) && func_808A5F28(this, globalCtx) && !func_808A6064(this)) {
+ func_808A650C(this);
+ this->actionFunc = func_808A6D84;
+ } else {
+ if ((this->unk_316 == 0) && (this->unk_314 == 0) && (this->unk_312 == 0) && (this->unk_2C8 > 0.0f) &&
+ (this->actor.xzDistToPlayer < 62.0f)) {
+ this->unk_30E = 0;
+ this->unk_18C |= 1;
+ }
+ func_808A5CCC(this);
+ }
+}
+
+void func_808A6D84(EnSt* this, GlobalContext* globalCtx) {
+ func_808A60E0(this);
+ this->actor.velocity.y = this->unk_2D4 + this->unk_2CC;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ if (func_808A6064(this)) {
+ if (this->unk_2C8 < 0.0f) {
+ func_808A6468(this, globalCtx);
+ } else {
+ func_808A63E8(this);
+ }
+ this->actionFunc = func_808A6C04;
+ }
+ func_808A5CCC(this);
+}
+
+void func_808A6E24(EnSt* this, GlobalContext* globalCtx) {
+ s32 i;
+ s32 count = 0;
+
+ if (this->unk_18E == 10) {
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) {
+ if (DECR(this->unk_31C[i]) == 0) {
+ count++;
+ }
+ }
+
+ if (count == ARRAY_COUNT(this->unk_31C)) {
+ func_8013BC6C(&this->skelAnime, sAnimations, 7);
+ this->unk_18E = 1;
+ this->unk_2CC = 0.0f;
+ this->unk_2D4 = 0.0f;
+ this->actor.gravity = -1.0f;
+ func_808A5AF8(this, globalCtx);
+ }
+ } else if (this->unk_18C & 0x80) {
+ this->actionFunc = func_808A701C;
+ this->actor.gravity = 0.0f;
+ this->unk_2CC = 0.0f;
+ this->unk_2D4 = 0.0f;
+ } else {
+ if (this->actor.bgCheckFlags & 1) {
+ this->actor.shape.yOffset = 400.0f;
+ this->actor.world.rot.x = 0x4000;
+ this->actor.shape.rot.x = this->actor.world.rot.x;
+ this->unk_2D0 = this->actor.velocity.y = fabsf(this->actor.velocity.y) * 0.6f;
+ this->actor.speedXZ = 0.0f;
+
+ if ((s32)this->unk_2D0 != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_ATTACK);
+ } else {
+ this->actor.velocity.y = 0.0f;
+ this->actionFunc = func_808A701C;
+ }
+
+ if ((s32)this->actor.velocity.y >= 2) {
+ func_808A52A8(this, globalCtx);
+ }
+ } else {
+ Math_ApproachF(&this->actor.shape.yOffset, 400.0f, 0.3f, 1000.0f);
+ this->actor.world.rot.x += 0x1000;
+ if (this->actor.world.rot.x >= 0x4000) {
+ this->actor.world.rot.x = 0x4000;
+ }
+ this->actor.shape.rot.x = this->actor.world.rot.x;
+ }
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ }
+}
+
+void func_808A701C(EnSt* this, GlobalContext* globalCtx) {
+ s32 i;
+ s32 count = 0;
+
+ if (this->unk_18C & 0x40) {
+ if (DECR(this->unk_318) == 0) {
+ this->unk_18C |= 0x20;
+ }
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) {
+ if (DECR(this->unk_31C[i]) == 0) {
+ count++;
+ }
+ }
+
+ if (count == ARRAY_COUNT(this->unk_31C)) {
+ Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0);
+ Actor_MarkForDeath(&this->actor);
+ }
+ } else if (DECR(this->unk_318) == 0) {
+ this->unk_18C |= 0x40;
+ if (this->unk_18E == 1) {
+ func_808A576C(this);
+ this->unk_318 = 10;
+ }
+ }
+}
+
+void EnSt_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnSt* this = THIS;
+
+ this->unk_2C0 = Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_KEEP);
+ if (((ENST_GET_3F(&this->actor) != ENST_3F_63) && Flags_GetSwitch(globalCtx, ENST_GET_3F(&this->actor))) ||
+ (this->unk_2C0 < 0)) {
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ this->actionFunc = func_808A6A78;
+ }
+}
+
+void EnSt_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnSt* this = THIS;
+
+ Collider_DestroyCylinder(globalCtx, &this->collider1);
+ Collider_DestroyCylinder(globalCtx, &this->collider2);
+ Collider_DestroyCylinder(globalCtx, &this->collider3);
+ Collider_DestroyCylinder(globalCtx, &this->collider4);
+}
+
+void EnSt_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnSt* this = THIS;
+
+ if (this->actor.flags & 0x8000) {
+ SkelAnime_Update(&this->skelAnime);
+ this->unk_18C |= 0x80;
+ return;
+ }
+
+ if (!(this->actor.flags & 0x80) && func_808A6A3C(this)) {
+ this->actor.flags |= 0x80;
+ }
+
+ if (func_808A6580(this, globalCtx)) {
+ this->actionFunc = func_808A6E24;
+ } else if (DECR(this->unk_312) == 0) {
+ this->actionFunc(this, globalCtx);
+ if (this->unk_18E != 10) {
+ SkelAnime_Update(&this->skelAnime);
+ }
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 5);
+ } else if (this->unk_312 < 20) {
+ s16 idx = (this->unk_312 % 2) ? -1 : 1;
+
+ idx *= 0x800;
+ idx += this->actor.world.rot.y;
+ this->actor.shape.rot.y = idx;
+
+ if (this->unk_18E == 30) {
+ if (this->unk_312 == 1) {
+ s32 i;
+
+ // clang-format off
+ for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; }
+ // clang-format on
+ }
+ }
+ }
+
+ Actor_SetHeight(&this->actor, 0.0f);
+ func_808A6220(this, globalCtx);
+}
+
+s32 EnSt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx,
+ Gfx** gfx) {
+ EnSt* this = THIS;
+ Color_RGB8 sp20;
+
+ if (limbIndex == 4) {
+ func_808A5DCC(this, &sp20);
+
+ gDPPipeSync((*gfx)++);
+ gDPSetEnvColor((*gfx)++, sp20.r, sp20.g, sp20.b, 0);
+ }
+ return false;
+}
+
+void func_808A7478(Actor* thisx, GlobalContext* globalCtx) {
+ EnSt* this = THIS;
+ s32 i;
+ s32 count;
+
+ if (!(this->unk_18C & 0x20)) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if (func_808A6A3C(this)) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ EnSt_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP);
+ } else {
+ func_8012C28C(globalCtx->state.gfxCtx);
+ POLY_OPA_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ EnSt_OverrideLimbDraw, NULL, &this->actor, POLY_OPA_DISP);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+
+ for (i = 0, count = 0; i < ARRAY_COUNT(this->unk_31C); i++) {
+ count += func_808A5988(this, globalCtx, i);
+ }
+
+ if (count != 0) {
+ this->unk_31A += 2;
+ }
+
+ func_808A54B0(this, globalCtx);
+}
diff --git a/src/overlays/actors/ovl_En_St/z_en_st.h b/src/overlays/actors/ovl_En_St/z_en_st.h
index 0ad88efef..a82ff397b 100644
--- a/src/overlays/actors/ovl_En_St/z_en_st.h
+++ b/src/overlays/actors/ovl_En_St/z_en_st.h
@@ -7,11 +7,45 @@ struct EnSt;
typedef void (*EnStActionFunc)(struct EnSt*, GlobalContext*);
+#define ENST_GET_3F(thisx) (((thisx)->params & 0x3F) & 0xFF)
+#define ENST_GET_1C0(thisx) ((((thisx)->params & 0x1C0) >> 6) & 0xFF)
+
+#define ENST_3F_63 63
+#define ENST_1C0_1 1
+
typedef struct EnSt {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x44];
- /* 0x0188 */ EnStActionFunc actionFunc;
- /* 0x018C */ char unk_18C[0x3C4];
+ /* 0x000 */ Actor actor;
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ EnStActionFunc actionFunc;
+ /* 0x18C */ u16 unk_18C;
+ /* 0x18E */ u8 unk_18E;
+ /* 0x190 */ ColliderCylinder collider1;
+ /* 0x1DC */ ColliderCylinder collider2;
+ /* 0x228 */ ColliderCylinder collider3;
+ /* 0x274 */ ColliderCylinder collider4;
+ /* 0x2C0 */ s8 unk_2C0;
+ /* 0x2C4 */ f32 unk_2C4;
+ /* 0x2C8 */ f32 unk_2C8;
+ /* 0x2CC */ f32 unk_2CC;
+ /* 0x2D0 */ f32 unk_2D0;
+ /* 0x2D4 */ f32 unk_2D4;
+ /* 0x2D8 */ f32 unk_2D8;
+ /* 0x2DC */ f32 unk_2DC[12];
+ /* 0x30C */ s16 unk_30C;
+ /* 0x30E */ s16 unk_30E;
+ /* 0x310 */ s16 unk_310;
+ /* 0x312 */ s16 unk_312;
+ /* 0x314 */ s16 unk_314;
+ /* 0x316 */ s16 unk_316;
+ /* 0x318 */ s16 unk_318;
+ /* 0x31A */ s16 unk_31A;
+ /* 0x31C */ s16 unk_31C[12];
+ /* 0x334 */ s16 unk_334[12];
+ /* 0x34C */ f32 unk_34C;
+ /* 0x350 */ UNK_TYPE1 unk_350[0x8];
+ /* 0x358 */ Vec3f unk_358[12];
+ /* 0x3E8 */ Vec3s jointTable[30];
+ /* 0x49C */ Vec3s morphTable[30];
} EnSt; // size = 0x550
extern const ActorInit En_St_InitVars;
diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.c b/src/overlays/actors/ovl_En_Stream/z_en_stream.c
index 6f20e1bd5..9ce7ac906 100644
--- a/src/overlays/actors/ovl_En_Stream/z_en_stream.c
+++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.c
@@ -5,6 +5,7 @@
*/
#include "z_en_stream.h"
+#include "objects/object_stream/object_stream.h"
#define FLAGS 0x00000010
@@ -33,8 +34,6 @@ static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 20, ICHAIN_STOP),
};
-extern Gfx D_06000950[];
-
void EnStream_SetupAction(EnStream* this, EnStreamActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
@@ -144,7 +143,7 @@ void EnStream_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPSegment(&gfx[1], 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, frames * 30, -multipliedFrames, 64, 64, 1, multipliedFrames,
-multipliedFrames, 64, 64));
- gSPDisplayList(&gfx[2], D_06000950);
+ gSPDisplayList(&gfx[2], gWaterVortexDL);
POLY_XLU_DISP = &gfx[3];
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
index da6211d3c..7f1930437 100644
--- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
+++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
@@ -689,7 +689,7 @@ s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg
if (this->unk428 == 10 || this->unk428 == 11 || this->unk428 == 2) {
return 0;
}
- sp48 = (EnDoor*)func_8013BB7C(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR);
+ sp48 = (EnDoor*)SubS_FindNearestActor(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR);
sp24 = D_80BAE8F8[unkStruct->unk0];
if ((sp48 != NULL) && (sp24 >= 0)) {
this->unk404 = func_8013BB34(globalCtx, sp47, sp24);
diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c
index d07c74a04..6781548ce 100644
--- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c
+++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c
@@ -402,12 +402,12 @@ s32 func_80C10E98(GlobalContext* globalCtx) {
sp64.y = player->actor.world.pos.y + 20.0f;
sp64.z = (Math_CosS(phi_s3) * 40.0f) + player->actor.world.pos.z;
if (dropItem00Ids[i] != ITEM00_NO_DROP) {
- EnItem00* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, dropItem00Ids[i]);
+ Actor* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, dropItem00Ids[i]);
if (temp_s1_5 != NULL) {
- temp_s1_5->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f;
- temp_s1_5->actor.speedXZ = Rand_ZeroFloat(3.0f) + 3.0f;
- temp_s1_5->actor.world.rot.y = phi_s3;
+ temp_s1_5->velocity.y = Rand_ZeroFloat(3.0f) + 6.0f;
+ temp_s1_5->speedXZ = Rand_ZeroFloat(3.0f) + 3.0f;
+ temp_s1_5->world.rot.y = phi_s3;
}
phi_s3 += (s16)(0x10000 / (spB0 + spAC + phi_s0_2 + spA0 + phi_s2 + spA8));
}
@@ -430,7 +430,7 @@ void func_80C11338(EnThiefbird* this, GlobalContext* globalCtx) {
this->unk_3EC = NULL;
do {
- item = (EnItem00*)func_ActorCategoryIterateById(globalCtx, &item->actor, ACTORCAT_MISC, ACTOR_EN_ITEM00);
+ item = (EnItem00*)SubS_FindActor(globalCtx, &item->actor, ACTORCAT_MISC, ACTOR_EN_ITEM00);
if (item != NULL) {
if (item->unk152 > 0) {
if (Actor_XZDistanceBetweenActors(&player->actor, &item->actor) > 10.0f) {
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 61112d8cb..c3bdb98ea 100644
--- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c
+++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c
@@ -450,7 +450,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) {
door1 = NULL;
label:
do {
- door1 = func_ActorCategoryIterateById(globalCtx, door1, ACTORCAT_DOOR, ACTOR_EN_DOOR);
+ door1 = SubS_FindActor(globalCtx, door1, ACTORCAT_DOOR, ACTOR_EN_DOOR);
if (door1 != NULL) {
if (Actor_XZDistanceBetweenActors(&this->actor, door1) <= 120.0f) {
if (ABS(BINANG_SUB(Actor_YawToPoint(&this->actor, &door1->world.pos), this->actor.shape.rot.y)) <=
@@ -466,7 +466,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) {
} else {
door2 = NULL;
do {
- door2 = func_ActorCategoryIterateById(globalCtx, door2, ACTORCAT_DOOR, ACTOR_EN_DOOR);
+ door2 = SubS_FindActor(globalCtx, door2, ACTORCAT_DOOR, ACTOR_EN_DOOR);
if (door2 != NULL) {
if (Actor_XZDistanceBetweenActors(&this->actor, door2) <= 160.0f) {
sp4C4 = (EnDoor*)door2;
@@ -682,7 +682,7 @@ void func_80AED940(EnTk* this, GlobalContext* globalCtx) {
actor = NULL;
do {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_TK);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_TK);
if (actor != NULL) {
if (ENTK_GET_F(actor) == 1) {
Math_Vec3f_Copy(&this->unk_2EC, &actor->world.pos);
@@ -933,7 +933,7 @@ void func_80AEE374(EnTk* this, GlobalContext* globalCtx) {
sp30.unk_00 = NULL;
sp30.unk_04 = FLT_MAX;
- func_8013E640(globalCtx, &this->actor, NULL, ACTORCAT_NPC, ACTOR_EN_TK, &sp30, func_80AEE300);
+ SubS_FindActorCustom(globalCtx, &this->actor, NULL, ACTORCAT_NPC, ACTOR_EN_TK, &sp30, func_80AEE300);
if (sp30.unk_00 == 0) {
Actor_MarkForDeath(&this->actor);
} else {
@@ -971,7 +971,7 @@ void func_80AEE4D0(EnTk* this, GlobalContext* globalCtx) {
if (Animation_OnFrame(&this->skelAnime, 37.0f)) {
bigPoe = NULL;
do {
- bigPoe = func_ActorCategoryIterateById(globalCtx, bigPoe, ACTORCAT_PROP, ACTOR_EN_BIGPO);
+ bigPoe = SubS_FindActor(globalCtx, bigPoe, ACTORCAT_PROP, ACTOR_EN_BIGPO);
if (bigPoe != NULL) {
if ((bigPoe->params == 3) && (Actor_DistanceBetweenActors(&this->actor, bigPoe) < 80.0f)) {
diff --git a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
index 236881f25..05d86f3cd 100644
--- a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
+++ b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
@@ -5,6 +5,8 @@
*/
#include "z_en_water_effect.h"
+#include "objects/object_water_effect/object_water_effect.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00000035
@@ -15,7 +17,11 @@ void EnWaterEffect_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnWaterEffect_Update(Actor* thisx, GlobalContext* globalCtx);
void EnWaterEffect_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void func_80A59C04(Actor* thisx, GlobalContext* globalCtx2);
+void func_80A5A184(Actor* thisx, GlobalContext* globalCtx2);
+void func_80A5A534(Actor* thisx, GlobalContext* globalCtx);
+void func_80A5A6B8(Actor* thisx, GlobalContext* globalCtx2);
+
const ActorInit En_Water_Effect_InitVars = {
ACTOR_EN_WATER_EFFECT,
ACTORCAT_BOSS,
@@ -28,30 +34,672 @@ const ActorInit En_Water_Effect_InitVars = {
(ActorFunc)EnWaterEffect_Draw,
};
-#endif
+static Vec3f D_80A5AFB0 = { 0.0f, 0.0f, 0.0f };
+static Vec3f D_80A5AFBC = { 0.0f, -1.0f, 0.0f };
-extern UNK_TYPE D_06000DE0;
-extern UNK_TYPE D_060042B0;
-extern UNK_TYPE D_060043E8;
+void func_80A587A0(EnWaterEffect* this, Vec3f* arg1, u8 arg2) {
+ s16 i;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A587A0.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if (!ptr->unk_00) {
+ ptr->unk_00 = true;
+ ptr->unk_04 = *arg1;
+ ptr->unk_10 = D_80A5AFB0;
+ ptr->unk_1C = D_80A5AFB0;
+ ptr->unk_2C.x = 0.1f;
+ ptr->unk_2C.y = 0.0f;
+ ptr->unk_2C.z = Rand_ZeroFloat(M_PI * 2);
+ ptr->unk_01 = Rand_ZeroFloat(100.0f);
+ ptr->unk_2A = arg2;
+ break;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A58908.s")
+void func_80A58908(EnWaterEffect* this, Vec3f* arg1, Vec3f* arg2, u8 arg3) {
+ Vec3f sp2C = D_80A5AFBC;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Init.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_00 = 2;
+ ptr->unk_04 = *arg1;
+ ptr->unk_10 = *arg2;
+ ptr->unk_1C = sp2C;
+ ptr->unk_2C.y = Rand_ZeroFloat(0.02f) + 0.02f;
+ ptr->unk_2C.x = ptr->unk_2C.y;
+ ptr->unk_2C.z = Rand_ZeroFloat(M_PI * 2);
+ ptr->unk_01 = Rand_ZeroFloat(100.0f);
+ ptr->unk_2A = arg3;
+ break;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Destroy.s")
+void EnWaterEffect_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnWaterEffect* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Update.s")
+ this->actor.flags &= ~1;
+ this->unk_DC4 = Rand_ZeroFloat(100.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Draw.s")
+ if (this->actor.params == ENWATEREFFECT_1) {
+ this->actor.update = func_80A59C04;
+ this->actor.draw = func_80A5A184;
+ this->unk_DC6 = Rand_ZeroFloat(100.0f) + 60.0f;
+ } else if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_778) ||
+ (this->actor.params == ENWATEREFFECT_779) || (this->actor.params == ENWATEREFFECT_780)) {
+ this->actor.update = func_80A5A534;
+ this->actor.draw = func_80A5A6B8;
+ this->actor.shape.rot.y = Rand_ZeroFloat(0x10000);
+ Actor_SetScale(&this->actor, this->actor.shape.rot.z * 0.0002f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A599E8.s")
+ if (this->actor.params == ENWATEREFFECT_777) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, this->actor.shape.rot.z, 0x30A);
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, this->actor.shape.rot.z, 0x30B);
+ } else if (this->actor.params == ENWATEREFFECT_778) {
+ this->unk_DC4 = -3;
+ } else if (this->actor.params == ENWATEREFFECT_779) {
+ this->unk_DC4 = -6;
+ } else if (this->actor.params == ENWATEREFFECT_780) {
+ this->unk_DC4 = 23;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A59C04.s")
+ this->unk_E08[1] = 0.2f;
+ this->unk_E18[1] = -0.017f;
+ this->unk_E08[2] = 0.2f;
+ this->unk_E18[2] = -0.018f;
+ this->unk_E08[3] = 0.2f;
+ this->unk_E18[3] = -0.019f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A184.s")
+ this->unk_DC8[1].y = 1.0f;
+ this->unk_DC8[2].y = 1.0f;
+ this->unk_DC8[3].y = 1.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A534.s")
+ this->unk_E2C = 255.0f;
+ this->unk_E34 = 255.0f;
+ this->unk_E30 = 200.0f;
+ this->unk_E38 = 191.25f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A6B8.s")
+void EnWaterEffect_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void EnWaterEffect_Update(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnWaterEffect* this = THIS;
+ Player* player = GET_PLAYER(globalCtx);
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+ s16 i;
+ s16 j;
+ s32 phi_v0;
+ Vec3f spA4;
+ Vec3f sp98;
+ u8 phi_v1;
+ Vec3f sp88;
+
+ if (!Flags_GetSwitch(globalCtx, this->actor.params)) {
+ this->unk_DC4++;
+ if ((this->unk_DC4 % 32) == 0) {
+ if (Rand_ZeroOne() < 0.5f) {
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 10.0f, 40.0f, 4);
+ sp88.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x;
+ sp88.y = this->actor.world.pos.y;
+ sp88.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z;
+ if ((this->actor.world.pos.y + this->actor.depthInWater) <= this->actor.floorHeight) {
+ phi_v1 = 0;
+ } else {
+ phi_v1 = 1;
+ this->actor.floorHeight = this->actor.world.pos.y + this->actor.depthInWater;
+ }
+ func_80A587A0(this, &sp88, phi_v1);
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if (ptr->unk_00 != 0) {
+ ptr->unk_01++;
+
+ ptr->unk_04.x += ptr->unk_10.x;
+ ptr->unk_04.y += ptr->unk_10.y;
+ ptr->unk_04.z += ptr->unk_10.z;
+ ptr->unk_10.y += ptr->unk_1C.y;
+
+ Math_ApproachF(&ptr->unk_38, (ptr->unk_01 & 6) ? 80.0f : 200.0f, 1.0f, 80);
+
+ if (ptr->unk_00 == 1) {
+ ptr->unk_2C.z += 0.15f;
+ Math_ApproachF(&ptr->unk_2C.x, 0.03f, 0.5f, 0.005f);
+ Math_ApproachF(&ptr->unk_2C.y, 0.5f, 0.5f, 0.02f);
+
+ if (ptr->unk_2C.y > 0.15f) {
+ ptr->unk_1C.y = -1.0f;
+ if (ptr->unk_10.y < -20.0f) {
+ ptr->unk_10.y = -20.0f;
+ }
+ }
+
+ if ((fabsf(ptr->unk_04.x - player->actor.world.pos.x) < 15.0f) &&
+ (fabsf(ptr->unk_04.z - player->actor.world.pos.z) < 15.0f) &&
+ (player->actor.world.pos.y < ptr->unk_04.y) &&
+ ((ptr->unk_04.y - player->actor.world.pos.y) < 40.0f)) {
+ phi_v0 = true;
+ } else {
+ phi_v0 = false;
+ }
+
+ if ((ptr->unk_04.y <= this->actor.floorHeight) || phi_v0) {
+
+ if (phi_v0) {
+ ptr->unk_00 = 0;
+ Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_BOMB_DROP_WATER);
+ } else {
+ ptr->unk_04.y = this->actor.floorHeight;
+ if (ptr->unk_2A == 0) {
+ Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_WATERDROP_GRD);
+ ptr->unk_00 = 3;
+ ptr->unk_2C.x = 0.1f;
+ ptr->unk_2C.y = 0.6f;
+ ptr->unk_10 = D_80A5AFB0;
+ ptr->unk_1C = D_80A5AFB0;
+ ptr->unk_3C = 200;
+ ptr->unk_28 = 9;
+ Math_Vec3f_Copy(&sp98, &ptr->unk_04);
+ sp98.y += 3.0f;
+ EffectSsGSplash_Spawn(globalCtx, &sp98, NULL, NULL, 1, 100);
+ } else {
+ ptr->unk_00 = 0;
+ Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_WATERDROP);
+ EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 70, 500, 0);
+ EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 70, 500, 10);
+ Math_Vec3f_Copy(&sp98, &ptr->unk_04);
+ sp98.y += 10.0f;
+ EffectSsGSplash_Spawn(globalCtx, &sp98, NULL, NULL, 1, 300);
+ }
+ }
+
+ for (j = 0; j < 12; j++) {
+ Matrix_InsertYRotation_f((2.0f * (j * M_PI)) / 5.5f, MTXMODE_NEW);
+ Matrix_GetStateTranslationAndScaledZ(Rand_ZeroFloat(1.5f) + 1.5f, &spA4);
+ spA4.y = Rand_ZeroFloat(4.0f) + 2.0f;
+ func_80A58908(this, &ptr->unk_04, &spA4, ptr->unk_2A);
+ }
+ }
+ } else if (ptr->unk_00 == 2) {
+ ptr->unk_2C.z += 0.15f;
+ if (ptr->unk_10.y < -8.0f) {
+ ptr->unk_10.y = -8.0f;
+ }
+
+ if (ptr->unk_10.y < 0.0f) {
+ if (ptr->unk_04.y <= this->actor.floorHeight) {
+ ptr->unk_04.y = this->actor.floorHeight;
+ if (ptr->unk_2A == 0) {
+ ptr->unk_00 = 3;
+ ptr->unk_2C.x = 0.05f;
+ ptr->unk_2C.y = 0.2f;
+ ptr->unk_10 = D_80A5AFB0;
+ ptr->unk_1C = D_80A5AFB0;
+ ptr->unk_3C = 150;
+ ptr->unk_28 = Rand_ZeroFloat(5.0f) + 7.0f;
+ } else {
+ EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 0, 200, 0);
+ ptr->unk_00 = 0;
+ }
+ }
+ }
+ } else if (ptr->unk_00 == 3) {
+ Math_ApproachF(&ptr->unk_2C.x, ptr->unk_2C.y, 0.1f, 0.6f);
+ ptr->unk_3C -= ptr->unk_28;
+ if (ptr->unk_3C <= 0) {
+ ptr->unk_3C = 0;
+ ptr->unk_00 = 0;
+ }
+ }
+ }
+ }
+}
+
+void EnWaterEffect_Draw(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
+ EnWaterEffect* this = THIS;
+ s32 pad;
+ EnWaterEffectStruct* backupPtr = &this->unk_144[0];
+ EnWaterEffectStruct* ptr = backupPtr;
+ u8 phi_s4 = false;
+ s16 i;
+
+ OPEN_DISPS(gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if ((ptr->unk_00 == 1) || (ptr->unk_00 == 2)) {
+ if (!phi_s4) {
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0));
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260);
+ gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0);
+ phi_s4++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, 150);
+
+ Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
+
+ if (ptr->unk_00 == 1) {
+ Matrix_RotateY(func_800DFC68(GET_ACTIVE_CAM(globalCtx)), MTXMODE_APPLY);
+ } else {
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ }
+
+ Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY);
+ Matrix_InsertZRotation_f(ptr->unk_2C.z, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042B0);
+ }
+ }
+
+ phi_s4 = false;
+ ptr = backupPtr;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if (ptr->unk_00 == 3) {
+ if (!phi_s4) {
+ func_8012C448(gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0));
+ gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260);
+ phi_s4++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225,
+ ptr->unk_3C);
+
+ Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
+ Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(ptr->unk_2C.z, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8);
+ }
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+void func_80A599E8(EnWaterEffect* this, Vec3f* arg1, u8 arg2) {
+ s16 i;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_00 = 4;
+ ptr->unk_04 = *arg1;
+
+ ptr->unk_1C = D_80A5AFB0;
+ ptr->unk_10 = D_80A5AFB0;
+
+ if ((arg2 == 0) || (arg2 == 2)) {
+ ptr->unk_1C.y = -1.0f;
+ }
+
+ if (arg2 >= 2) {
+ if (arg2 == 2) {
+ ptr->unk_10.x = randPlusMinusPoint5Scaled(10.0f);
+ ptr->unk_10.y = Rand_ZeroFloat(3.0f) + 5.0f;
+ ptr->unk_10.z = randPlusMinusPoint5Scaled(10.0f);
+ }
+ ptr->unk_2C.z = 0.0017f;
+ ptr->unk_2C.x = 0.003f;
+ ptr->unk_2C.y = 0.0018f;
+ } else {
+ ptr->unk_2C.z = 0.003f;
+ ptr->unk_2C.x = 0.003f;
+ ptr->unk_2C.y = 0.003f;
+ }
+ ptr->unk_38 = 255.0f;
+ ptr->unk_28 = Rand_ZeroFloat(0x10000);
+ ptr->unk_3C = 255;
+ ptr->unk_01 = Rand_ZeroFloat(200.0f);
+ ptr->unk_2A = arg2;
+ break;
+ }
+ }
+}
+
+void func_80A59C04(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnWaterEffect* this = THIS;
+ s16 i;
+ s16 j;
+ f32 temp_f0_2;
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f sp90;
+ Actor* rotaryRoom = globalCtx->actorCtx.actorList[ACTORCAT_BG].first;
+ CollisionPoly* sp88;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+ u8 phi_s5;
+ Vec3f sp74;
+
+ while (rotaryRoom != NULL) {
+ if (rotaryRoom->id == ACTOR_BG_IKANA_ROTARYROOM) {
+ break;
+ }
+ rotaryRoom = rotaryRoom->next;
+ }
+
+ if (this->unk_DC6 != 0) {
+ this->unk_DC6--;
+ }
+
+ if ((rotaryRoom != NULL) && Flags_GetSwitch(globalCtx, (rotaryRoom->params >> 1) & 0x7F)) {
+ this->unk_DC6 = Rand_ZeroFloat(150.0f) + 100.0f;
+ } else if (!func_801690CC(globalCtx)) {
+ this->unk_DC4++;
+ if (this->unk_DC6 == 0) {
+ this->unk_DC6 = Rand_ZeroFloat(150.0f) + 100.0f;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 10.0f, 40.0f, 4);
+ sp74.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x;
+ sp74.y = this->actor.world.pos.y;
+ sp74.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z;
+ func_80A599E8(this, &sp74, 0);
+ }
+ }
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) {
+ phi_s5 = false;
+
+ if (ptr->unk_00 != 0) {
+ ptr->unk_01++;
+
+ ptr->unk_04.x += ptr->unk_10.x;
+ ptr->unk_04.y += ptr->unk_10.y;
+ ptr->unk_04.z += ptr->unk_10.z;
+ ptr->unk_10.y = ptr->unk_10.y + ptr->unk_1C.y;
+
+ if (ptr->unk_00 == 4) {
+ if (ptr->unk_2A > 0) {
+ if (ptr->unk_2A == 1) {
+ Math_ApproachF(&ptr->unk_2C.x, 0.001f, 0.5f, 0.0002f);
+ }
+
+ if (ptr->unk_2A & 1) {
+ Math_ApproachZeroF(&ptr->unk_38, 1.0f, 30.0f);
+ if (ptr->unk_2A == 1) {
+ ptr->unk_3C -= 20;
+ } else {
+ ptr->unk_3C -= 10;
+ }
+ if (ptr->unk_3C <= 0) {
+ ptr->unk_00 = 0;
+ }
+ Math_ApproachZeroF(&ptr->unk_10.x, 1.0f, 1.0f);
+ Math_ApproachZeroF(&ptr->unk_10.z, 1.0f, 1.0f);
+ }
+ }
+
+ if ((ptr->unk_2A % 2) == 0) {
+ if (ptr->unk_2A == 0) {
+ func_80A599E8(this, &ptr->unk_04, 1);
+ } else if ((ptr->unk_01 & 1) == 0) {
+ func_80A599E8(this, &ptr->unk_04, 3);
+ }
+
+ if (ptr->unk_10.y < -20.0f) {
+ ptr->unk_10.y = -20.0f;
+ }
+
+ ptr->unk_28 += 0x800;
+ if ((fabsf(ptr->unk_04.x - player->actor.world.pos.x) < 20.0f) &&
+ (fabsf(ptr->unk_04.z - player->actor.world.pos.z) < 20.0f) &&
+ (fabsf(ptr->unk_04.y - (player->actor.world.pos.y + 25.0f)) < 30.0f)) {
+ phi_s5 = true;
+ if ((player->transformation != PLAYER_FORM_GORON) && !player->isBurning) {
+ func_800B8D50(globalCtx, &this->actor, 2.0f, Rand_ZeroFloat(0x10000), 0.0f, 0x10);
+ for (j = 0; j < ARRAY_COUNT(player->flameTimers); j++) {
+ player->flameTimers[j] = Rand_S16Offset(0, 200);
+ }
+ player->isBurning = true;
+ func_800B8E58(&player->actor, player->ageProperties->unk_92 + NA_SE_VO_LI_DEMO_DAMAGE);
+ }
+ }
+
+ Math_Vec3f_Copy(&sp90, &ptr->unk_04);
+ sp90.y += 30.0f;
+
+ temp_f0_2 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp88, &sp90);
+ if (fabsf(temp_f0_2 - this->actor.floorHeight) > 200.0f) {
+ phi_s5 = true;
+ }
+
+ if ((ptr->unk_04.y <= temp_f0_2) || (phi_s5 != 0)) {
+ if (phi_s5 == 0) {
+ ptr->unk_04.y = temp_f0_2;
+ }
+ ptr->unk_10.y = 0.0f;
+ ptr->unk_1C.y = 0.0f;
+ if (ptr->unk_2A == 0) {
+ for (j = 0; j < 5; j++) {
+ func_80A599E8(this, &ptr->unk_04, 2);
+ }
+ Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_PLANT_BROKEN);
+ }
+ ptr->unk_2A++;
+ }
+ }
+ }
+ }
+ }
+}
+
+void func_80A5A184(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnWaterEffect* this = THIS;
+ GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+ u8 flag = false;
+ s16 i;
+
+ OPEN_DISPS(gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) {
+ if (ptr->unk_00 == 4) {
+ if (!flag) {
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004340);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0);
+ POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 500, 3600);
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, (u8)ptr->unk_38, 0, 0, (u8)ptr->unk_3C);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (ptr->unk_01 * -20) & 0x1FF,
+ 0x20, 0x80));
+
+ Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
+
+ if (ptr->unk_2A >= 2) {
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ } else {
+ Matrix_RotateY(func_800DFC68(GET_ACTIVE_CAM(globalCtx)), MTXMODE_APPLY);
+ }
+
+ Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY);
+
+ if ((i & 1) != 0) {
+ Matrix_InsertYRotation_f(M_PI, MTXMODE_APPLY);
+ }
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0043E8);
+
+ if ((ptr->unk_2A & 1) == 0) {
+ Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y + 5.0f, ptr->unk_04.z, MTXMODE_NEW);
+ Matrix_InsertXRotation_s(ptr->unk_28, MTXMODE_APPLY);
+ Matrix_Scale(ptr->unk_2C.z, ptr->unk_2C.z, ptr->unk_2C.z, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30);
+ }
+ }
+ }
+
+ POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP);
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+void func_80A5A534(Actor* thisx, GlobalContext* globalCtx) {
+ EnWaterEffect* this = THIS;
+ s32 i;
+
+ if (this->unk_E38 < 1.0f) {
+ Actor_MarkForDeath(&this->actor);
+ }
+
+ this->unk_DC4++;
+
+ if (this->unk_DC4 >= 0) {
+ for (i = 1; i < 4; i++) {
+ this->unk_DC8[i].z += this->unk_E08[i];
+ this->unk_E08[i] += this->unk_E18[i];
+ if (this->unk_DC8[i].z <= 0.0f) {
+ this->unk_DC8[i].z = 0.0f;
+ this->unk_E08[i] = 0.0f;
+ }
+ }
+
+ Math_ApproachF(&this->unk_DC8[1].y, 20.0f, 1.0f, 0.025f);
+ Math_ApproachF(&this->unk_DC8[2].y, 20.0f, 1.0f, 0.075f);
+ Math_ApproachF(&this->unk_DC8[3].y, 20.0f, 1.0f, 0.1f);
+
+ if (this->unk_DC4 >= 24) {
+ Math_ApproachF(&this->unk_DC8[4].y, 2.0f, 0.1f, 0.2f);
+ Math_ApproachZeroF(&this->unk_E2C, 1.0f, 26.0f);
+ Math_ApproachZeroF(&this->unk_E30, 1.0f, 26.0f);
+ Math_ApproachZeroF(&this->unk_E34, 1.0f, 24.0f);
+ if (this->unk_DC4 >= 50) {
+ Math_ApproachZeroF(&this->unk_E38, 1.0f, 3.75f);
+ }
+ }
+ }
+}
+
+void func_80A5A6B8(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnWaterEffect* this = THIS;
+ EnWaterEffectStruct* ptr = &this->unk_144[0];
+ u8 phi_s4 = false;
+ s16 i;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 165, 235, 255, 128);
+
+ Matrix_StatePush();
+ Matrix_StatePush();
+ Matrix_StatePush();
+
+ if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_778)) {
+ if (this->unk_E2C > 1.0f) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000DE0));
+ Matrix_Scale(this->unk_DC8[1].y, this->unk_DC8[1].z, this->unk_DC8[1].y, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E2C);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000420);
+ }
+
+ Matrix_StatePop();
+
+ if (this->unk_E30 > 1.0f) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E0C));
+ Matrix_Scale(this->unk_DC8[2].y, this->unk_DC8[2].z, this->unk_DC8[2].y, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E30);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000730);
+ }
+ Matrix_StatePop();
+ } else {
+ Matrix_StatePop();
+ Matrix_StatePop();
+ }
+
+ if ((this->unk_E34 > 1.0f) && (this->actor.params != ENWATEREFFECT_780)) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E40));
+ Matrix_Scale(this->unk_DC8[3].y, this->unk_DC8[3].z, this->unk_DC8[3].y, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E34);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000A48);
+ }
+
+ Matrix_StatePop();
+
+ if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_780)) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E58));
+ Matrix_Scale(this->unk_DC8[4].y, this->unk_DC8[4].z, this->unk_DC8[4].y, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E38);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000CD8);
+ }
+
+ if (this->actor.params == ENWATEREFFECT_777) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) {
+ if (ptr->unk_00 == 3) {
+ if (!phi_s4) {
+ func_8012C448(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0));
+ gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260);
+ phi_s4++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225,
+ ptr->unk_3C);
+
+ Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
+ Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY);
+ Matrix_InsertYRotation_f(ptr->unk_2C.z, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8);
+ }
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h
index f7805ddca..774b858cd 100644
--- a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h
+++ b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h
@@ -5,9 +5,41 @@
struct EnWaterEffect;
+typedef struct {
+ /* 0x00 */ u8 unk_00;
+ /* 0x01 */ u8 unk_01;
+ /* 0x04 */ Vec3f unk_04;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ Vec3f unk_1C;
+ /* 0x28 */ s16 unk_28;
+ /* 0x2A */ u8 unk_2A;
+ /* 0x2C */ Vec3f unk_2C;
+ /* 0x38 */ f32 unk_38;
+ /* 0x3C */ s16 unk_3C;
+} EnWaterEffectStruct; // size = 0x40
+
+enum {
+ /* 0x 1 */ ENWATEREFFECT_1 = 1,
+ /* 0x309 */ ENWATEREFFECT_777 = 777,
+ /* 0x30A */ ENWATEREFFECT_778,
+ /* 0x30B */ ENWATEREFFECT_779,
+ /* 0x30C */ ENWATEREFFECT_780,
+};
+
typedef struct EnWaterEffect {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0xCF8];
+ /* 0x144 */ EnWaterEffectStruct unk_144[50];
+ /* 0xDC4 */ s16 unk_DC4;
+ /* 0xDC6 */ s16 unk_DC6;
+ /* 0xDC8 */ Vec3f unk_DC8[5];
+ /* 0xE04 */ UNK_TYPE1 unk_E04[4];
+ /* 0xE04 */ f32 unk_E08[4];
+ /* 0xE18 */ f32 unk_E18[4];
+ /* 0xE28 */ UNK_TYPE1 unk_E28[4];
+ /* 0xE2C */ f32 unk_E2C;
+ /* 0xE30 */ f32 unk_E30;
+ /* 0xE34 */ f32 unk_E34;
+ /* 0xE38 */ f32 unk_E38;
} EnWaterEffect; // size = 0xE3C
extern const ActorInit En_Water_Effect_InitVars;
diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
index 5bbf27029..1388260cf 100644
--- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
+++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
@@ -11,9 +11,13 @@ typedef struct EnWiz {
/* 0x0000 */ Actor actor;
/* 0x0144 */ char unk_144[0x268];
/* 0x03AC */ EnWizActionFunc actionFunc;
- /* 0x03B0 */ char unk_3B0[0x98];
+ /* 0x03B0 */ char unk_3B0[0xA];
+ /* 0x03BA */ s16 unk_3BA;
+ /* 0x03BC */ char unk_3BC[0x8C];
/* 0x0448 */ s32 unk_448;
- /* 0x044C */ char unk_44C[0x934];
+ /* 0x044C */ char unk_44C[0x2FE];
+ /* 0x074A */ s16 unk_74A;
+ /* 0x074C */ char unk_74C[0x634];
} EnWiz; // size = 0xD80
extern const ActorInit En_Wiz_InitVars;
diff --git a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c
index 480bdaeaa..4853331bb 100644
--- a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c
+++ b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c
@@ -5,6 +5,8 @@
*/
#include "z_en_wiz_fire.h"
+#include "overlays/actors/ovl_En_Wiz/z_en_wiz.h"
+#include "objects/object_wiz/object_wiz.h"
#define FLAGS 0x08000015
@@ -21,8 +23,13 @@ void func_80A49F38(EnWizFire* this, GlobalContext* globalCtx);
void func_80A49FD8(EnWizFire* this, GlobalContext* globalCtx);
void func_80A4A11C(EnWizFire* this, GlobalContext* globalCtx);
void func_80A4A608(EnWizFire* this, GlobalContext* globalCtx);
+void func_80A4BAB4(Actor* thisx, GlobalContext* globalCtx);
+void func_80A4BC74(EnWizFire* this, Vec3f* arg1, Vec3f* arg2);
+void func_80A4BDDC(EnWizFire* this, GlobalContext* globalCtx);
+void func_80A4BF78(EnWizFire* this, GlobalContext* globalCtx);
+
+static s32 D_80A4C1C0 = 0;
-#if 0
const ActorInit En_Wiz_Fire_InitVars = {
ACTOR_EN_WIZ_FIRE,
ACTORCAT_ENEMY,
@@ -35,51 +42,838 @@ const ActorInit En_Wiz_Fire_InitVars = {
(ActorFunc)EnWizFire_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A4C1E4 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x09, 0x10 }, { 0x01001202, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x09, 0x10 },
+ { 0x01001202, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 0, 0, 0, { 0, 0, 0 } },
};
-#endif
+void EnWizFire_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnWizFire* this = THIS;
-extern ColliderCylinderInit D_80A4C1E4;
+ Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ this->unk_162 = this->actor.params;
+ this->actor.targetMode = 3;
+ this->unk_172 = 10;
+ this->unk_1FC = 255.0f;
+ this->actor.flags &= ~1;
-extern UNK_TYPE D_06000FD8;
-extern UNK_TYPE D_06002630;
-extern UNK_TYPE D_06002B40;
-extern UNK_TYPE D_06003120;
-extern UNK_TYPE D_06005190;
+ if (!func_8012405C(globalCtx)) {
+ this->collider.info.toucher.dmgFlags = 0x20000000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Init.s")
+ switch (this->unk_162) {
+ case 4:
+ this->unk_166 = 1;
+ this->collider.info.toucher.damage = 8;
+ this->collider.info.toucher.effect = 2;
+ this->collider.info.bumper.dmgFlags = (0x1000000 | 0x800 | 0x200 | 0x2);
+ this->unk_162 = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Destroy.s")
+ case 0:
+ if (this->unk_162 == 4) {
+ this->unk_162 = 0;
+ this->collider.info.toucher.damage = 8;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4984C.s")
+ case 1:
+ case 3:
+ this->actionFunc = func_80A4984C;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49A44.s")
+ case 2:
+ this->actor.draw = func_80A4BAB4;
+ this->unk_170 = Rand_S16Offset(0, 10000);
+ this->unk_160 = 1;
+ this->collider.info.toucher.damage = 2;
+ this->actionFunc = func_80A49F38;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49F38.s")
+void EnWizFire_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnWizFire* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49FD8.s")
+ if (this->unk_162 == 0) {
+ globalCtx->envCtx.unk_8C.fogColor[2] = 0;
+ globalCtx->envCtx.unk_8C.fogColor[1] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.fogColor[0] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor2[2] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor2[1] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor2[0] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor1[2] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor1[1] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.diffuseColor1[0] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.ambientColor[2] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.ambientColor[1] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.ambientColor[0] = globalCtx->envCtx.unk_8C.fogColor[2];
+ globalCtx->envCtx.unk_8C.fogNear = globalCtx->envCtx.unk_8C.fogColor[2];
+ }
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4A11C.s")
+void func_80A4984C(EnWizFire* this, GlobalContext* globalCtx) {
+ Vec3f sp44 = { 0.0f, 0.0f, 0.0f };
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4A608.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_178); i++) {
+ this->unk_178[i] = this->actor.world.pos;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Update.s")
+ this->unk_16E = 0;
+ Matrix_StatePush();
+ Matrix_RotateY(this->actor.world.rot.y, MTXMODE_NEW);
+ Matrix_InsertXRotation_s(this->actor.world.rot.x, MTXMODE_APPLY);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4B0C8.s")
+ if (this->unk_162 != 0) {
+ sp44.z = randPlusMinusPoint5Scaled(2.0f) + 8.0f;
+ } else {
+ sp44.z = 12.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4B33C.s")
+ Matrix_MultiplyVector3fByState(&sp44, &this->actor.velocity);
+ Matrix_StatePop();
+ this->actor.world.rot.x = this->actor.world.rot.y = this->actor.world.rot.z = 0;
+ this->unk_168 = 50;
+ if (this->unk_162 != 0) {
+ this->actor.velocity.y = 10.0f;
+ this->actor.gravity = -1.0f;
+ this->unk_150 = 0.01f;
+ } else {
+ this->unk_150 = 0.02f;
+ this->unk_168 = 100;
+ }
+ this->unk_160 = 0;
+ this->actionFunc = func_80A49A44;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Draw.s")
+void func_80A49A44(EnWizFire* this, GlobalContext* globalCtx) {
+ Vec3f sp54 = { 0.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BAB4.s")
+ this->actor.world.rot.z += 5000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BC74.s")
+ if (this->unk_162 != 0) {
+ this->unk_150 = 0.01f;
+ } else {
+ this->unk_150 = 0.02f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BDDC.s")
+ if ((this->unk_168 == 0) && (this->unk_14C < 0.001f)) {
+ Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f);
+ this->unk_160 = 3;
+ this->unk_16A = 0;
+ this->actionFunc = func_80A4A608;
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BF78.s")
+ if (this->unk_168 == 0) {
+ this->unk_150 = 0.0f;
+ }
+
+ Math_ApproachF(&this->unk_14C, this->unk_150, 0.2f, 0.01f);
+
+ if (this->unk_172 == 0) {
+ if ((this->actor.bgCheckFlags & 8) && (this->unk_162 == 0) && (this->unk_168 != 0) &&
+ (this->actor.bgCheckFlags & 8)) {
+ D_80A4C1C0 = 0;
+ this->unk_168 = 0;
+ this->unk_150 = 0.0f;
+ }
+ }
+
+ if ((this->actor.bgCheckFlags & 1) && (this->unk_16A == 0)) {
+ s32 i;
+ s16 phi_s0;
+ s32 temp;
+
+ if (this->unk_162 == 1) {
+ this->unk_16A = 10;
+
+ Matrix_StatePush();
+ Matrix_RotateY((s16)randPlusMinusPoint5Scaled(0x100) + this->actor.world.rot.y, MTXMODE_NEW);
+ sp54.z = randPlusMinusPoint5Scaled(2.0f) + 8.0f;
+ Matrix_MultiplyVector3fByState(&sp54, &this->actor.velocity);
+ Matrix_StatePop();
+
+ this->actor.velocity.y = 6.0f;
+ this->actor.gravity = -0.7f;
+
+ if (this->unk_164 == 0) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WIZ_FIRE, this->actor.world.pos.x,
+ this->actor.world.pos.y - 10.0f, this->actor.world.pos.z, 0, 0, 0, 2);
+ this->unk_164 = 1;
+ }
+
+ this->unk_168 = 0;
+ this->unk_14C = 0.0f;
+ Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f);
+ this->unk_160 = 3;
+ this->unk_16A = 0;
+ this->actionFunc = func_80A4A608;
+ return;
+ }
+
+ if ((this->unk_162 == 0) && (this->unk_168 != 0)) {
+ if (this->actor.floorBgId == BGCHECK_SCENE) {
+ this->unk_16A = 100;
+ if (this->unk_166 == 0) {
+ phi_s0 = 0;
+
+ for (i = 0; i < 5; i++) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WIZ_FIRE, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, phi_s0, 0, 1);
+ phi_s0 += BINANG_ADD((s32)randPlusMinusPoint5Scaled(0x1000), 0x3333);
+ }
+
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION);
+ this->unk_16A = Rand_S16Offset(70, 30);
+ if (this->unk_16A != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_EXP - SFX_FLAG);
+ }
+ } else if (this->unk_16A != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+ Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f);
+ this->unk_168 = 0;
+ this->unk_160 = 2;
+ this->unk_14C = 0.0f;
+ this->actionFunc = func_80A4A11C;
+ }
+ return;
+ }
+ }
+
+ if ((this->unk_162 != 3) && (this->unk_168 != 0)) {
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ if (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000) {
+ this->unk_168 = 0;
+ this->unk_148 = 1;
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT);
+ }
+ }
+
+ if (func_8012405C(globalCtx) && (this->collider.base.atFlags & AT_BOUNCED)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_MG);
+ this->collider.base.atFlags &= ~(AT_TYPE_ENEMY | AT_BOUNCED | AT_HIT);
+ this->collider.base.atFlags |= AT_TYPE_PLAYER;
+ this->collider.info.toucher.dmgFlags = 0x20;
+ this->collider.info.toucher.damage = 2;
+ this->unk_168 = 100;
+ this->unk_162 = 3;
+ this->actor.velocity.x *= -1.0f;
+ this->actor.velocity.y *= -0.5f;
+ this->actor.velocity.z *= -1.0f;
+
+ if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) &&
+ (this->actor.parent->update != NULL)) {
+ ((EnWiz*)this->actor.parent)->unk_3BA = 0;
+ }
+ }
+ }
+}
+
+void func_80A49F38(EnWizFire* this, GlobalContext* globalCtx) {
+ this->unk_150 = 0.02f;
+ this->unk_168 = Rand_S16Offset(50, 50);
+ this->unk_154 = randPlusMinusPoint5Scaled(1.0f) * 0.007f;
+ this->unk_158 = randPlusMinusPoint5Scaled(1.0f) * 0.005f;
+ this->unk_15C = randPlusMinusPoint5Scaled(1.0f) * 0.007f;
+ this->actionFunc = func_80A49FD8;
+}
+
+void func_80A49FD8(EnWizFire* this, GlobalContext* globalCtx) {
+ if (this->unk_168 > 10) {
+ Math_ApproachF(&this->unk_14C, this->unk_150, 0.3f, 0.01f);
+ } else {
+ Math_ApproachF(&this->unk_14C, 2.0f * this->unk_150, 0.2f, 0.002f);
+ Math_ApproachZeroF(&this->unk_1FC, 1.0f, 35.0f);
+ if ((this->unk_168 == 0) && (this->unk_1FC < 2.0f)) {
+ Actor_MarkForDeath(&this->actor);
+ }
+ return;
+ }
+
+ if (this->collider.base.acFlags & AC_HIT) {
+ if (this->unk_168 != 0) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ if (this->unk_168 > 10) {
+ this->unk_168 -= 10;
+ }
+
+ if (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000) {
+ this->unk_168 = 0;
+ this->unk_148 = 1;
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT);
+ }
+ }
+ }
+
+ if (this->unk_168 != 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_BURN_OUT - SFX_FLAG);
+ }
+}
+
+void func_80A4A11C(EnWizFire* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) &&
+ (this->actor.parent->update != NULL) && (this->actor.parent->colChkInfo.health == 0)) {
+ this->unk_16A = 0;
+ this->unk_174 = 1;
+ }
+
+ this->unk_16E++;
+
+ if (this->unk_16E > 10) {
+ this->unk_16E = 10;
+ }
+
+ if (this->unk_16A != 0) {
+ Math_ApproachF(&this->unk_200, 60.0f, 0.5f, 10.0f);
+ if (this->unk_166 == 1) {
+ Vec3f sp40 = { 0.0f, 0.0f, 0.0f };
+ Vec3f sp34;
+
+ sp40.x = randPlusMinusPoint5Scaled(3.0f) / 10.0f;
+ sp40.y = 0.23f;
+ sp40.z = randPlusMinusPoint5Scaled(3.0f) / 10.0f;
+
+ Math_Vec3f_Copy(&sp34, &this->actor.world.pos);
+ sp34.x += randPlusMinusPoint5Scaled(150.0f);
+ sp34.z += randPlusMinusPoint5Scaled(150.0f);
+
+ Math_ApproachF(&this->unk_1F0, 0.022f, 0.3f, 0.01f);
+ this->collider.dim.radius = this->unk_1F0 * 4300.0f;
+ this->collider.dim.height = 30;
+ this->collider.dim.yShift = 15;
+ func_80A4BC74(this, &sp34, &sp40);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ return;
+ }
+
+ Math_ApproachF(&this->unk_1F0, 0.02f, 0.3f, 0.002f);
+ Math_ApproachF(&this->unk_1F8, 0.02f, 0.3f, 0.002f);
+ Math_ApproachF(&this->unk_1F4, 0.02f, 0.3f, 0.2f);
+ this->collider.dim.radius = this->unk_1F0 * 4000.0f;
+ this->collider.dim.height = this->unk_1F4 * 1850.0f;
+ this->collider.dim.yShift = -15;
+
+ if (this->collider.dim.height < 2) {
+ this->collider.dim.height = 2;
+ }
+
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ if ((D_80A4C1C0 == 0) && (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000)) {
+ D_80A4C1C0 = 1;
+ this->unk_148 = 1;
+ this->unk_16A = 0;
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT);
+ }
+ }
+ this->actor.world.pos.y = this->actor.floorHeight + 10.0f;
+ Actor_SetHeight(&this->actor, 0.0f);
+ return;
+ }
+
+ Math_ApproachZeroF(&this->unk_200, 0.2f, 3.0f);
+
+ if (this->unk_166 == 1) {
+ Math_ApproachZeroF(&this->unk_1F0, 0.046f, 0.001f);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+
+ if (this->unk_164 == 0) {
+ if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) && (this->unk_1F0 < 0.05f)) {
+ EnWiz* wiz = (EnWiz*)this->actor.parent;
+
+ this->collider.dim.yShift = -15;
+ this->unk_164 = 1;
+ wiz->unk_3BA = 0;
+ }
+ }
+
+ if ((this->unk_164 != 0) && (this->unk_1F0 < 0.05f)) {
+ Math_ApproachZeroF(&this->unk_1FC, 1.0f, 5.0f);
+ }
+
+ if ((this->unk_1F0 < 0.001f) && (this->unk_204 < 0.001f)) {
+ D_80A4C1C0 = 0;
+ Actor_MarkForDeath(&this->actor);
+ }
+ return;
+ }
+
+ Math_ApproachZeroF(&this->unk_1F4, 0.1f, 0.01f);
+
+ if (this->unk_1F4 < 0.01f) {
+ Math_ApproachZeroF(&this->unk_1FC, 1.0f, 10.0f);
+ if ((this->unk_1FC < 10.0f) && (this->unk_204 < 0.001f)) {
+ D_80A4C1C0 = 0;
+ if ((this->actor.parent != NULL) && (this->unk_162 == 0) && (this->actor.parent->id == ACTOR_EN_WIZ) &&
+ (this->actor.parent->update != NULL)) {
+ EnWiz* wiz = (EnWiz*)this->actor.parent;
+
+ wiz->unk_3BA = 0;
+ }
+ Actor_MarkForDeath(&this->actor);
+ }
+ }
+}
+
+void func_80A4A608(EnWizFire* this, GlobalContext* globalCtx) {
+ if (this->unk_16A == 0) {
+ this->unk_16A = 2;
+ this->unk_16E++;
+ if (this->unk_16E >= 6) {
+ if ((this->actor.parent != NULL) && (this->unk_162 == 0) && (this->actor.parent->id == ACTOR_EN_WIZ)) {
+ EnWiz* wiz = (EnWiz*)this->actor.parent;
+
+ D_80A4C1C0 = 0;
+ if (wiz->actor.update != NULL) {
+ wiz->unk_3BA = 0;
+ }
+ }
+ Actor_MarkForDeath(&this->actor);
+ }
+ }
+}
+
+void EnWizFire_Update(Actor* thisx, GlobalContext* globalCtx2) {
+ static Color_RGB8 D_80A4C234[] = {
+ { 100, 40, 40 }, { 180, 0x78, 80 }, { 155, 80, 80 }, { 125, 20, 0 },
+ { 0, 0, 0 }, { 200, 250, 250 }, { 100, 250, 250 }, { 225, 255, 235 },
+ };
+ static Color_RGBA8 D_80A4C24C = { 250, 250, 250, 255 };
+ static Color_RGBA8 D_80A4C250 = { 180, 180, 180, 255 };
+ GlobalContext* globalCtx = globalCtx2;
+ EnWizFire* this = THIS;
+ Player* player = GET_PLAYER(globalCtx);
+ s32 j;
+ s16 temp_s0;
+ s16 idx;
+
+ Actor_SetScale(&this->actor, this->unk_14C);
+ func_80A4BDDC(this, globalCtx);
+ this->unk_204 = this->unk_200 / 60.0f;
+
+ if (this->unk_162 == 0) {
+ Actor* wiz = this->actor.parent;
+
+ if ((wiz != NULL) && (wiz->id == ACTOR_EN_WIZ) && (wiz->update != NULL) && (((EnWiz*)wiz)->unk_74A != 2)) {
+ f32 phi_f0;
+
+ idx = this->unk_166 * 4;
+
+ phi_f0 = 970.0f;
+ if (this->unk_166 == 0) {
+ phi_f0 = 968.0f;
+ }
+
+ globalCtx->envCtx.unk_8C.fogNear = (phi_f0 - (s16)globalCtx->envCtx.unk_C4.fogNear) * this->unk_204;
+
+ globalCtx->envCtx.unk_8C.ambientColor[0] =
+ ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.ambientColor[0]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.ambientColor[1] =
+ ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.ambientColor[1]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.ambientColor[2] =
+ ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.ambientColor[2]) * this->unk_204;
+
+ idx++;
+ globalCtx->envCtx.unk_8C.diffuseColor1[0] =
+ ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor1[0]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.diffuseColor1[1] =
+ ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor1[1]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.diffuseColor1[2] =
+ ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor1[2]) * this->unk_204;
+
+ idx++;
+ globalCtx->envCtx.unk_8C.diffuseColor2[0] =
+ ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor[0]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.diffuseColor2[1] =
+ ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor[1]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.diffuseColor2[2] =
+ ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor[2]) * this->unk_204;
+
+ idx++;
+ globalCtx->envCtx.unk_8C.fogColor[0] =
+ ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.fogColor[0]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.fogColor[1] =
+ ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.fogColor[1]) * this->unk_204;
+ globalCtx->envCtx.unk_8C.fogColor[2] =
+ ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.fogColor[2]) * this->unk_204;
+ }
+ }
+
+ this->unk_170++;
+
+ this->actionFunc(this, globalCtx);
+
+ this->actor.shape.yOffset = 10.0f;
+ Actor_ApplyMovement(&this->actor);
+
+ this->unk_178[0] = this->actor.world.pos;
+
+ for (j = 8; j >= 0; j--) {
+ this->unk_178[j + 1] = this->unk_178[j];
+ }
+
+ this->actor.velocity.y += this->actor.gravity;
+
+ if (this->unk_172 != 0) {
+ this->unk_172--;
+ }
+
+ if (this->unk_168 != 0) {
+ this->unk_168--;
+ }
+
+ if (this->unk_16C != 0) {
+ this->unk_16C--;
+ }
+
+ if (this->unk_16A != 0) {
+ this->unk_16A--;
+ }
+
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 5.0f, 10, 0x1D);
+
+ if (((this->unk_148 != 0) || (D_80A4C1C0 != 0)) && (this->unk_16C == 0)) {
+ Vec3f sp70;
+ Vec3f sp64;
+ Vec3f sp58;
+ f32 sp54;
+ s32 i;
+
+ sp70.x = 0.0f;
+ sp70.y = 1.0f;
+ sp70.z = 0.0f;
+ sp64.x = 0.0f;
+ sp64.y = 1.0f;
+ sp64.z = 0.0f;
+
+ sp54 = Rand_S16Offset(20, 10);
+ if (this->unk_162 == 0) {
+ sp54 = Rand_S16Offset(40, 20);
+ }
+
+ this->unk_16C = Rand_S16Offset(2, 2);
+
+ for (i = 0; i < 2; i++) {
+ temp_s0 = Rand_S16Offset(20, 20);
+ sp58.x = ((f32)((Rand_ZeroOne() < 0.5f) ? -1 : 1) * temp_s0) + this->actor.world.pos.x;
+ sp58.y = (Rand_ZeroOne() * 20.0f) + this->actor.floorHeight;
+ temp_s0 = Rand_S16Offset(20, 20);
+ sp58.z = ((f32)((Rand_ZeroOne() < .5f) ? -1 : 1) * temp_s0) + this->actor.world.pos.z;
+ func_800B0DE0(globalCtx, &sp58, &sp64, &sp70, &D_80A4C24C, &D_80A4C250, Rand_S16Offset(350, 100), sp54);
+ }
+ }
+
+ if (this->unk_160 < 2) {
+ this->collider.dim.radius = (this->unk_14C * 15.0f) + 25.0f;
+ this->collider.dim.height = (this->unk_14C * 15.0f) + 25.0f;
+ this->collider.dim.yShift = (this->unk_14C * -0.75f) - 5.0f;
+ }
+
+ if (this->unk_162 == 2) {
+ this->collider.dim.radius = 10;
+ this->collider.dim.height = this->unk_14C * 5000.0f;
+ this->collider.dim.yShift = 0;
+ }
+
+ if (this->collider.base.atFlags & AT_HIT) {
+ this->collider.base.atFlags &= ~AT_HIT;
+ if (this->unk_162 == 0) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_LAUGH2);
+ if (player->invincibilityTimer > 0) {
+ player->invincibilityTimer += 40;
+ if (this->unk_166 != 0) {
+ player->invincibilityTimer += 50;
+ this->unk_174 = 1;
+ }
+ }
+ }
+ }
+
+ if ((player->stateFlags2 & 0x4000) && (player->unk_AE8 < 90)) {
+ player->unk_AE8 = 90;
+ }
+
+ if ((this->unk_148 == 0) && (D_80A4C1C0 == 0) && ((this->unk_162 != 0) || (this->unk_1FC > 200.0f))) {
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ if (player->invincibilityTimer == 0) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ }
+}
+
+void func_80A4B0C8(EnWizFire* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if ((this->unk_162 == 0) && (this->unk_160 == 2)) {
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_Scale(this->unk_1F0, this->unk_1F0, this->unk_1F0, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_1FC);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 40, 30, 80);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_005190);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 215, 215, 215, (s8)this->unk_1FC);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -globalCtx->state.frames & 0x7F,
+ -globalCtx->state.frames & 0x7F, 0x20, 0x40, 1, globalCtx->state.frames & 0xFF,
+ globalCtx->state.frames & 0xFF, 0x10, 0x10));
+
+ Matrix_RotateY(0, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_005750);
+ }
+
+ func_80A4BF78(this, globalCtx);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A4B33C(EnWizFire* this, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if ((this->unk_162 == 0) && (this->unk_160 == 2)) {
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ Matrix_StatePush();
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_Scale(this->unk_1F0, this->unk_1F0, this->unk_1F0, MTXMODE_APPLY);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -globalCtx->state.frames % 128, 0, 0x20, 0x20, 1,
+ (globalCtx->state.frames * 2) % 128, 0, 0x20, 0x20));
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 100, 40, 0, (s8)this->unk_1FC);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 245, 255, 128);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003120);
+
+ Matrix_StatePop();
+ Matrix_StatePush();
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->state.frames % 128,
+ (-globalCtx->state.frames * 6) % 256, 0x20, 0x40, 1,
+ (globalCtx->state.frames * 2) % 128, (-globalCtx->state.frames * 6) % 256, 0x20,
+ 0x40));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 80, 0, 0, (s8)this->unk_1FC);
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 100);
+
+ Matrix_Scale(this->unk_1F8, this->unk_1F8, this->unk_1F8, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003640);
+
+ Matrix_StatePop();
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, 0);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (-globalCtx->state.frames * 3) % 128, 0, 0x20, 0x20, 1,
+ 0, (-globalCtx->state.frames * 10) % 256, 0x20, 0x40));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 100, 50, 0, 255);
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 200, 235, 240, 128);
+
+ Matrix_Scale(this->unk_1F4, this->unk_1F4, this->unk_1F4, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003FC0);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void EnWizFire_Draw(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ EnWizFire* this = THIS;
+ s32 i;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ Matrix_StatePush();
+
+ for (i = 9; i >= this->unk_16E; i--) {
+ f32 temp_f20 = this->actor.scale.x - (i * -0.0019f);
+
+ if (temp_f20 > 0.0f) {
+ if (this->unk_166 == 0) {
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255 - (i * 25), 0, 255 - (i * 25));
+ gDPSetEnvColor(POLY_XLU_DISP++, 255 - (i * 25), 0, 0, 0);
+ } else {
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255 - (i * 7), 255 - (i * 3), 255 - (i * 3), 255 - (i * 25));
+ gDPSetEnvColor(POLY_XLU_DISP++, 220, 255, 235, 0);
+ }
+
+ Matrix_InsertTranslation(this->unk_178[i].x, this->unk_178[i].y + this->actor.shape.yOffset,
+ this->unk_178[i].z, MTXMODE_NEW);
+ Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_InsertZRotation_s(this->actor.world.rot.z, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_002B40);
+ }
+ }
+
+ Matrix_StatePop();
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+
+ if (this->unk_166 == 0) {
+ func_80A4B33C(this, globalCtx);
+ } else {
+ func_80A4B0C8(this, globalCtx);
+ }
+}
+
+void func_80A4BAB4(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ EnWizFire* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight + 20.0f, this->actor.world.pos.z,
+ MTXMODE_NEW);
+ Matrix_Scale(this->unk_14C + this->unk_154, this->unk_14C + this->unk_158, this->unk_14C + this->unk_15C,
+ MTXMODE_APPLY);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x20, 1, this->unk_170 & 0x7F,
+ (-this->unk_170 * 10) & 0x7F, 0x20, 0x20));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 100, 50, 0, (s8)this->unk_1FC);
+ gDPSetEnvColor(POLY_XLU_DISP++, 200, 235, 245, 255);
+
+ Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_002630);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A4BC74(EnWizFire* this, Vec3f* arg1, Vec3f* arg2) {
+ s16 i;
+ EnWizFireStruct* ptr = this->unk_254;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) {
+ if (ptr->unk_00 == 0) {
+ ptr->unk_00 = 1;
+ Math_Vec3f_Copy(&ptr->unk_1C, &gZeroVec3f);
+ ptr->unk_01 = Rand_ZeroFloat(100.0f);
+ ptr->unk_10 = *arg1;
+ ptr->unk_28 = *arg2;
+ ptr->unk_0C = (Rand_ZeroFloat(5.0f) + 20.0f) * 0.001f;
+ ptr->unk_08 = 0;
+ ptr->unk_06 = 0;
+ break;
+ }
+ }
+}
+
+void func_80A4BDDC(EnWizFire* this, GlobalContext* globalCtx) {
+ s32 i;
+ EnWizFireStruct* ptr = &this->unk_254[0];
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) {
+ if (ptr->unk_00 != 0) {
+ ptr->unk_01++;
+
+ ptr->unk_10.x += ptr->unk_1C.x;
+ ptr->unk_10.y += ptr->unk_1C.y;
+ ptr->unk_10.z += ptr->unk_1C.z;
+
+ ptr->unk_1C.x += ptr->unk_28.x;
+ ptr->unk_1C.y += ptr->unk_28.y;
+ ptr->unk_1C.z += ptr->unk_28.z;
+
+ if (ptr->unk_08 == 0) {
+ ptr->unk_06 += 10;
+ if (ptr->unk_06 >= 100) {
+ ptr->unk_08 = 1;
+ }
+ } else {
+ ptr->unk_06 -= 8;
+ if (ptr->unk_06 <= 0) {
+ ptr->unk_06 = 0;
+ ptr->unk_00 = 0;
+ }
+ }
+ }
+ }
+}
+
+void func_80A4BF78(EnWizFire* this, GlobalContext* globalCtx) {
+ s16 i;
+ u8 flag;
+ EnWizFireStruct* ptr = &this->unk_254[0];
+ GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
+
+ OPEN_DISPS(gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ flag = false;
+ for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) {
+ if (ptr->unk_00 != 0) {
+ if (!flag) {
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_000E70);
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, ptr->unk_06);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (ptr->unk_01 * 3) & 0x7F,
+ (ptr->unk_01 * 0xF) & 0xFF, 0x20, 0x40, 1, 0, 0, 0x20, 0x20));
+
+ Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(ptr->unk_0C, ptr->unk_0C, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_AA_ZB_XLU_SURF2);
+ gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BACK | G_FOG);
+ gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_000FD8);
+ }
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h
index 0f5b705f5..df396da97 100644
--- a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h
+++ b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h
@@ -7,10 +7,48 @@ struct EnWizFire;
typedef void (*EnWizFireActionFunc)(struct EnWizFire*, GlobalContext*);
+typedef struct {
+ /* 0x00 */ u8 unk_00;
+ /* 0x01 */ u8 unk_01;
+ /* 0x02 */ UNK_TYPE1 unk02[0x4];
+ /* 0x06 */ s16 unk_06;
+ /* 0x08 */ s16 unk_08;
+ /* 0x0A */ UNK_TYPE1 unk0A[0x2];
+ /* 0x0C */ f32 unk_0C;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ Vec3f unk_1C;
+ /* 0x28 */ Vec3f unk_28;
+} EnWizFireStruct; // size = 0x34
+
typedef struct EnWizFire {
/* 0x0000 */ Actor actor;
/* 0x0144 */ EnWizFireActionFunc actionFunc;
- /* 0x0148 */ char unk_148[0x29AC];
+ /* 0x0148 */ u8 unk_148;
+ /* 0x014C */ f32 unk_14C;
+ /* 0x0150 */ f32 unk_150;
+ /* 0x0154 */ f32 unk_154;
+ /* 0x0158 */ f32 unk_158;
+ /* 0x015C */ f32 unk_15C;
+ /* 0x0160 */ s16 unk_160;
+ /* 0x0162 */ s16 unk_162;
+ /* 0x0164 */ u8 unk_164;
+ /* 0x0166 */ s16 unk_166;
+ /* 0x0168 */ s16 unk_168;
+ /* 0x016A */ s16 unk_16A;
+ /* 0x016C */ s16 unk_16C;
+ /* 0x016E */ s16 unk_16E;
+ /* 0x0170 */ s16 unk_170;
+ /* 0x0172 */ s16 unk_172;
+ /* 0x0174 */ s8 unk_174;
+ /* 0x0178 */ Vec3f unk_178[10];
+ /* 0x01F0 */ f32 unk_1F0;
+ /* 0x01F4 */ f32 unk_1F4;
+ /* 0x01F8 */ f32 unk_1F8;
+ /* 0x01FC */ f32 unk_1FC;
+ /* 0x0200 */ f32 unk_200;
+ /* 0x0204 */ f32 unk_204;
+ /* 0x0208 */ ColliderCylinder collider;
+ /* 0x0254 */ EnWizFireStruct unk_254[200];
} EnWizFire; // size = 0x2AF4
extern const ActorInit En_Wiz_Fire_InitVars;
diff --git a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c
index 98f66c014..60da4d5b5 100644
--- a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c
+++ b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c
@@ -14,7 +14,9 @@ void ObjDowsing_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjDowsing_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjDowsing_Update(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+s32 ObjDowsing_GetFlag(ObjDowsing* this, GlobalContext* globalCtx);
+s32 ObjDowsing_CheckValidSpawn(ObjDowsing* this, GlobalContext* globalCtx);
+
const ActorInit Obj_Dowsing_InitVars = {
ACTOR_OBJ_DOWSING,
ACTORCAT_ITEMACTION,
@@ -27,14 +29,42 @@ const ActorInit Obj_Dowsing_InitVars = {
(ActorFunc)NULL,
};
-#endif
+s32 ObjDowsing_GetFlag(ObjDowsing* this, GlobalContext* globalCtx) {
+ s32 type = DOWSING_GET_TYPE(&this->actor);
+ s32 flag = DOWSING_GET_FLAG(&this->actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/func_80B23D50.s")
+ if (type == DOWSING_COLLECTIBLE) {
+ return Actor_GetCollectibleFlag(globalCtx, flag);
+ } else if (type == DOWSING_CHEST) {
+ return Actor_GetChestFlag(globalCtx, flag);
+ } else if (type == DOWSING_SWITCH) {
+ return Flags_GetSwitch(globalCtx, flag);
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/func_80B23DD0.s")
+s32 ObjDowsing_CheckValidSpawn(ObjDowsing* this, GlobalContext* globalCtx) {
+ if (ObjDowsing_GetFlag(this, globalCtx)) {
+ Actor_MarkForDeath(&this->actor);
+ return true;
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Init.s")
+void ObjDowsing_Init(Actor* thisx, GlobalContext* globalCtx) {
+ ObjDowsing* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Destroy.s")
+ ObjDowsing_CheckValidSpawn(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Update.s")
+void ObjDowsing_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void ObjDowsing_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjDowsing* this = THIS;
+
+ if (!ObjDowsing_CheckValidSpawn(this, globalCtx)) {
+ func_800B8C50(thisx, globalCtx);
+ }
+}
diff --git a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h
index 5a2982cab..7b1125a28 100644
--- a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h
+++ b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h
@@ -3,8 +3,17 @@
#include "global.h"
+#define DOWSING_GET_TYPE(thisx) ((thisx)->params >> 7)
+#define DOWSING_GET_FLAG(thisx) ((thisx)->params & 0x7F)
+
struct ObjDowsing;
+typedef enum {
+ /* 1 */ DOWSING_COLLECTIBLE = 1,
+ /* 2 */ DOWSING_CHEST,
+ /* 3 */ DOWSING_SWITCH
+} DowsingType;
+
typedef struct ObjDowsing {
/* 0x000 */ Actor actor;
} ObjDowsing; // size = 0x144
diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c
index a4eb9ad9a..56f9b9f7a 100644
--- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c
+++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c
@@ -5,6 +5,7 @@
*/
#include "z_obj_etcetera.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00000010
@@ -14,8 +15,8 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx);
-void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx);
-void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx);
+void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, GlobalContext* globalCtx);
+void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, GlobalContext* globalCtx);
void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx);
void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx);
void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx);
@@ -105,6 +106,11 @@ void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx) {
Collider_DestroyCylinder(globalCtx, &this->collider);
}
+/**
+ * This function will make the flower oscillate on the X and Z axes in most situations
+ * where something interacts with it. When the player launches out of the flower, the
+ * oscillation is handled by ObjEtcetera_DoBounceOscillation instead.
+ */
void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx) {
if (this->oscillationTimer > 0) {
s32 requiredScopeTemp;
@@ -119,10 +125,11 @@ void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx
}
}
-void ObjEtcetera_StartSmallFlutterAnimation(ObjEtcetera* this) {
- Animation_Change(&this->skelAnime, &D_040117A8, 1.0f, 0.0f, Animation_GetLastFrame(&D_040117A8), 2, 0.0f);
+void ObjEtcetera_StartRustleAnimation(ObjEtcetera* this) {
+ Animation_Change(&this->skelAnime, &gDekuFlowerRustleAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gDekuFlowerRustleAnim), 2, 0.0f);
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
- this->actionFunc = ObjEtcetera_PlaySmallFlutterAnimation;
+ this->actionFunc = ObjEtcetera_PlayRustleAnimation;
}
void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) {
@@ -131,12 +138,13 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) {
if ((player->stateFlags3 & 0x200) && (this->dyna.actor.xzDistToPlayer < 20.0f)) {
// Player is launching out of the Deku Flower
- Animation_Change(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, Animation_GetLastFrame(&D_0400EB7C), 2, 0.0f);
+ Animation_Change(&this->skelAnime, &gDekuFlowerBounceAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gDekuFlowerBounceAnim), 2, 0.0f);
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
- this->actionFunc = ObjEtcetera_DoIntenseOscillation;
+ this->actionFunc = ObjEtcetera_DoBounceOscillation;
Actor_SetScale(&this->dyna.actor, 0.01f);
this->dyna.actor.scale.y = 0.02f;
- this->intenseOscillationScale = 0.003f;
+ this->bounceOscillationScale = 0.003f;
this->oscillationTimer = 30;
this->burrowFlag &= ~1;
} else if ((player->stateFlags3 & 0x2000) && (this->dyna.actor.xzDistToPlayer < 30.0f) &&
@@ -151,7 +159,7 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) {
if (!(this->burrowFlag & 1)) {
// Player is walking onto the Deku Flower, or falling on it from a height
this->oscillationTimer = 10;
- ObjEtcetera_StartSmallFlutterAnimation(this);
+ ObjEtcetera_StartRustleAnimation(this);
} else if ((player->actor.speedXZ > 0.1f) || ((player->unk_ABC < 0.0f) && !(player->stateFlags3 & 0x100))) {
// Player is walking on top of the Deku Flower, is at the very start of burrowing, or is at the very
// start of launching
@@ -162,19 +170,19 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) {
if (this->burrowFlag & 1) {
// Player is walking off the Deku Flower
this->oscillationTimer = 10;
- ObjEtcetera_StartSmallFlutterAnimation(this);
+ ObjEtcetera_StartRustleAnimation(this);
}
this->burrowFlag &= ~1;
}
}
if ((this->collider.base.acFlags & AC_HIT)) {
this->oscillationTimer = 10;
- ObjEtcetera_StartSmallFlutterAnimation(this);
+ ObjEtcetera_StartRustleAnimation(this);
}
ObjEtcetera_DoNormalOscillation(this, globalCtx);
}
-void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx) {
+void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, GlobalContext* globalCtx) {
if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) {
this->burrowFlag |= 1;
} else {
@@ -187,7 +195,12 @@ void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* glo
ObjEtcetera_DoNormalOscillation(this, globalCtx);
}
-void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx) {
+/**
+ * When the bounce animation plays (either because the player launched out of the flower,
+ * or because the flower spawned after killing a Mad Scrub), this function makes the
+ * flower oscillate stronger than it normally does, including an oscillation on the Y-axis.
+ */
+void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, GlobalContext* globalCtx) {
// In order to match, we are seemingly required to access scale.x at one point
// without using this. We can create a thisx or dyna pointer to achieve that, but
// it's more likely they used dyna given that DynaPolyActor_IsInRidingMovingState takes a DynaPolyActor.
@@ -208,12 +221,12 @@ void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCt
Actor_SetScale(&this->dyna.actor, 0.01f);
this->dyna.actor.scale.y = 0.02f;
this->oscillationTimer = 0;
- this->intenseOscillationScale = 0.0f;
+ this->bounceOscillationScale = 0.0f;
return;
}
- this->intenseOscillationScale *= 0.8f;
- this->intenseOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f;
- scaleTemp = dyna->actor.scale.x + this->intenseOscillationScale;
+ this->bounceOscillationScale *= 0.8f;
+ this->bounceOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f;
+ scaleTemp = dyna->actor.scale.x + this->bounceOscillationScale;
Actor_SetScale(&this->dyna.actor, scaleTemp);
this->dyna.actor.scale.y = 2.0f * scaleTemp;
}
@@ -221,7 +234,12 @@ void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCt
void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) {
CollisionHeader* colHeader = NULL;
s32 type;
- CollisionHeader* collisionHeaders[] = { &D_0400E710, &D_0400E710, &D_040118D8, &D_040118D8 };
+ CollisionHeader* collisionHeaders[] = {
+ &gPinkDekuFlowerCol,
+ &gPinkDekuFlowerCol,
+ &gGoldDekuFlowerCol,
+ &gGoldDekuFlowerCol,
+ };
s32 pad;
CollisionHeader* thisCollisionHeader;
@@ -244,15 +262,15 @@ void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) {
switch (type) {
case DEKU_FLOWER_TYPE_PINK:
case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB:
- SkelAnime_Init(globalCtx, &this->skelAnime, &D_04011518, &D_0400EB7C, this->jointTable,
- this->morphTable, 11);
- this->dList = &D_0400ED80;
+ SkelAnime_Init(globalCtx, &this->skelAnime, &gPinkDekuFlowerSkel, &gDekuFlowerBounceAnim,
+ this->jointTable, this->morphTable, DEKU_FLOWER_LIMB_MAX);
+ this->dList = gPinkDekuFlowerIdleDL;
break;
case DEKU_FLOWER_TYPE_GOLD:
case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB:
- this->dList = &D_04011BD0;
- SkelAnime_Init(globalCtx, &this->skelAnime, &D_040127E8, &D_0400EB7C, this->jointTable,
- this->morphTable, 11);
+ this->dList = gGoldDekuFlowerIdleDL;
+ SkelAnime_Init(globalCtx, &this->skelAnime, &gGoldDekuFlowerSkel.sh, &gDekuFlowerBounceAnim,
+ this->jointTable, this->morphTable, DEKU_FLOWER_LIMB_MAX);
this->collider.dim.height = 20;
break;
}
@@ -270,13 +288,13 @@ void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) {
break;
case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB:
case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB:
- Animation_Change(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, Animation_GetLastFrame(&D_0400EB7C), 2,
- 0.0f);
+ Animation_Change(&this->skelAnime, &gDekuFlowerBounceAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gDekuFlowerBounceAnim), 2, 0.0f);
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
- this->actionFunc = ObjEtcetera_DoIntenseOscillation;
+ this->actionFunc = ObjEtcetera_DoBounceOscillation;
Actor_SetScale(&this->dyna.actor, 0.0f);
this->oscillationTimer = 30;
- this->intenseOscillationScale = 0.0f;
+ this->bounceOscillationScale = 0.0f;
this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f;
this->dyna.actor.targetMode = 3;
break;
@@ -299,6 +317,11 @@ void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx) {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
+/**
+ * When the flower isn't animating, this function is used to draw it.
+ * It draws the flower as a single, non-moving display list that encompasses the whole flower.
+ * When an animation is finished, functions are expected to set the actor's draw function to this.
+ */
void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) {
ObjEtcetera* this = THIS;
@@ -311,6 +334,11 @@ void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) {
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
+/**
+ * When the flower is animating, this function is used to draw it.
+ * It draws the flower as an animated bunch of limbs using the SkelAnime system.
+ * When a function wants to play an animation, it is expected to set the actor's draw function to this.
+ */
void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx) {
ObjEtcetera* this = THIS;
diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h
index f5642ff28..a52f5ae2e 100644
--- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h
+++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h
@@ -13,6 +13,26 @@ typedef enum {
/* 4 */ DEKU_FLOWER_TYPE_MAX,
} DekuFlowerType;
+/**
+ * For the petal/leaf directions, "back" is negative and "front" is positive
+ * on the flower's local Z-axis. "Left" and "right" are relative to the front
+ * and back.
+ */
+typedef enum {
+ /* 0 */ DEKU_FLOWER_LIMB_NONE,
+ /* 1 */ DEKU_FLOWER_LIMB_BASE,
+ /* 2 */ DEKU_FLOWER_LIMB_CENTER,
+ /* 3 */ DEKU_FLOWER_LIMB_BACK_PETAL_OR_LEAF,
+ /* 4 */ DEKU_FLOWER_LIMB_FRONT_PETAL_OR_LEAF,
+ /* 5 */ DEKU_FLOWER_LIMB_FRONT_RIGHT_PETAL,
+ /* 6 */ DEKU_FLOWER_LIMB_BACK_RIGHT_PETAL,
+ /* 7 */ DEKU_FLOWER_LIMB_RIGHT_PETAL_OR_LEAF,
+ /* 8 */ DEKU_FLOWER_LIMB_FRONT_LEFT_PETAL,
+ /* 9 */ DEKU_FLOWER_LIMB_LEFT_PETAL_OR_LEAF,
+ /* 10 */ DEKU_FLOWER_LIMB_BACK_LEFT_PETAL,
+ /* 11 */ DEKU_FLOWER_LIMB_MAX,
+} DekuFlowerLimbs;
+
struct ObjEtcetera;
typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, GlobalContext*);
@@ -21,9 +41,9 @@ typedef struct ObjEtcetera {
/* 0x000 */ DynaPolyActor dyna;
/* 0x15C */ SkelAnime skelAnime;
/* 0x1A0 */ ColliderCylinder collider;
- /* 0x1EC */ Vec3s jointTable[11];
- /* 0x22E */ Vec3s morphTable[11];
- /* 0x270 */ f32 intenseOscillationScale;
+ /* 0x1EC */ Vec3s jointTable[DEKU_FLOWER_LIMB_MAX];
+ /* 0x22E */ Vec3s morphTable[DEKU_FLOWER_LIMB_MAX];
+ /* 0x270 */ f32 bounceOscillationScale;
/* 0x274 */ s16 oscillationTimer;
/* 0x276 */ u16 burrowFlag;
/* 0x278 */ s8 objIndex;
diff --git a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c
index 8a6795094..793f7cbe0 100644
--- a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c
+++ b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c
@@ -5,6 +5,7 @@
*/
#include "z_obj_flowerpot.h"
+#include "objects/object_flowerpot/object_flowerpot.h"
#define FLAGS 0x00000000
@@ -15,7 +16,21 @@ void ObjFlowerpot_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjFlowerpot_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjFlowerpot_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void func_80A1C818(ObjFlowerpot* this);
+void func_80A1C838(ObjFlowerpot* this, GlobalContext* globalCtx);
+void func_80A1CBF8(ObjFlowerpot* this);
+void func_80A1CC0C(ObjFlowerpot* this, GlobalContext* globalCtx);
+void func_80A1CD10(ObjFlowerpot* this);
+void func_80A1CEF4(ObjFlowerpot* this2, GlobalContext* globalCtx);
+
+static u32 D_80A1D830;
+static MtxF D_80A1D838[8];
+static s16 D_80A1DA38;
+static s16 D_80A1DA3A;
+static s16 D_80A1DA3C;
+static s16 D_80A1DA3E;
+static s16 D_80A1DA40;
+
const ActorInit Obj_Flowerpot_InitVars = {
ACTOR_OBJ_FLOWERPOT,
ACTORCAT_PROP,
@@ -28,86 +43,646 @@ const ActorInit Obj_Flowerpot_InitVars = {
(ActorFunc)ObjFlowerpot_Draw,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[2] = {
-static ColliderJntSphElementInit D_80A1D3A0[2] = {
+static ColliderJntSphElementInit sJntSphElementsInit[2] = {
{
- { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x05CBFFBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00400000, 0x00, 0x02 },
+ { 0x05CBFFBE, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 100, 0 }, 12 }, 100 },
},
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x0580C71C, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x0580C71C, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 1, { { 0, 300, 0 }, 12 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_80A1D3E8 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, },
- 2, D_80A1D3A0, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_PLAYER,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_JNTSPH,
+ },
+ 2,
+ sJntSphElementsInit,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80A1D414[] = {
- ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE),
- ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
- ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneForward, 1600, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
- ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
+static s16 D_80A1D3F8 = 0;
+
+static s16 D_80A1D3FC = 0;
+
+static s16 D_80A1D400 = 0;
+
+static u8 D_80A1D404 = true;
+
+static Vec3f D_80A1D408 = { 0.0f, 20.0f, 0.0f };
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
+ ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1600, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
};
-#endif
+void func_80A1B3D0(void) {
+ s32 i;
+ s32 pad;
+ f32 spB4;
+ f32* ptr;
+ f32 spAC;
+ f32 spA8;
+ f32 tempf1;
+ f32 tempf2;
+ f32 tempf3;
+ f32 tempf4;
+ f32 tempf5;
+ f32 sp74[8];
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f24;
+ f32 temp_f26;
+ f32 temp_f28;
+ f32 temp_f0;
+ f32 temp_f30;
-extern ColliderJntSphElementInit D_80A1D3A0[2];
-extern ColliderJntSphInit D_80A1D3E8;
-extern InitChainEntry D_80A1D414[];
+ D_80A1DA38 += 70;
+ D_80A1DA3A += 300;
+ D_80A1DA3C += 700;
+ D_80A1DA3E += 1300;
+ D_80A1DA40 += 8900;
-extern UNK_TYPE D_060012E0;
-extern UNK_TYPE D_060014F0;
-extern UNK_TYPE D_060015B0;
+ temp_f28 = Math_SinS(D_80A1DA38);
+ spB4 = Math_SinS(D_80A1DA3A);
+ temp_f30 = Math_SinS(D_80A1DA3C);
+ spAC = Math_SinS(D_80A1DA3E);
+ spA8 = Math_SinS(D_80A1DA40);
+ temp_f26 = Math_CosS(D_80A1DA38);
+ temp_f20 = Math_CosS(D_80A1DA3A);
+ temp_f22 = Math_CosS(D_80A1DA3C);
+ temp_f24 = Math_CosS(D_80A1DA3E);
+ temp_f0 = Math_CosS(D_80A1DA40);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B3D0.s")
+ sp74[0] = (temp_f28 - temp_f20) * temp_f30 * temp_f26 * temp_f28 * 0.0012f;
+ sp74[1] = (spB4 - temp_f22) * spAC * temp_f20 * temp_f28 * 0.0012f;
+ sp74[2] = (temp_f30 - temp_f24) * temp_f22 * temp_f28 * temp_f26 * 0.0012f;
+ sp74[3] = (spAC - temp_f20) * temp_f24 * spB4 * temp_f26 * 0.0012f;
+ sp74[4] = (temp_f28 - temp_f22) * temp_f28 * spB4 * spA8 * 0.0013f;
+ sp74[5] = (spB4 - temp_f24) * temp_f30 * spAC * spA8 * 0.0013f;
+ sp74[6] = (temp_f30 - temp_f26) * temp_f26 * temp_f20 * temp_f0 * 0.0013f;
+ sp74[7] = (spAC - temp_f20) * temp_f22 * temp_f24 * temp_f0 * 0.0013f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B840.s")
+ for (i = 0; i < ARRAY_COUNT(D_80A1D838); i++) {
+ ptr = (f32*)&D_80A1D838[i].mf[0];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B914.s")
+ tempf1 = sp74[(i + 0) & 7];
+ tempf2 = sp74[(i + 1) & 7];
+ tempf3 = sp74[(i + 2) & 7];
+ tempf4 = sp74[(i + 3) & 7];
+ tempf5 = sp74[(i + 4) & 7];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B994.s")
+ ptr[0] = sp74[1] * 0.2f;
+ ptr[1] = tempf1;
+ ptr[2] = tempf2;
+ ptr[3] = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B9CC.s")
+ ptr[4] = tempf3;
+ ptr[5] = sp74[0];
+ ptr[6] = tempf3;
+ ptr[7] = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BA04.s")
+ ptr[8] = tempf4;
+ ptr[9] = tempf5;
+ ptr[10] = sp74[3] * 0.2f;
+ ptr[11] = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BA44.s")
+ ptr[12] = 0.0f;
+ ptr[13] = 0.0f;
+ ptr[14] = 0.0f;
+ ptr[15] = 0.0f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BD80.s")
+void func_80A1B840(MtxF* matrix) {
+ MtxF* temp = Matrix_GetCurrentState();
+ f32* tmp = (f32*)&temp->mf[0];
+ f32* tmp2 = (f32*)&matrix->mf[0];
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C0FC.s")
+ for (i = 0; i < 16; i++) {
+ *tmp++ += *tmp2++;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C328.s")
+void func_80A1B914(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ if (!(this->unk_1EA & 4)) {
+ s32 temp_v0 = func_800A8150(ENOBJFLOWERPOT_GET_3F(&this->actor));
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C554.s")
+ if (temp_v0 >= 0) {
+ s32 params = ENOBJFLOWERPOT_GET_7F00(&this->actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C5E8.s")
+ Item_DropCollectible(globalCtx, &this->actor.world.pos, temp_v0 | (params << 8));
+ this->unk_1EA |= 4;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C62C.s")
+void func_80A1B994(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_POT_BROKEN);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Init.s")
+void func_80A1B9CC(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Destroy.s")
+void func_80A1BA04(ObjFlowerpot* this, Vec3f* arg1) {
+ Matrix_SetStateRotationAndTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
+ &this->actor.shape.rot);
+ Matrix_MultiplyVector3fByState(&D_80A1D408, arg1);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C818.s")
+void func_80A1BA44(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ s32 i;
+ Vec3f spD0;
+ Vec3f spC4;
+ Vec3f spB8;
+ f32 temp_f0;
+ f32 temp_f20;
+ s16 phi_s3;
+ s32 phi_s0;
+ s32 phi_s1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C838.s")
+ spD0.x = this->actor.world.pos.x;
+ spD0.y = this->actor.world.pos.y;
+ spD0.z = this->actor.world.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CBF8.s")
+ for (i = 0, phi_s3 = 0; i < 18; i++, phi_s3 += 0xE38) {
+ temp_f20 = (Rand_ZeroOne() * 8.0f) + 2.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CC0C.s")
+ spC4.x = Math_SinS((s32)(Rand_ZeroOne() * 3640.0f) + phi_s3) * temp_f20;
+ spC4.y = Rand_ZeroOne() * 30.0f;
+ spC4.z = Math_CosS((s32)(Rand_ZeroOne() * 3640.0f) + phi_s3) * temp_f20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CD10.s")
+ spB8.x = spC4.x * 0.27f;
+ spB8.y = (Rand_ZeroOne() * 6.0f) + 2.6f + ((30.0f - spC4.y) * 0.2f);
+ spB8.z = spC4.z * 0.27f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CEF4.s")
+ Math_Vec3f_Sum(&spC4, &spD0, &spC4);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Update.s")
+ temp_f0 = Rand_ZeroOne();
+ if (temp_f0 < 0.2f) {
+ phi_s0 = 32;
+ phi_s1 = 0;
+ } else if (temp_f0 < 0.6f) {
+ phi_s0 = 65;
+ phi_s1 = 1;
+ } else {
+ phi_s0 = 64;
+ phi_s1 = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Draw.s")
+ EffectSsKakera_Spawn(globalCtx, &spC4, &spB8, &spC4, -600, phi_s0, 30, 0, 0, (Rand_ZeroOne() * 12.0f) + 16.6f,
+ phi_s1, 0, 35, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0);
+ }
+
+ spD0.y += 20.0f;
+
+ func_800BBFB0(globalCtx, &spD0, 30.0f, 2, 20, 50, 1);
+ func_800BBFB0(globalCtx, &spD0, 30.0f, 2, 10, 80, 1);
+ func_800BBFB0(globalCtx, &spD0, 30.0f, 1, 10, 40, 1);
+}
+
+void func_80A1BD80(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ s32 i;
+ Vec3f spC8;
+ Vec3f spBC;
+ Vec3f spB0;
+ f32 temp_f20;
+ s16 phi_s1;
+ s32 phi_s0;
+
+ spC8.x = this->actor.world.pos.x;
+ spC8.y = this->actor.world.pos.y;
+ spC8.z = this->actor.world.pos.z;
+
+ for (i = 0, phi_s1 = 0; i < 14; i++, phi_s1 += 0x1249) {
+ temp_f20 = (Rand_ZeroOne() * 8.0f) + 2.0f;
+
+ spBC.x = Math_SinS((s32)(Rand_ZeroOne() * 4681.0f) + phi_s1) * temp_f20;
+ spBC.y = Rand_ZeroOne() * 20.0f;
+ spBC.z = Math_CosS((s32)(Rand_ZeroOne() * 4681.0f) + phi_s1) * temp_f20;
+
+ spB0.x = spBC.x * 0.17f;
+ spB0.y = (Rand_ZeroOne() * 5.0f) + 1.4f;
+ spB0.z = spBC.z * 0.17f;
+
+ Math_Vec3f_Sum(&spBC, &spC8, &spBC);
+
+ if (Rand_ZeroOne() < 0.2f) {
+ phi_s0 = 64;
+ } else {
+ phi_s0 = 32;
+ }
+
+ EffectSsKakera_Spawn(globalCtx, &spBC, &spB0, &spBC, -240, phi_s0, 40, 0, 0, (Rand_ZeroOne() * 20.0f) + 10.6f,
+ 0, 0, 42, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0);
+ }
+
+ spBC.y = this->actor.world.pos.y + this->actor.depthInWater;
+
+ for (phi_s1 = 0, i = 0; i < 4; i++, phi_s1 += 0x4000) {
+ spBC.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s1) * 15.0f) + this->actor.world.pos.x;
+ spBC.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s1) * 15.0f) + this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &spBC, NULL, NULL, 0, 200);
+ }
+
+ spBC.x = this->actor.world.pos.x;
+ spBC.z = this->actor.world.pos.z;
+ EffectSsGSplash_Spawn(globalCtx, &spBC, NULL, NULL, 0, 350);
+ EffectSsGRipple_Spawn(globalCtx, &spBC, 150, 650, 0);
+}
+
+void func_80A1C0FC(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ Vec3f spC4;
+ Vec3f spB8;
+ Vec3f spAC;
+ f32 temp_f20;
+ s16 phi_s0;
+ s32 i;
+
+ func_80A1BA04(this, &spC4);
+
+ for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) {
+ temp_f20 = (Rand_ZeroOne() * 18.0f) + 2.0f;
+
+ spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20;
+ spB8.y = Rand_ZeroOne() * 15.0f;
+ spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20;
+
+ spAC.x = spB8.x * 0.23f;
+ spAC.y = (Rand_ZeroOne() * 8.0f) + 1.5f;
+ spAC.z = spB8.z * 0.23f;
+
+ Math_Vec3f_Sum(&spB8, &spC4, &spB8);
+ EffectSsKakera_Spawn(globalCtx, &spB8, &spAC, &spB8, -100, 64, 40, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0,
+ 80, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0);
+ }
+}
+
+void func_80A1C328(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ Vec3f spC4;
+ Vec3f spB8;
+ Vec3f spAC;
+ f32 temp_f20;
+ s16 phi_s0;
+ s32 i;
+
+ func_80A1BA04(this, &spC4);
+
+ for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) {
+ temp_f20 = (Rand_ZeroOne() * 18.0f) + 2.0f;
+
+ spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20;
+ spB8.y = Rand_ZeroOne() * 15.0f;
+ spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20;
+
+ spAC.x = spB8.x * 0.18f;
+ spAC.y = (Rand_ZeroOne() * 4.0f) + 1.2f;
+ spAC.z = spB8.z * 0.18f;
+
+ Math_Vec3f_Sum(&spB8, &spC4, &spB8);
+ EffectSsKakera_Spawn(globalCtx, &spB8, &spAC, &spB8, -80, 64, 44, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0,
+ 80, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0);
+ }
+}
+
+void func_80A1C554(ObjFlowerpot* this) {
+ if ((this->actor.projectedPos.z < 455.0f) && (this->actor.projectedPos.z > -10.0f)) {
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ this->actor.shape.shadowScale = 1.9f;
+ if (this->actor.projectedPos.z < 255.0f) {
+ this->actor.shape.shadowAlpha = 200;
+ } else {
+ this->actor.shape.shadowAlpha = 455 - (s32)this->actor.projectedPos.z;
+ }
+ } else {
+ this->actor.shape.shadowDraw = NULL;
+ }
+}
+
+void func_80A1C5E8(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 18.0f, 15.0f, 0.0f, 0x45);
+}
+
+void func_80A1C62C(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ if (!(this->unk_1EA & 4) && (globalCtx->roomCtx.currRoom.num != this->unk_1EC)) {
+ this->unk_1EA |= 4;
+ }
+}
+
+void ObjFlowerpot_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjFlowerpot* this = THIS;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+
+ if (this->actor.shape.rot.y == 0) {
+ this->actor.shape.rot.y = this->actor.world.rot.y = (u32)Rand_Next() >> 0x10;
+ }
+
+ Collider_InitJntSph(globalCtx, &this->collider);
+ Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
+ Matrix_SetStateRotationAndTranslation(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z,
+ &this->actor.shape.rot);
+ Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY);
+ Collider_UpdateSpheres(0, &this->collider);
+ Collider_UpdateSpheres(1, &this->collider);
+
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ this->unk_1EC = this->actor.room;
+ func_80A1C818(this);
+
+ if (D_80A1D404) {
+ D_80A1DA38 = (u32)Rand_Next() >> 0x10;
+ D_80A1DA3A = (u32)Rand_Next() >> 0x10;
+ D_80A1DA3C = (u32)Rand_Next() >> 0x10;
+ D_80A1DA3E = (u32)Rand_Next() >> 0x10;
+ D_80A1DA40 = (u32)Rand_Next() >> 0x10;
+ D_80A1D404 = false;
+ func_80A1B3D0();
+ D_80A1D830 = globalCtx->gameplayFrames;
+ }
+ this->unk_1EB = D_80A1D400 & 7;
+ D_80A1D400++;
+}
+
+void ObjFlowerpot_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ Collider_DestroyJntSph(globalCtx, &THIS->collider);
+}
+
+void func_80A1C818(ObjFlowerpot* this) {
+ this->actionFunc = func_80A1C838;
+ this->unk_1EA |= 1;
+}
+
+void func_80A1C838(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ func_80A1CBF8(this);
+ this->actor.room = -1;
+ this->actor.colChkInfo.mass = 180;
+ this->actor.flags |= 0x10;
+ if (func_800A817C(ENOBJFLOWERPOT_GET_3F(&this->actor))) {
+ func_80A1B914(this, globalCtx);
+ }
+ func_800B8E58(&this->actor, NA_SE_PL_PULL_UP_POT);
+ } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 19.0f)) {
+ if (!(this->unk_1EA & 2)) {
+ func_80A1B914(this, globalCtx);
+ func_80A1C328(this, globalCtx);
+ func_80A1B9CC(this, globalCtx);
+ this->unk_1EA |= 2;
+ }
+ func_80A1BD80(this, globalCtx);
+ func_80A1B994(this, globalCtx);
+ Actor_MarkForDeath(&this->actor);
+ } else if ((this->collider.elements[0].info.bumperFlags & 2) &&
+ (this->collider.elements[0].info.acHitInfo->toucher.dmgFlags & 0x058BFFBC)) {
+ if (!(this->unk_1EA & 2)) {
+ func_80A1B914(this, globalCtx);
+ func_80A1C0FC(this, globalCtx);
+ func_80A1B9CC(this, globalCtx);
+ this->unk_1EA |= 2;
+ }
+ func_80A1BA44(this, globalCtx);
+ func_80A1B994(this, globalCtx);
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ if (this->collider.elements[1].info.bumperFlags & 2) {
+ if (!(this->unk_1EA & 2)) {
+ this->unk_1EA |= 2;
+ this->collider.elements[1].info.bumperFlags &= ~0x1;
+ func_80A1C0FC(this, globalCtx);
+ func_80A1B914(this, globalCtx);
+ func_80A1B9CC(this, globalCtx);
+ }
+ }
+
+ if (this->unk_1EA & 1) {
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A1C5E8(this, globalCtx);
+ if (this->actor.bgCheckFlags & 1) {
+ if (this->actor.colChkInfo.mass == MASS_IMMOVABLE) {
+ if (DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId) == NULL) {
+ this->actor.flags &= ~0x10;
+ this->unk_1EA &= ~0x1;
+ }
+ } else if (Math3D_Vec3fDistSq(&this->actor.world.pos, &this->actor.prevPos) < 0.01f) {
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ }
+ }
+ }
+
+ if (!(this->collider.base.ocFlags1 & OC1_TYPE_PLAYER) && (this->actor.xzDistToPlayer > 28.0f)) {
+ this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER;
+ }
+
+ this->collider.base.acFlags &= ~AC_HIT;
+
+ if (this->actor.xzDistToPlayer < 600.0f) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+
+ if (this->actor.xzDistToPlayer < 180.0f) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+
+ if (this->actor.xzDistToPlayer < 100.0f) {
+ s16 temp_v0_3 = this->actor.yawTowardsPlayer - GET_PLAYER(globalCtx)->actor.world.rot.y;
+
+ if (ABS_ALT(temp_v0_3) >= 0x5556) {
+ func_800B8A1C(&this->actor, globalCtx, 0, 36.0f, 30.0f);
+ }
+ }
+ }
+ }
+ }
+}
+
+void func_80A1CBF8(ObjFlowerpot* this) {
+ this->actionFunc = func_80A1CC0C;
+}
+
+void func_80A1CC0C(ObjFlowerpot* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ func_80A1C62C(this, globalCtx);
+
+ if (Actor_HasNoParent(&this->actor, globalCtx)) {
+ this->actor.room = globalCtx->roomCtx.currRoom.num;
+ if (fabsf(this->actor.speedXZ) < 0.1f) {
+ func_80A1C818(this);
+ func_800B8E58(&GET_PLAYER(globalCtx)->actor, NA_SE_PL_PUT_DOWN_POT);
+ this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER;
+ } else {
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ func_80A1CD10(this);
+ }
+ func_80A1C5E8(this, globalCtx);
+ } else {
+ Vec3f sp30;
+ s32 sp2C;
+
+ sp30.x = this->actor.world.pos.x;
+ sp30.y = this->actor.world.pos.y + 20.0f;
+ sp30.z = this->actor.world.pos.z;
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30);
+ }
+}
+
+void func_80A1CD10(ObjFlowerpot* this) {
+ f32 sp1C;
+
+ this->actionFunc = func_80A1CEF4;
+ this->unk_1E8 = 64;
+
+ if (this->unk_1EA & 2) {
+ sp1C = (Rand_ZeroOne() * 1.2f) - 1.1f;
+ if (sp1C < -0.9f) {
+ sp1C = -0.9f;
+ }
+ D_80A1D3F8 = sp1C * 8000.0f;
+ D_80A1D3FC = ((Rand_ZeroOne() - 0.5f) * 3800.0f) * (fabsf(sp1C) + 0.1f);
+ this->actor.shape.yOffset = -71.5f;
+ this->actor.world.pos.y += 7.15f;
+ } else {
+ sp1C = (Rand_ZeroOne() - 0.78f) * 1.3f;
+ if (sp1C < -0.78f) {
+ sp1C = -0.78f;
+ } else if (sp1C > 0.22000003f) {
+ sp1C = 0.22000003f;
+ }
+ D_80A1D3F8 = sp1C * 6200.0f;
+ D_80A1D3FC = (Rand_ZeroOne() - 0.5f) * 4200.0f;
+ this->actor.shape.yOffset = -110.0f;
+ this->actor.world.pos.y += 11.0f;
+ }
+}
+
+void func_80A1CEF4(ObjFlowerpot* this2, GlobalContext* globalCtx) {
+ ObjFlowerpot* this = this2;
+ s32 sp28 = this->collider.elements[0].info.toucherFlags & TOUCH_HIT;
+
+ if (sp28) {
+ this->collider.elements[0].info.toucherFlags &= ~TOUCH_ON;
+ }
+
+ if (this->unk_1E8 > 0) {
+ this->unk_1E8--;
+ }
+
+ func_80A1C62C(this, globalCtx);
+
+ if ((this->actor.bgCheckFlags & (0x8 | 0x2 | 0x1)) || sp28 || (this->unk_1E8 <= 0)) {
+ if (!(this->unk_1EA & 2)) {
+ func_80A1B914(this, globalCtx);
+ func_80A1C0FC(this, globalCtx);
+ func_80A1B9CC(this, globalCtx);
+ this->unk_1EA |= 2;
+ }
+ func_80A1BA44(this, globalCtx);
+ func_80A1B994(this, globalCtx);
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ if (this->actor.bgCheckFlags & 0x40) {
+ if (!(this->unk_1EA & 2)) {
+ func_80A1B914(this, globalCtx);
+ func_80A1C328(this, globalCtx);
+ func_80A1B9CC(this, globalCtx);
+ this->unk_1EA |= 2;
+ }
+ func_80A1BD80(this, globalCtx);
+ func_80A1B994(this, globalCtx);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+
+ if (!(this->unk_1EA & 2)) {
+ D_80A1D3F8 += (s16)(this->actor.shape.rot.x * -0.06f);
+ } else {
+ Math_StepToS(&D_80A1D3F8, 0, 80);
+ Math_StepToS(&D_80A1D3FC, 0, 20);
+ }
+
+ this->actor.shape.rot.x += D_80A1D3F8;
+ this->actor.shape.rot.y += D_80A1D3FC;
+
+ func_80A1C5E8(this, globalCtx);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+void ObjFlowerpot_Update(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ ObjFlowerpot* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+
+ func_80A1C554(this);
+
+ if ((D_80A1D830 != globalCtx->gameplayFrames) && (globalCtx->roomCtx.currRoom.unk3 == 0)) {
+ func_80A1B3D0();
+ D_80A1D830 = globalCtx->gameplayFrames;
+ }
+}
+
+void ObjFlowerpot_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjFlowerpot* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, object_flowerpot_DL_0012E0);
+
+ if ((this->actionFunc != func_80A1C838) || (this->unk_1EA & 1)) {
+ Collider_UpdateSpheres(0, &this->collider);
+ if (!(this->unk_1EA & 2)) {
+ Collider_UpdateSpheres(1, &this->collider);
+ }
+ }
+
+ if (!(this->unk_1EA & 2)) {
+ if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actionFunc == func_80A1C838)) {
+ if ((this->actor.projectedPos.z > -150.0f) && (this->actor.projectedPos.z < 400.0f)) {
+ func_80A1B840(&D_80A1D838[this->unk_1EB]);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ }
+ }
+
+ gSPDisplayList(POLY_OPA_DISP++, object_flowerpot_DL_001408);
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h
index 3396a1aba..01557bc2b 100644
--- a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h
+++ b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h
@@ -7,11 +7,18 @@ struct ObjFlowerpot;
typedef void (*ObjFlowerpotActionFunc)(struct ObjFlowerpot*, GlobalContext*);
+#define ENOBJFLOWERPOT_GET_3F(thisx) ((thisx)->params & 0x3F)
+#define ENOBJFLOWERPOT_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F)
+
typedef struct ObjFlowerpot {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0xA0];
+ /* 0x0144 */ ColliderJntSph collider;
+ /* 0x0164 */ ColliderJntSphElement colliderElements[2];
/* 0x01E4 */ ObjFlowerpotActionFunc actionFunc;
- /* 0x01E8 */ char unk_1E8[0x8];
+ /* 0x01E8 */ s16 unk_1E8;
+ /* 0x01EA */ u8 unk_1EA;
+ /* 0x01EB */ s8 unk_1EB;
+ /* 0x01EC */ s8 unk_1EC;
} ObjFlowerpot; // size = 0x1F0
extern const ActorInit Obj_Flowerpot_InitVars;
diff --git a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c
index 6731feda7..a290435af 100644
--- a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c
+++ b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c
@@ -5,6 +5,7 @@
*/
#include "z_obj_hugebombiwa.h"
+#include "objects/object_bombiwa/object_bombiwa.h"
#define FLAGS 0x00000010
@@ -15,7 +16,16 @@ void ObjHugebombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjHugebombiwa_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjHugebombiwa_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void func_80A54BF0(ObjHugebombiwa* this);
+void func_80A54C04(ObjHugebombiwa* this, GlobalContext* globalCtx);
+void func_80A54CD8(ObjHugebombiwa* this);
+void func_80A54CEC(ObjHugebombiwa* this, GlobalContext* globalCtx);
+void func_80A54E10(ObjHugebombiwa* this);
+void func_80A55064(ObjHugebombiwa* this, GlobalContext* globalCtx);
+void func_80A55310(ObjHugebombiwa* this);
+void func_80A55564(ObjHugebombiwa* this, GlobalContext* globalCtx);
+void func_80A55B34(Actor* thisx, GlobalContext* globalCtx);
+
const ActorInit Obj_Hugebombiwa_InitVars = {
ACTOR_OBJ_HUGEBOMBIWA,
ACTORCAT_PROP,
@@ -28,64 +38,683 @@ const ActorInit Obj_Hugebombiwa_InitVars = {
(ActorFunc)ObjHugebombiwa_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A55D00 = {
- { COLTYPE_HARD, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x81C37BB6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_HARD,
+ AT_NONE,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x81C37BB6, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 180, 226, 0, { 0, 0, 0 } },
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80A55D7C[] = {
+static Vec3f D_80A55D2C = { 0.0f, 0.3f, 0.0f };
+
+void func_80A53BE0(GlobalContext* globalCtx, Vec3f* arg1) {
+ Vec3f spBC;
+ Vec3f spB0;
+ s32 i;
+ s32 gravity;
+ s16 phi_v0;
+ s16 life;
+ s16 phi_v1;
+
+ for (i = 0, gravity = -300; i < 16; i++, gravity -= 30) {
+ spBC.x = (Rand_ZeroOne() - 0.5f) * 260.0f;
+ spBC.y = i * (40.0f / 3);
+ spBC.z = (Rand_ZeroOne() - 0.5f) * 260.0f;
+
+ spB0.x = ((Rand_ZeroOne() - 0.5f) * 5.7f) + (spBC.x * 0.035f);
+ spB0.y = (Rand_ZeroOne() * 16.0f) + 5.0f + ((16 - i) * 0.25f);
+ spB0.z = ((Rand_ZeroOne() - 0.5f) * 5.7f) + (spBC.z * 0.035f);
+
+ spBC.x += arg1->x;
+ spBC.y += arg1->y;
+ spBC.z += arg1->z;
+
+ if (i >= 14) {
+ phi_v0 = 37;
+ life = 70;
+ } else {
+ phi_v0 = 65;
+ if (i >= 12) {
+ life = 70;
+ } else {
+ life = 40;
+ if (Rand_ZeroOne() < 0.7f) {
+ phi_v0 = 64;
+ } else {
+ phi_v0 = 32;
+ }
+ }
+ }
+
+ phi_v1 = i;
+ if (phi_v1 <= 0) {
+ phi_v1 = 1;
+ if (1) {}
+ }
+
+ EffectSsKakera_Spawn(globalCtx, &spBC, &spB0, &spBC, gravity, phi_v0, 15, 0, 0, phi_v1, 1, 0, life, -1,
+ OBJECT_BOMBIWA, object_bombiwa_DL_001990);
+ }
+}
+
+void func_80A53E60(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3) {
+ static Color_RGBA8 D_80A55D38 = { 210, 210, 210, 255 };
+ static Color_RGBA8 D_80A55D3C = { 140, 140, 140, 255 };
+ static f32 D_80A55D40[] = { 3.0f, 5.0f, 9.0f, 18.0f };
+ Vec3f spDC;
+ Vec3f spD0;
+ s32 i;
+ f32 temp_f0;
+ s32 phi_s1;
+ s32 phi_s2;
+ s32 phi_v0;
+ s32 phi_v1;
+ s16 phi_s0;
+ s32 pad;
+
+ for (phi_s2 = -300, i = 0; phi_s2 > -540; phi_s2 -= 60, i++) {
+ spDC.x = (Rand_ZeroOne() - 0.5f) * 11.0f;
+ spDC.y = (Rand_ZeroOne() - 0.2f) * 8.0f;
+ spDC.z = (Rand_ZeroOne() - 0.5f) * 11.0f;
+
+ spD0.x = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spDC.x * 1.4f);
+ spD0.y = (Rand_ZeroOne() * 13.0f) + 8.2f + (arg2 * -0.26f);
+ if (1) {}
+ spD0.z = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spDC.z * 1.4f);
+
+ spDC.x += arg1->x;
+ spDC.y += arg1->y;
+ spDC.z += arg1->z;
+
+ if ((s32)(phi_s2 & 0xFFFFFFFF) == -480) {
+ phi_v0 = 33;
+ phi_s0 = 70;
+ } else {
+ phi_v0 = 65;
+ if (phi_s2 == -420) {
+ phi_s0 = 70;
+ } else {
+ phi_s0 = 40;
+ if (Rand_ZeroOne() < 0.7f) {
+ phi_v0 = 64;
+ } else {
+ phi_v0 = 32;
+ }
+ }
+ }
+
+ temp_f0 = D_80A55D40[i] * arg3;
+ if (temp_f0 <= 1.0f) {
+ phi_v1 = 1;
+ } else {
+ phi_v1 = temp_f0;
+ }
+
+ EffectSsKakera_Spawn(globalCtx, &spDC, &spD0, &spDC, phi_s2, phi_v0, 15, 0, 0, phi_v1, 1, 0, phi_s0, -1,
+ OBJECT_BOMBIWA, object_bombiwa_DL_001990);
+
+ spDC.x += (Rand_ZeroOne() - 0.5f) * 270.0f;
+ spDC.y += (Rand_ZeroOne() - 0.1f) * 150.0f;
+ spDC.z += (Rand_ZeroOne() - 0.5f) * 270.0f;
+
+ phi_s0 = (Rand_ZeroOne() * 160.0f) + 140.0f;
+ phi_s1 = (Rand_ZeroOne() * 180.0f) + 120.0f;
+ func_800B0E48(globalCtx, &spDC, &gZeroVec3f, &D_80A55D2C, &D_80A55D38, &D_80A55D3C, phi_s0, phi_s1);
+ }
+}
+
+void func_80A541F4(ObjHugebombiwa* this, GlobalContext* globalCtx) {
+ static s16 D_80A55D50[] = { 24, 17, 13, 7, 6, 5, 3, 2 };
+ s32 i;
+ s32 pad[2];
+ s32 phi_s2;
+ Vec3f spF4;
+ Vec3f spE8;
+ Vec3f spDC;
+ Vec3f spD0;
+ Vec3f spC4;
+ f32 temp_f0;
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f24;
+ s32 phi_s0;
+ f32 phi_f30;
+
+ for (i = 0, phi_s2 = 0, phi_f30 = 0.0f; i < 13; i++, phi_s2 += 0x4E20, phi_f30 += (230.0f / 13)) {
+ temp_f0 = Rand_ZeroOne();
+ temp_f22 = (1.0f - SQ(temp_f0)) * 120.0f;
+ temp_f20 = Math_SinS(phi_s2 & 0xFFFF);
+ temp_f24 = Math_CosS(phi_s2 & 0xFFFF);
+
+ spF4.x = (temp_f20 * temp_f22) + this->actor.world.pos.x;
+ spF4.y = this->actor.world.pos.y + phi_f30;
+ spF4.z = (temp_f24 * temp_f22) + this->actor.world.pos.z;
+
+ spE8.x = temp_f20 * 10.0f;
+ spE8.y = (Rand_ZeroOne() * 18.0f) + 10.0f;
+ spE8.z = temp_f24 * 10.0f;
+
+ EffectSsKakera_Spawn(globalCtx, &spF4, &spE8, &spF4, -650, 37, 15, 0, 0, D_80A55D50[i & 7], 1, 0, 60, -1,
+ OBJECT_BOMBIWA, object_bombiwa_DL_0009E0);
+
+ spDC.x = ((Rand_ZeroOne() - 0.5f) * 230.0f) + spF4.x;
+ spDC.y = ((Rand_ZeroOne() - 0.2f) * 200.0f) + spF4.y;
+ spDC.z = ((Rand_ZeroOne() - 0.5f) * 230.0f) + spF4.z;
+
+ spD0.x = temp_f20 * 7.0f;
+ spD0.y = -7.0f;
+ spD0.z = temp_f24 * 7.0f;
+
+ spC4.x = temp_f20 * -0.07f;
+ spC4.y = 0.24f;
+ spC4.z = temp_f24 * -0.07f;
+
+ func_800B12F0(globalCtx, &spDC, &spD0, &spC4, (s32)(Rand_ZeroOne() * 800.0f) + 1000, -49, 20);
+
+ spDC.x = ((Rand_ZeroOne() - 0.5f) * 160.0f) + spF4.x;
+ spDC.y = ((Rand_ZeroOne() - 0.2f) * 140.0f) + spF4.y;
+ spDC.z = ((Rand_ZeroOne() - 0.5f) * 160.0f) + spF4.z;
+
+ spD0.x = temp_f20 * 15.0f;
+ spD0.y = 0.0f;
+ spD0.z = temp_f24 * 15.0f;
+
+ spC4.x = temp_f20 * -0.09f;
+ spC4.y = 0.3f;
+ spC4.z = temp_f24 * -0.09f;
+
+ func_800B12F0(globalCtx, &spDC, &spD0, &spC4, (s32)(Rand_ZeroOne() * 100.0f) + 40,
+ (s32)(Rand_ZeroOne() * 200.0f) + 20, 10);
+ }
+}
+
+void func_80A54600(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3) {
+ static f32 D_80A55D60[] = { 3.0f, 5.0f, 9.0f, 18.0f };
+ static s8 D_80A55D70 = 0;
+ Vec3f spCC;
+ Vec3f spC0;
+ s32 i;
+ f32 spA0;
+ s16 temp_s0;
+ s16 temp_s1;
+ s32 phi_v0;
+ s16 phi_v1;
+ f32 temp;
+
+ for (i = 0; i < 2; i++) {
+ spCC.x = (Rand_ZeroOne() - 0.5f) * 11.0f;
+ spCC.y = (Rand_ZeroOne() - 0.2f) * 8.0f;
+ spCC.z = (Rand_ZeroOne() - 0.5f) * 11.0f;
+
+ spC0.x = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spCC.x * 1.4f);
+ spC0.y = (Rand_ZeroOne() * 13.0f) + 8.2f + (arg2 * -0.38f);
+ spC0.z = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spCC.z * 1.4f);
+
+ spCC.x += arg1->x;
+ spCC.y += arg1->y;
+ spCC.z += arg1->z;
+
+ temp = D_80A55D60[D_80A55D70] * arg3;
+ phi_v1 = (D_80A55D70 * -90) - 350;
+ D_80A55D70++;
+ D_80A55D70 &= 3;
+
+ if (temp <= 1.0f) {
+ phi_v0 = 1;
+ } else {
+ phi_v0 = temp;
+ }
+
+ EffectSsKakera_Spawn(globalCtx, &spCC, &spC0, &spCC, phi_v1, 33, 15, 0, 0, phi_v0, 1, 0, 70, -1, OBJECT_BOMBIWA,
+ object_bombiwa_DL_0009E0);
+
+ spCC.x += (Rand_ZeroOne() - 0.5f) * 270.0f;
+ spCC.y += (Rand_ZeroOne() - 0.1f) * 150.0f;
+ spCC.z += (Rand_ZeroOne() - 0.5f) * 270.0f;
+
+ temp_s0 = (Rand_ZeroOne() * 160.0f) + 140.0f;
+ temp_s1 = (Rand_ZeroOne() * 180.0f) + 120.0f;
+ func_800B1210(globalCtx, &spCC, &gZeroVec3f, &D_80A55D2C, temp_s0, temp_s1);
+ }
+}
+
+void func_80A54980(ObjHugebombiwa* this, GlobalContext* globalCtx, s32 arg2) {
+ s32 pad[2];
+ s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3);
+
+ Quake_SetSpeed(quake, 0x4E20);
+ Quake_SetQuakeValues(quake, arg2, 0, 0, 0);
+ Quake_SetCountdown(quake, 7);
+ func_8013ECE0(this->actor.xyzDistToPlayerSq, 255, 20, 150);
+}
+
+s32 func_80A54A0C(ObjHugebombiwa* this) {
+ static f32 D_80A55D74[] = { 62500.0f, 108900.0f };
+ s32 sp2C;
+ Actor* ac;
+ s32 params;
+ Vec3f sp20;
+
+ if ((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000000)) {
+ ac = this->collider.base.ac;
+ params = ENHUGEBOMBIWA_GET_100(&this->actor);
+
+ sp20.x = this->actor.world.pos.x;
+ sp20.y = this->actor.world.pos.y + 50.0f;
+ sp20.z = this->actor.world.pos.z;
+ if (ac != NULL) {
+ if (Math3D_Vec3fDistSq(&sp20, &ac->world.pos) < D_80A55D74[params]) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 3700, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 900, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 900, ICHAIN_STOP),
};
-#endif
+void ObjHugebombiwa_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjHugebombiwa* this = THIS;
-extern ColliderCylinderInit D_80A55D00;
-extern InitChainEntry D_80A55D7C[];
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ Collider_InitCylinder(globalCtx, &this->collider);
-extern UNK_TYPE D_060009E0;
-extern UNK_TYPE D_06001820;
-extern UNK_TYPE D_06001990;
-extern UNK_TYPE D_06002F60;
+ if (Flags_GetSwitch(globalCtx, ENHUGEBOMBIWA_GET_7F(&this->actor))) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A53BE0.s")
+ Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ if ((ENHUGEBOMBIWA_GET_100(&this->actor)) == 1) {
+ this->actor.draw = func_80A55B34;
+ Actor_SetScale(&this->actor, 0.74f);
+ this->collider.dim.radius = 204;
+ this->collider.dim.height = 230;
+ } else {
+ Actor_SetScale(&this->actor, 0.067f);
+ this->collider.dim.radius = 120;
+ this->collider.dim.height = 151;
+ }
+ func_80A54BF0(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A53E60.s")
+void ObjHugebombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ Collider_DestroyCylinder(globalCtx, &THIS->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A541F4.s")
+void func_80A54BF0(ObjHugebombiwa* this) {
+ this->actionFunc = func_80A54C04;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54600.s")
+void func_80A54C04(ObjHugebombiwa* this, GlobalContext* globalCtx) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54980.s")
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->unk_4B3 = 5;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54A0C.s")
+ if (func_80A54A0C(this)) {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ func_80A54CD8(this);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Init.s")
+ this->collider.base.acFlags &= ~AC_HIT;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Destroy.s")
+ if (this->unk_4B3 > 0) {
+ this->unk_4B3--;
+ if (this->unk_4B3 == 0) {
+ this->collider.base.colType = COLTYPE_HARD;
+ } else {
+ this->collider.base.colType = COLTYPE_NONE;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54BF0.s")
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54C04.s")
+void func_80A54CD8(ObjHugebombiwa* this) {
+ this->actionFunc = func_80A54CEC;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54CD8.s")
+void func_80A54CEC(ObjHugebombiwa* this, GlobalContext* globalCtx) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54CEC.s")
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
+ Actor_SetSwitchFlag(globalCtx, ENHUGEBOMBIWA_GET_7F(&this->actor));
+ if (!(ENHUGEBOMBIWA_GET_100(&this->actor)) &&
+ ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_17SETUGEN2))) {
+ gSaveContext.save.weekEventReg[19] |= 2;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54E10.s")
+ if (!(ENHUGEBOMBIWA_GET_100(&this->actor))) {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_WALL_BROKEN);
+ } else {
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_SNOWBALL_BROKEN);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55064.s")
+ if (!(ENHUGEBOMBIWA_GET_100(&this->actor))) {
+ func_80A53BE0(globalCtx, &this->actor.world.pos);
+ func_80A54E10(this);
+ } else {
+ func_80A541F4(this, globalCtx);
+ func_80A55310(this);
+ }
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55310.s")
+void func_80A54E10(ObjHugebombiwa* this) {
+ s32 i;
+ EnHugebombiwaStruct* ptr;
+ f32 temp_f20;
+ f32 temp_f20_2;
+ s16 phi_s2;
+ s32 pad;
+ Vec3f sp84;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55564.s")
+ Matrix_StatePush();
+ Matrix_RotateY(this->actor.shape.rot.y, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Update.s")
+ for (i = 0, phi_s2 = 0x1000; i < 20; i++, phi_s2 += 0x4000) {
+ ptr = &this->unk_190[i];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Draw.s")
+ temp_f20 = (Rand_ZeroOne() * 0.06f) + 0.013f;
+ ptr->unk_00.x = ((Rand_ZeroOne() * 0.6f) + 0.6f) * temp_f20;
+ ptr->unk_00.y = ((Rand_ZeroOne() * 0.6f) + 0.4f) * temp_f20;
+ ptr->unk_00.z = ((Rand_ZeroOne() * 0.6f) + 0.6f) * temp_f20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55B34.s")
+ temp_f20_2 = (Rand_ZeroOne() * 55.0f) + 47.0f;
+ sp84.x = Math_SinS(phi_s2) * temp_f20_2;
+ sp84.y = (i + 1) * 10.0f;
+ sp84.z = fabsf(Math_CosS(phi_s2)) * temp_f20_2;
+
+ Matrix_MultiplyVector3fByState(&sp84, &ptr->unk_0C);
+
+ ptr->unk_0C.x += this->actor.world.pos.x;
+ ptr->unk_0C.y += this->actor.world.pos.y;
+ ptr->unk_0C.z += this->actor.world.pos.z;
+
+ ptr->unk_18 = (i * 1.04f) + 2.4f;
+ ptr->unk_1C.x = phi_s2;
+ ptr->unk_1C.y = (u32)Rand_Next() >> 0x10;
+ ptr->unk_1C.z = 0;
+ ptr->unk_22 = Rand_ZeroFloat(5000.0f);
+ ptr->unk_24 = 0;
+ }
+
+ this->unk_4B0 = 0;
+ this->unk_4B2 = 100;
+ Matrix_StatePop();
+ this->actionFunc = func_80A55064;
+}
+
+void func_80A55064(ObjHugebombiwa* this, GlobalContext* globalCtx) {
+ s32 i;
+ s32 pad;
+ Vec3f spA4;
+ s32 pad2;
+ CollisionPoly* sp9C;
+ s32 sp98;
+ f32 temp_f0;
+ EnHugebombiwaStruct* ptr;
+ s16 phi_s3 = this->actor.shape.rot.y - 0x4000;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s3 += 0x666) {
+ ptr = &this->unk_190[i];
+ if (ptr->unk_24 != 0) {
+ continue;
+ }
+
+ ptr->unk_18 -= 3.0f;
+ if (ptr->unk_18 < -30.0f) {
+ ptr->unk_18 = -30.0f;
+ }
+
+ ptr->unk_0C.x += Math_SinS(phi_s3) * 4.0f;
+ ptr->unk_0C.y += ptr->unk_18;
+ ptr->unk_0C.z += Math_CosS(phi_s3) * 4.0f;
+
+ ptr->unk_1C.x += ptr->unk_22;
+
+ spA4.x = ptr->unk_0C.x;
+ spA4.y = ptr->unk_0C.y + 60.0f;
+ spA4.z = ptr->unk_0C.z;
+
+ temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp9C, &sp98, &this->actor, &spA4);
+ if ((temp_f0 <= BGCHECK_Y_MIN + 10.0f) || ((ptr->unk_0C.y - (350.0f * ptr->unk_00.y)) < temp_f0)) {
+ this->unk_4B0++;
+ ptr->unk_24 = 1;
+ func_80A53E60(globalCtx, &ptr->unk_0C, ptr->unk_18, ptr->unk_00.y * 9.8f);
+ if ((globalCtx->gameplayFrames % 4) == 0) {
+ func_80A54980(this, globalCtx, (s32)(Rand_ZeroOne() * 5.5f) + 1);
+ }
+ }
+ }
+
+ this->unk_4B2--;
+ if ((this->unk_4B0 >= 20) || (this->unk_4B2 <= 0)) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_80A55310(ObjHugebombiwa* this) {
+ s32 i;
+ EnHugebombiwaStruct* ptr;
+ s32 pad;
+ f32 temp_f20;
+ f32 temp_f20_2;
+ s16 phi_s2;
+ Vec3f sp84;
+
+ Matrix_StatePush();
+ Matrix_RotateY(this->actor.shape.rot.y, 0);
+
+ for (i = 0, phi_s2 = 0x1000; i < ARRAY_COUNT(this->unk_190); i++, phi_s2 += 0x4000) {
+ ptr = &this->unk_190[i];
+
+ temp_f20 = (Rand_ZeroOne() * 0.09f) + 0.016f;
+ ptr->unk_00.x = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20;
+ ptr->unk_00.y = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20;
+ ptr->unk_00.z = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20;
+
+ temp_f20_2 = (Rand_ZeroOne() * 85.0f) + 77.0f;
+ sp84.x = Math_SinS(phi_s2) * temp_f20_2;
+ sp84.y = (i + 1) * 14.0f;
+ sp84.z = fabsf(Math_CosS(phi_s2)) * temp_f20_2;
+ Matrix_MultiplyVector3fByState(&sp84, &ptr->unk_0C);
+
+ ptr->unk_0C.x += this->actor.world.pos.x;
+ ptr->unk_0C.y += this->actor.world.pos.y;
+ ptr->unk_0C.z += this->actor.world.pos.z;
+
+ ptr->unk_18 = (i * 1.04f) + 2.4f;
+
+ ptr->unk_1C.x = phi_s2;
+ ptr->unk_1C.y = (u32)Rand_Next() >> 0x10;
+ ptr->unk_1C.z = 0;
+
+ ptr->unk_22 = Rand_ZeroFloat(5000.0f);
+ ptr->unk_24 = 0;
+ }
+
+ this->unk_4B0 = 0;
+ this->unk_4B2 = 100;
+ Matrix_StatePop();
+ this->actionFunc = func_80A55564;
+}
+
+void func_80A55564(ObjHugebombiwa* this, GlobalContext* globalCtx) {
+ s32 i;
+ EnHugebombiwaStruct* ptr;
+ Vec3f spA4;
+ s32 pad;
+ CollisionPoly* sp9C;
+ s32 sp98;
+ f32 temp_f0;
+ s16 phi_s3 = this->actor.shape.rot.y - 0x4000;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s3 += 0x666) {
+ ptr = &this->unk_190[i];
+
+ if (ptr->unk_24 != 0) {
+ continue;
+ }
+
+ ptr->unk_18 -= 3.0f;
+ if (ptr->unk_18 < -30.0f) {
+ ptr->unk_18 = -30.0f;
+ }
+
+ ptr->unk_0C.x += (Math_SinS(phi_s3) * 4.0f);
+ ptr->unk_0C.y += ptr->unk_18;
+ ptr->unk_0C.z += (Math_CosS(phi_s3) * 4.0f);
+
+ ptr->unk_1C.x += ptr->unk_22;
+
+ spA4.x = ptr->unk_0C.x;
+ spA4.y = ptr->unk_0C.y + 60.0f;
+ spA4.z = ptr->unk_0C.z;
+
+ temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp9C, &sp98, &this->actor, &spA4);
+ if ((temp_f0 <= BGCHECK_Y_MIN + 10.0f) || (ptr->unk_0C.y < temp_f0)) {
+ this->unk_4B0++;
+ ptr->unk_24 = 1;
+ func_80A54600(globalCtx, &ptr->unk_0C, ptr->unk_18, ptr->unk_00.y * 10.1f);
+ if ((globalCtx->gameplayFrames % 4) == 0) {
+ func_80A54980(this, globalCtx, (s32)(Rand_ZeroOne() * 5.5f) + 1);
+ }
+ }
+ }
+
+ this->unk_4B2--;
+ if ((this->unk_4B0 >= 20) || (this->unk_4B2 <= 0)) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void ObjHugebombiwa_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjHugebombiwa* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+}
+
+void ObjHugebombiwa_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ ObjHugebombiwa* this = THIS;
+ s32 pad[8];
+ f32 sp38;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if ((this->actionFunc == func_80A54C04) || (this->actionFunc == func_80A54CEC)) {
+ if (this->actor.projectedPos.z <= 4300.0f) {
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0xFF, 255, 255, 255, 255);
+ gSPDisplayList(POLY_OPA_DISP++, object_bombiwa_DL_002F60);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_003110);
+
+ } else if (this->actor.projectedPos.z < 4500.0f) {
+ sp38 = (4500.0f - this->actor.projectedPos.z) * 1.275f;
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0xFF, 255, 255, 255, (s32)sp38);
+ gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_002F60);
+ }
+ } else {
+ s32 i;
+ EnHugebombiwaStruct* ptr;
+ Gfx* gfx = POLY_OPA_DISP;
+
+ gSPDisplayList(gfx++, &sSetupDL[6 * 25]);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) {
+ ptr = &this->unk_190[i];
+
+ if (ptr->unk_24 == 0) {
+ Matrix_SetStateRotationAndTranslation(ptr->unk_0C.x, ptr->unk_0C.y, ptr->unk_0C.z, &ptr->unk_1C);
+ Matrix_Scale(ptr->unk_00.x, ptr->unk_00.x, ptr->unk_00.x, MTXMODE_APPLY);
+
+ gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfx++, object_bombiwa_DL_001990);
+ }
+ }
+
+ POLY_OPA_DISP = gfx;
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A55B34(Actor* thisx, GlobalContext* globalCtx) {
+ ObjHugebombiwa* this = THIS;
+ s32 i;
+ Gfx* gfx;
+ EnHugebombiwaStruct* ptr;
+
+ if ((this->actionFunc == func_80A54C04) || (this->actionFunc == func_80A54CEC)) {
+ func_800BDFC0(globalCtx, object_bombiwa_DL_001820);
+ return;
+ }
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ gfx = POLY_OPA_DISP;
+
+ gSPDisplayList(gfx++, &sSetupDL[6 * 25]);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) {
+ ptr = &this->unk_190[i];
+
+ if (ptr->unk_24 != 0) {
+ continue;
+ }
+
+ Matrix_SetStateRotationAndTranslation(ptr->unk_0C.x, ptr->unk_0C.y + (325.0f * ptr->unk_00.y), ptr->unk_0C.z,
+ &ptr->unk_1C);
+ Matrix_Scale(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, -325.0f, 0.0f, MTXMODE_APPLY);
+
+ gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfx++, object_bombiwa_DL_0009E0);
+ }
+
+ POLY_OPA_DISP = gfx;
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h
index b85add2ef..f1d26aaf4 100644
--- a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h
+++ b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h
@@ -7,9 +7,25 @@ struct ObjHugebombiwa;
typedef void (*ObjHugebombiwaActionFunc)(struct ObjHugebombiwa*, GlobalContext*);
+#define ENHUGEBOMBIWA_GET_7F(thisx) ((thisx)->params & 0x7F)
+#define ENHUGEBOMBIWA_GET_100(thisx) (((thisx)->params >> 8) & 1)
+
+typedef struct {
+ /* 0x00 */ Vec3f unk_00;
+ /* 0x0C */ Vec3f unk_0C;
+ /* 0x18 */ f32 unk_18;
+ /* 0x1C */ Vec3s unk_1C;
+ /* 0x22 */ s16 unk_22;
+ /* 0x24 */ s16 unk_24;
+} EnHugebombiwaStruct; // size = 0x28
+
typedef struct ObjHugebombiwa {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x370];
+ /* 0x0144 */ ColliderCylinder collider;
+ /* 0x0190 */ EnHugebombiwaStruct unk_190[20];
+ /* 0x04B0 */ s16 unk_4B0;
+ /* 0x04B2 */ s8 unk_4B2;
+ /* 0x04B3 */ s8 unk_4B3;
/* 0x04B4 */ ObjHugebombiwaActionFunc actionFunc;
} ObjHugebombiwa; // size = 0x4B8
diff --git a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c
index e85548758..8a5c99a79 100644
--- a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c
+++ b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c
@@ -15,7 +15,6 @@ void ObjJgGakki_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjJgGakki_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjJgGakki_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
const ActorInit Obj_Jg_Gakki_InitVars = {
ACTOR_OBJ_JG_GAKKI,
ACTORCAT_PROP,
@@ -28,14 +27,42 @@ const ActorInit Obj_Jg_Gakki_InitVars = {
(ActorFunc)ObjJgGakki_Draw,
};
-#endif
+extern AnimationHeader D_0601B1E8; // gGoronElderDrumAnim
+extern SkeletonHeader D_0601B210; // gGoronElderDrumSkel
-extern UNK_TYPE D_0601B1E8;
+void ObjJgGakki_Init(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ ObjJgGakki* this = THIS;
+ f32 frameCount = Animation_GetLastFrame(&D_0601B1E8);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Init.s")
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f);
+ SkelAnime_Init(globalCtx, &this->skelAnime, &D_0601B210, NULL, NULL, NULL, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Destroy.s")
+ if (((globalCtx->sceneNum == SCENE_SPOT00) && (gSaveContext.sceneSetupIndex == 7)) &&
+ (globalCtx->csCtx.unk_12 == 0)) {
+ Animation_Change(&this->skelAnime, &D_0601B1E8, 1.0f, frameCount, frameCount, 2, 0.0f);
+ } else if ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA)) {
+ Animation_Change(&this->skelAnime, &D_0601B1E8, 1.0f, 0.0f, frameCount, 2, 0.0f);
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+ Actor_SetScale(&this->actor, 0.01f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Update.s")
+void ObjJgGakki_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ ObjJgGakki* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Draw.s")
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+}
+
+void ObjJgGakki_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjJgGakki* this = THIS;
+
+ SkelAnime_Update(&this->skelAnime);
+}
+
+void ObjJgGakki_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ ObjJgGakki* this = THIS;
+
+ SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->actor);
+}
diff --git a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h
index 75a02ed4a..a3e8ae8eb 100644
--- a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h
+++ b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h
@@ -7,7 +7,8 @@ struct ObjJgGakki;
typedef struct ObjJgGakki {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x90];
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ ColliderCylinder collider;
} ObjJgGakki; // size = 0x1D4
extern const ActorInit Obj_Jg_Gakki_InitVars;
diff --git a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c
index 204b50663..bda43e48d 100644
--- a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c
+++ b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c
@@ -5,6 +5,8 @@
*/
#include "z_obj_kibako.h"
+#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
+#include "objects/object_kibako/object_kibako.h"
#define FLAGS 0x04000010
@@ -66,14 +68,11 @@ static ColliderCylinderInit sCylinderInit = {
{ 15, 30, 0, { 0, 0, 0 } },
};
-extern Gfx D_06001A70[];
-extern Gfx D_06001180[];
-
static s16 sObjectIdList[] = { GAMEPLAY_DANGEON_KEEP, OBJECT_KIBAKO };
-static Gfx* sKakeraDisplayLists[] = { D_05007980, D_06001A70 };
+static Gfx* sKakeraDisplayLists[] = { gameplay_dangeon_keep_DL_007980, gSmallCrateFragmentDL };
-static Gfx* sDisplayLists[] = { D_05007890, D_06001180 };
+static Gfx* sDisplayLists[] = { gameplay_dangeon_keep_DL_007890, gSmallCrateDL };
static InitChainEntry sInitChain[] = {
ICHAIN_F32_DIV1000(gravity, -1500, ICHAIN_CONTINUE),
diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
index 69bfaad18..6bb1bbdb6 100644
--- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
+++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
@@ -5,6 +5,7 @@
*/
#include "z_obj_kibako2.h"
+#include "objects/object_kibako2/object_kibako2.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#define FLAGS 0x00000000
@@ -57,10 +58,6 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP),
};
-extern Gfx D_06000960[];
-extern CollisionHeader D_06000B70;
-extern Gfx D_06001040[];
-
s32 ObjKibako2_ContainsSkulltula(ObjKibako2* this, GlobalContext* globalCtx) {
s32 actorSpawnParam = KIBAKO2_SKULLTULA_SPAWN_PARAM(&this->dyna.actor);
s32 flag = -1;
@@ -103,7 +100,7 @@ void ObjKibako2_Break(ObjKibako2* this, GlobalContext* globalCtx) {
phi_s0 = 0x20;
}
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -200, phi_s0, 28, 2, 0, (Rand_ZeroOne() * 30.0f) + 5.0f,
- 0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, D_06001040);
+ 0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, gLargeCrateFragment1DL);
}
func_800BBFB0(globalCtx, thisPos, 90.0f, 6, 100, 160, 1);
}
@@ -147,12 +144,12 @@ void ObjKibako2_SpawnContents(ObjKibako2* this, GlobalContext* globalCtx) {
void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako2* this = THIS;
s32 pad;
- ObjKibako2Contents contents = KIBAKO2_CONTENTS(&this->dyna.actor);
+ s32 contents = KIBAKO2_CONTENTS(&this->dyna.actor);
DynaPolyActor_Init(&this->dyna, 0);
Collider_InitCylinder(globalCtx, &this->collider);
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
- DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &D_06000B70);
+ DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gLargeCrateCol);
Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit);
Collider_UpdateCylinder(&this->dyna.actor, &this->collider);
this->dyna.actor.home.rot.z = 0;
@@ -250,5 +247,5 @@ void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) {
}
void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx) {
- func_800BDFC0(globalCtx, D_06000960);
+ func_800BDFC0(globalCtx, gLargeCrateDL);
}
diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
index b6de7da89..dd4687ab2 100644
--- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
+++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
@@ -18,11 +18,11 @@ struct ObjKibako2;
typedef void (*ObjKibako2ActionFunc)(struct ObjKibako2*, GlobalContext*);
typedef struct ObjKibako2 {
- /* 0x0000 */ DynaPolyActor dyna;
- /* 0x015C */ ColliderCylinder collider;
- /* 0x01A8 */ ObjKibako2ActionFunc actionFunc;
- /* 0x01AC */ s8 unk_1AC;
- /* 0x01AD */ s8 skulltulaNoiseTimer;
+ /* 0x000 */ DynaPolyActor dyna;
+ /* 0x15C */ ColliderCylinder collider;
+ /* 0x1A8 */ ObjKibako2ActionFunc actionFunc;
+ /* 0x1AC */ s8 unk_1AC;
+ /* 0x1AD */ s8 skulltulaNoiseTimer;
} ObjKibako2; // size = 0x1B0
extern const ActorInit Obj_Kibako2_InitVars;
diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
index e398d3336..01e13e95c 100644
--- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
+++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
@@ -18,7 +18,6 @@ void func_80973CD8(ObjRoomtimer* this, GlobalContext* globalCtx);
void func_80973D3C(ObjRoomtimer* this, GlobalContext* globalCtx);
void func_80973DE0(ObjRoomtimer* this, GlobalContext* globalCtx);
-#if 0
const ActorInit Obj_Roomtimer_InitVars = {
ACTOR_OBJ_ROOMTIMER,
ACTORCAT_ENEMY,
@@ -31,16 +30,64 @@ const ActorInit Obj_Roomtimer_InitVars = {
(ActorFunc)NULL,
};
-#endif
+void ObjRoomtimer_Init(Actor* thisx, GlobalContext* globalCtx) {
+ ObjRoomtimer* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Init.s")
+ this->switchFlag = ROOMTIMER_GET_SWITCHFLAG(thisx);
+ this->actor.params &= 0x1FF;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Destroy.s")
+ if (this->actor.params != 0x1FF) {
+ this->actor.params = CLAMP_MAX(this->actor.params, 500);
+ }
+ this->actionFunc = func_80973CD8;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973CD8.s")
+void ObjRoomtimer_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ ObjRoomtimer* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973D3C.s")
+ if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] > 0) {
+ gSaveContext.unk_3DD0[4] = 5;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973DE0.s")
+void func_80973CD8(ObjRoomtimer* this, GlobalContext* globalCtx) {
+ if (this->actor.params != 0x1FF) {
+ func_8010E9F0(4, this->actor.params);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Update.s")
+ func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_PROP);
+ this->actionFunc = func_80973D3C;
+}
+
+void func_80973D3C(ObjRoomtimer* this, GlobalContext* globalCtx) {
+ if (Actor_GetRoomClearedTemp(globalCtx, this->actor.room)) {
+ if (this->actor.params != 0x1FF) {
+ gSaveContext.unk_3DD0[4] = 5;
+ }
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ this->actionFunc = func_80973DE0;
+ } else if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] == 0) {
+ play_sound(NA_SE_OC_ABYSS);
+ func_80169EFC(globalCtx);
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void func_80973DE0(ObjRoomtimer* this, GlobalContext* globalCtx) {
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ Actor_SetRoomCleared(globalCtx, this->actor.room);
+ Actor_SetSwitchFlag(globalCtx, this->switchFlag);
+ if (ActorCutscene_GetLength(this->actor.cutscene) != -1) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
+ }
+ Actor_MarkForDeath(&this->actor);
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
+
+void ObjRoomtimer_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjRoomtimer* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+}
diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
index db43c5c16..b58d5da49 100644
--- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
+++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
@@ -3,6 +3,8 @@
#include "global.h"
+#define ROOMTIMER_GET_SWITCHFLAG(thisx) (((thisx)->params >> 9) & 0x7F)
+
struct ObjRoomtimer;
typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, GlobalContext*);
@@ -10,7 +12,7 @@ typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, GlobalContext*);
typedef struct ObjRoomtimer {
/* 0x0000 */ Actor actor;
/* 0x0144 */ ObjRoomtimerActionFunc actionFunc;
- /* 0x0148 */ char unk_148[0x4];
+ /* 0x0148 */ s32 switchFlag;
} ObjRoomtimer; // size = 0x14C
extern const ActorInit Obj_Roomtimer_InitVars;
diff --git a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c
index 42cec6623..088e881ed 100644
--- a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c
+++ b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c
@@ -5,6 +5,8 @@
*/
#include "z_obj_snowball.h"
+#include "objects/object_goroiwa/object_goroiwa.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x00000000
@@ -15,7 +17,22 @@ void ObjSnowball_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjSnowball_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjSnowball_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void func_80B02CD0(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B02D58(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B02DB0(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B02E54(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04338(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04350(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04540(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B0457C(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04608(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04648(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B046E4(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B047C0(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04B48(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04B60(ObjSnowball* this, GlobalContext* globalCtx);
+void func_80B04D34(Actor* thisx, GlobalContext* globalCtx);
+
const ActorInit Obj_Snowball_InitVars = {
ACTOR_OBJ_SNOWBALL,
ACTORCAT_PROP,
@@ -28,80 +45,799 @@ const ActorInit Obj_Snowball_InitVars = {
(ActorFunc)ObjSnowball_Draw,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_80B04F50[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x81837FBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x81837FBE, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 73 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_80B04F74 = {
- { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, },
- 1, D_80B04F50, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80B04FD4[] = {
+typedef struct {
+ /* 0x00 */ s16 unk_00;
+ /* 0x02 */ s16 unk_02;
+ /* 0x04 */ ObjSnowballActionFunc unk_04;
+} ObjSnowballStruct2;
+
+static ObjSnowballStruct2 D_80B04F84[] = {
+ { -1, 0, func_80B02D58 },
+ { ACTOR_EN_JG, 0, func_80B02DB0 },
+ { ACTOR_EN_WF, 1, func_80B02E54 },
+ { ACTOR_EN_TITE, -4, func_80B02CD0 },
+ { ACTOR_EN_KAME, 0, func_80B02CD0 },
+ { -1, 0, NULL },
+};
+
+static Color_RGBA8 D_80B04FB4 = { 250, 250, 250, 255 };
+static Color_RGBA8 D_80B04FB8 = { 180, 180, 180, 255 };
+static Vec3f D_80B04FBC = { 0.0f, 0.3f, 0.0f };
+
+static Gfx* D_80B04FC8[] = {
+ object_goroiwa_DL_0072F0,
+ object_goroiwa_DL_0077D0,
+ object_goroiwa_DL_007C60,
+};
+
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP),
};
+void func_80B02CD0(ObjSnowball* this, GlobalContext* globalCtx) {
+ ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y];
+
+ Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x,
+ this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0,
+ this->actor.home.rot.z, ptr->unk_02, -1, this->actor.unk20, NULL);
+}
+
+void func_80B02D58(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 temp_v0 = func_800A8150(OBJSNOWBALL_GET_3F(&this->actor));
+
+ if (temp_v0 >= 0) {
+ Item_DropCollectible(globalCtx, &this->actor.home.pos, (OBJSNOWBALL_GET_7F00(&this->actor) << 8) | temp_v0);
+ }
+}
+
+void func_80B02DB0(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y];
+
+ Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x,
+ this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0,
+ this->actor.home.rot.z, this->actor.params | ptr->unk_02,
+ ActorCutscene_GetAdditionalCutscene(this->actor.cutscene), this->actor.unk20, NULL);
+}
+
+void func_80B02E54(ObjSnowball* this, GlobalContext* globalCtx) {
+ ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y];
+
+ Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x,
+ this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0,
+ this->actor.home.rot.z, this->actor.params | ptr->unk_02, -1, this->actor.unk20,
+ NULL);
+}
+
+void func_80B02EE4(ObjSnowball* this, GlobalContext* globalCtx) {
+ Vec3f spAC;
+ Vec3f spA0;
+ Vec3f sp94;
+ Vec3s* hitPos = &this->collider.elements->info.bumper.hitPos;
+ s32 i;
+
+ for (i = 0; i < 4; i++) {
+ sp94.x = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->x;
+ sp94.y = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->y;
+ sp94.z = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->z;
+
+ spA0.x = (Rand_ZeroOne() - 0.5f) * 1.6f;
+ spA0.y = -0.8f;
+ spA0.z = (Rand_ZeroOne() - 0.5f) * 1.6f;
+
+ spAC.x = spA0.x * -0.06f;
+ spAC.y = spA0.y * -0.06f;
+ spAC.z = spA0.z * -0.06f;
+
+ func_800B0E48(globalCtx, &sp94, &spA0, &spAC, &D_80B04FB4, &D_80B04FB8, (s32)(Rand_ZeroOne() * 30.0f) + 15,
+ (s32)(Rand_ZeroOne() * 40.0f) + 30);
+ }
+}
+
+void func_80B030F8(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 pad;
+ f32 temp_f28 = sqrtf(this->unk_20C);
+ Vec3f spFC;
+ Vec3f spF0;
+ Vec3f spE4;
+ s32 i;
+ s32 phi_s6;
+ Gfx* temp_s2;
+ s16 scale;
+ s32 temp_s1;
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f26;
+ s16 temp_s0;
+ s32 temp_s7;
+ f32 phi_f22;
+ s32 gravity;
+ s32 phi_s0;
+ s32 phi_s4;
+
+ for (i = 0, phi_s6 = 0; i < 25; i++, phi_s6 += 0xA3D) {
+ temp_s7 = i & 7;
+ if (temp_s7 < 4) {
+ temp_s2 = D_80B04FC8[2];
+ gravity = -280;
+ phi_s4 = 0;
+ phi_s0 = 0x40;
+ phi_f22 = 1.0f;
+ } else if (temp_s7 < 6) {
+ temp_s2 = D_80B04FC8[1];
+ gravity = -340;
+ phi_s4 = 0;
+ phi_f22 = 0.9f;
+ if (Rand_ZeroOne() < 0.4f) {
+ phi_s0 = 0x20;
+ } else {
+ phi_s0 = 0x40;
+ }
+ } else {
+ temp_s2 = D_80B04FC8[0];
+ gravity = -400;
+ phi_s4 = 1;
+ phi_f22 = 0.8f;
+ if (Rand_Next() > 0) {
+ phi_s0 = 0x21;
+ } else {
+ phi_s0 = 0x41;
+ }
+ }
+
+ temp_f20 = (Rand_ZeroOne() * (40.0f * this->unk_20C)) + 20.0f;
+
+ spFC.x = Math_SinS((s32)(Rand_ZeroOne() * 2621.44f) + phi_s6) * temp_f20;
+ spFC.y = (Rand_ZeroOne() - 0.4f) * temp_f20 * 1.6666666f;
+ spFC.z = Math_CosS((s32)(Rand_ZeroOne() * 2621.44f) + phi_s6) * temp_f20;
+
+ spF0.x = spFC.x * 0.16f * phi_f22;
+ spF0.y = (Rand_ZeroOne() * 16.0f) + 3.0f;
+ spF0.z = spFC.z * 0.16f * phi_f22;
+
+ spFC.x += this->actor.world.pos.x;
+ spFC.y += this->actor.world.pos.y;
+ spFC.z += this->actor.world.pos.z;
+
+ scale = ((Rand_ZeroOne() * 15.0f) + 30.0f) * this->unk_20C;
+
+ EffectSsKakera_Spawn(globalCtx, &spFC, &spF0, &spFC, gravity, phi_s0, 30, 0, 0, scale, phi_s4, 0, 50, -1, 0xEF,
+ temp_s2);
+ if ((this->unk_210 == 0) && (temp_s7 >= 3)) {
+ spFC.x += (Rand_ZeroOne() * 120.0f) - 60.0f;
+ spFC.y += Rand_ZeroOne() * 80.0f;
+ spFC.z += (Rand_ZeroOne() * 120.0f) - 60.0f;
+
+ temp_s0 = (s32)(Rand_ZeroOne() * 50.0f * temp_f28) + 40;
+ temp_s1 = (s32)(Rand_ZeroOne() * 60.0f * temp_f28) + 50;
+ func_800B0E48(globalCtx, &spFC, &gZeroVec3f, &D_80B04FBC, &D_80B04FB4, &D_80B04FB8, temp_s0, temp_s1);
+ }
+ }
+
+ if (this->unk_210 != 0) {
+ temp_f26 = this->unk_20C * 60.0f;
+
+ for (i = 0, phi_s6 = 0; i < 16; i++, phi_s6 += 0x1000) {
+ temp_s0 = (u32)Rand_Next() >> 0x10;
+ temp_f20 = Math_SinS(temp_s0);
+ temp_f22 = Math_CosS(temp_s0);
+
+ spFC.x = Math_SinS(phi_s6);
+ spFC.z = Math_CosS(phi_s6);
+
+ spF0.x = 2.0f * spFC.x;
+ spF0.y = (2.0f * Rand_ZeroOne()) + 1.0f;
+ spF0.z = 2.0f * spFC.z;
+
+ spFC.x *= temp_f22 * temp_f26;
+ spFC.y = temp_f20 * temp_f26;
+ spFC.z *= temp_f22 * temp_f26;
+
+ spFC.x += this->actor.world.pos.x;
+ spFC.y += this->actor.world.pos.y;
+ spFC.z += this->actor.world.pos.z;
+
+ spE4.x = spF0.x * -0.02f;
+ spE4.y = spF0.y * -0.05f;
+ spE4.z = spF0.z * -0.02f;
+
+ EffectSsIceSmoke_Spawn(globalCtx, &spFC, &spF0, &spE4, ((s32)(Rand_ZeroOne() * 170.0f) + 150) * temp_f28);
+ }
+ }
+}
+
+void func_80B03688(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 i;
+ Vec3f spB8;
+ Vec3f spAC;
+ Vec3f spA0;
+ s32 pad[2];
+ f32 temp_f20;
+ f32 temp_f22 = sqrtf(this->unk_20C);
+ s16 temp_s3;
+ s32 phi_s0;
+
+ if (this->unk_210 == 0) {
+ for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) {
+ temp_f20 = (Rand_ZeroOne() * (45.0f * this->unk_20C)) + 50.0f;
+
+ spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s0) * temp_f20;
+ spB8.y = Rand_ZeroOne() * 20.0f;
+ spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s0) * temp_f20;
+
+ spAC.x = spB8.x * 0.06f;
+ spAC.y = 0.0f;
+ spAC.z = spB8.z * 0.06f;
+
+ spA0.x = spAC.x * -0.08f;
+ spA0.y = 0.3f;
+ spA0.z = spAC.z * -0.08f;
+
+ spB8.x += this->actor.home.pos.x;
+ spB8.y += this->actor.home.pos.y;
+ spB8.z += this->actor.home.pos.z;
+
+ temp_s3 = (s32)(Rand_ZeroOne() * 60.0f * temp_f22) + 70;
+
+ func_800B0E48(globalCtx, &spB8, &spAC, &spA0, &D_80B04FB4, &D_80B04FB8, temp_s3,
+ (s32)(Rand_ZeroOne() * 70.0f * temp_f22) + 70);
+ }
+ } else {
+ for (i = 0, phi_s0 = 0; i < 18; i++, phi_s0 += 0xE38) {
+ temp_f20 = (Rand_ZeroOne() * (45.0f * this->unk_20C)) + 50.0f;
+
+ spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 3640.889f) + phi_s0);
+ spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 3640.889f) + phi_s0);
+
+ spAC.x = spB8.x * 3.0f * temp_f22;
+ spAC.y = 0.0f;
+ spAC.z = spB8.z * 3.0f * temp_f22;
+
+ spA0.x = spAC.x * -0.02f;
+ spA0.y = 0.03f;
+ spA0.z = spAC.z * -0.02f;
+
+ spB8.x = (spB8.x * temp_f20) + this->actor.home.pos.x;
+ spB8.y = (Rand_ZeroOne() * 20.0f) + this->actor.home.pos.y;
+ spB8.z = (spB8.z * temp_f20) + this->actor.home.pos.z;
+
+ EffectSsIceSmoke_Spawn(globalCtx, &spB8, &spAC, &spA0, (s32)(Rand_ZeroOne() * 140.0f * temp_f22) + 100);
+ }
+ }
+}
+
+#ifdef NON_MATCHING
+void func_80B03A80(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2) {
+ f32 temp_f30 = sqrtf(arg1);
+ Vec3f spD8;
+ Vec3f spCC;
+ s32 i;
+ Gfx* temp_s1;
+ f32 temp_f20;
+ s32 phi_s5;
+ s32 pad;
+ s16 phi_s2;
+ s32 pad2;
+ s16 phi_s0;
+ s16 phi_s3;
+
+ for (i = 0, phi_s5 = 0; i < 13; i++, phi_s5 += 0x1999) {
+ temp_f20 = (Rand_ZeroOne() * (40.0f * arg1)) + 20.0f;
+
+ spD8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s5) * temp_f20;
+ spD8.y = Rand_ZeroOne() * temp_f20;
+ spD8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s5) * temp_f20;
+
+ spCC.x = spD8.x * 0.17f;
+ spCC.y = (Rand_ZeroOne() * 14.0f) + 3.0f;
+ spCC.z = spD8.z * 0.17f;
+
+ spD8.x += arg2->x;
+ spD8.y += arg2->y;
+ spD8.z += arg2->z;
+
+ if ((i & 3) == 0) {
+ temp_s1 = D_80B04FC8[0];
+ phi_s2 = -400;
+ phi_s3 = 1;
+ if (Rand_Next() > 0) {
+ phi_s0 = 0x21;
+ } else {
+ phi_s0 = 0x41;
+ }
+ } else if ((i & 3) == 1) {
+ temp_s1 = D_80B04FC8[1];
+ phi_s2 = -340;
+ phi_s3 = 1;
+ if (Rand_Next() > 0) {
+ phi_s0 = 0x21;
+ } else {
+ phi_s0 = 0x41;
+ }
+ } else {
+ temp_s1 = D_80B04FC8[2];
+ phi_s2 = -280;
+ phi_s3 = 0;
+ phi_s0 = 0x40;
+ }
+
+ EffectSsKakera_Spawn(globalCtx, &spD8, &spCC, &spD8, phi_s2, phi_s0, 30, 0, 0,
+ ((Rand_ZeroOne() * 15.0f) + 25.0f) * arg1, phi_s3, 0, 0x36, -1, 0xEF, temp_s1);
+
+ spD8.x += (Rand_ZeroOne() * 80.0f) - 40.0f;
+ spD8.y += Rand_ZeroOne() * 55.0f;
+ spD8.z += (Rand_ZeroOne() * 80.0f) - 40.0f;
+
+ phi_s0 = (s32)(Rand_ZeroOne() * 60.0f * temp_f30) + 60;
+
+ func_800B0E48(globalCtx, &spD8, &gZeroVec3f, &D_80B04FBC, &D_80B04FB4, &D_80B04FB8, phi_s0,
+ (s32)(Rand_ZeroOne() * 30.0f * temp_f30) + 60);
+ }
+}
+#else
+void func_80B03A80(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2);
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03A80.s")
#endif
-extern ColliderJntSphElementInit D_80B04F50[1];
-extern ColliderJntSphInit D_80B04F74;
-extern InitChainEntry D_80B04FD4[];
+void func_80B03E2C(ObjSnowball* this, GlobalContext* globalCtx) {
+ ObjSnowballStruct* ptr;
+ s32 i;
-extern UNK_TYPE D_060082D0;
-extern UNK_TYPE D_06008B90;
+ this->unk_1A8[0].unk_1C.y = this->actor.yawTowardsPlayer - 0x4000;
+ this->unk_1A8[0].unk_24 = Rand_ZeroOne() * -600.0f;
+ this->unk_1A8[1].unk_1C.y = this->actor.yawTowardsPlayer + 0x4000;
+ this->unk_1A8[1].unk_24 = Rand_ZeroOne() * 600.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02CD0.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) {
+ ptr = &this->unk_1A8[i];
+ ptr->unk_00.x = this->actor.home.pos.x;
+ ptr->unk_00.y = this->actor.home.pos.y + (61.0f * this->unk_20C);
+ ptr->unk_00.z = this->actor.home.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02D58.s")
+ ptr->unk_0C = Math_SinS(ptr->unk_1C.y) * (Rand_ZeroOne() + 5.0f);
+ ptr->unk_10 = (Rand_ZeroOne() * 11.0f) + 20.0f;
+ ptr->unk_14 = Math_CosS(ptr->unk_1C.y) * (Rand_ZeroOne() + 5.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02DB0.s")
+ ptr->unk_1C.x = 0;
+ ptr->unk_1C.z = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02E54.s")
+ ptr->unk_22 = (s32)(Rand_ZeroOne() * 400.0f) + 1100;
+ ptr->unk_26 = Rand_ZeroOne() * -600.0f;
+ ptr->unk_2D = 0;
+ ptr->unk_2C = 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02EE4.s")
+void func_80B03FF8(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s16 rotY = this->actor.home.rot.y;
+ ObjSnowballStruct2* sp18 = &D_80B04F84[rotY];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B030F8.s")
+ if (sp18->unk_04 != NULL) {
+ sp18->unk_04(this, globalCtx);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03688.s")
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_SNOWBALL_BROKEN);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03A80.s")
+ if (rotY == 5) {
+ Actor_SetSwitchFlag(globalCtx, OBJSNOWBALL_GET_3F(&this->actor));
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03E2C.s")
+void ObjSnowball_Init(Actor* thisx, GlobalContext* globalCtx) {
+ ObjSnowball* this = THIS;
+ Sphere16* sphere;
+ ColliderJntSphElementDim* elementDim;
+ Vec3f sp48;
+ s32 sp44;
+ s32 sp40 = this->actor.home.rot.y;
+ f32 phi_f20;
+ s32 sp34;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03FF8.s")
+ Actor_ProcessInitChain(&this->actor, sInitChain);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Init.s")
+ sp34 = sp40 == 1;
+ if (sp34) {
+ phi_f20 = 1.5f;
+ } else {
+ phi_f20 = 1.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Destroy.s")
+ Actor_SetScale(&this->actor, 0.1f * phi_f20);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04338.s")
+ this->actor.shape.rot.x = 0;
+ this->actor.shape.rot.z = 0;
+ this->actor.world.pos.y += 20.0f * phi_f20;
+ this->actor.uncullZoneScale = 150.0f * phi_f20;
+ this->actor.uncullZoneDownward = 300.0f * phi_f20;
+ this->actor.shape.rot.y = (u32)Rand_Next() >> 0x10;
+ this->unk_20C = phi_f20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04350.s")
+ if (sp34) {
+ this->actor.textId = 0x238;
+ this->actor.flags |= 1;
+ this->actor.targetArrowOffset = 1400.0f / 3.0f;
+ Actor_SetHeight(&this->actor, 24.0f);
+ this->actor.targetMode = 3;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04540.s")
+ Collider_InitJntSph(globalCtx, &this->collider);
+ Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
+ this->actor.colChkInfo.mass = MASS_HEAVY;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B0457C.s")
+ sphere = &this->collider.elements[0].dim.worldSphere;
+ sphere->center.x = this->actor.world.pos.x;
+ sphere->center.y = this->actor.world.pos.y;
+ sphere->center.z = this->actor.world.pos.z;
+ sphere->radius =
+ (this->collider.elements[0].dim.scale * this->collider.elements[0].dim.modelSphere.radius) * phi_f20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04608.s")
+ sp48.x = this->actor.home.pos.x;
+ sp48.y = this->actor.home.pos.y + 30.0f;
+ sp48.z = this->actor.home.pos.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04648.s")
+ this->actor.floorHeight =
+ BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp44, &this->actor, &sp48);
+ if (this->actor.floorHeight < (this->actor.home.pos.y - 10.0f)) {
+ this->actor.floorPoly = NULL;
+ } else {
+ ActorShape_Init(&this->actor.shape, 0.0f, NULL, 13.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B046E4.s")
+ func_80B04338(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B047C0.s")
+ if ((sp40 == 5) && Flags_GetSwitch(globalCtx, OBJSNOWBALL_GET_3F(&this->actor))) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B48.s")
+void ObjSnowball_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ ObjSnowball* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B60.s")
+ Collider_DestroyJntSph(globalCtx, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Update.s")
+void func_80B04338(ObjSnowball* this, GlobalContext* globalCtx) {
+ this->actionFunc = func_80B04350;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Draw.s")
+void func_80B04350(ObjSnowball* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 flag = (this->collider.base.acFlags & AC_HIT) != 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04D34.s")
+ if (flag) {
+ this->collider.base.acFlags &= ~AC_HIT;
+ }
+
+ if (flag && (this->unk_211 == 0) &&
+ (this->collider.elements->info.acHitInfo->toucher.dmgFlags &
+ (0x80000000 | 0x4000 | 0x800 | 0x400 | 0x100 | 0x8))) {
+ this->actor.flags |= 0x10;
+ if (this->actor.home.rot.y == 1) {
+ this->actor.flags &= ~(8 | 1);
+ }
+
+ if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x4000) {
+ this->unk_20A = 1;
+ } else {
+ if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x800) {
+ this->unk_210 = 1;
+ }
+ this->unk_20A = 0;
+ }
+
+ if (this->actor.cutscene < 0) {
+ func_80B03FF8(this, globalCtx);
+ if (this->unk_20A == 0) {
+ func_80B04608(this, globalCtx);
+ } else {
+ func_80B046E4(this, globalCtx);
+ }
+ } else {
+ func_80B04540(this, globalCtx);
+ }
+ return;
+ }
+
+ if (flag &&
+ !(this->collider.elements->info.acHitInfo->toucher.dmgFlags & (0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20))) {
+ if (this->unk_209 <= 0) {
+ func_80B02EE4(this, globalCtx);
+ if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x1000000) {
+ this->unk_209 = 25;
+ } else {
+ this->unk_209 = 10;
+ }
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_REFLECTION_SNOW);
+ }
+ }
+
+ if (this->unk_209 > 0) {
+ this->unk_209--;
+ }
+
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+}
+
+void func_80B04540(ObjSnowball* this, GlobalContext* globalCtx) {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ this->actionFunc = func_80B0457C;
+}
+
+void func_80B0457C(ObjSnowball* this, GlobalContext* globalCtx) {
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
+ func_80B03FF8(this, globalCtx);
+ this->unk_20B = 1;
+ if (this->unk_20A == 0) {
+ func_80B04608(this, globalCtx);
+ } else {
+ func_80B046E4(this, globalCtx);
+ }
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
+
+void func_80B04608(ObjSnowball* this, GlobalContext* globalCtx) {
+ func_80B030F8(this, globalCtx);
+ this->actor.draw = NULL;
+ this->unk_208 = 50;
+ this->actor.floorPoly = NULL;
+ this->actionFunc = func_80B04648;
+}
+
+void func_80B04648(ObjSnowball* this, GlobalContext* globalCtx) {
+ this->unk_208--;
+ if (this->unk_208 <= 0) {
+ if (this->unk_20B != 0) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ }
+
+ if (this->actor.home.rot.y == 1) {
+ func_80B04B48(this, globalCtx);
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+ } else if (this->unk_208 == 0x2D) {
+ func_80B03688(this, globalCtx);
+ }
+}
+
+void func_80B046E4(ObjSnowball* this, GlobalContext* globalCtx) {
+ Vec3f sp44;
+ s32 i;
+
+ func_80B03E2C(this, globalCtx);
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) {
+ sp44.x = this->unk_1A8[i].unk_00.x;
+ sp44.y = this->unk_1A8[i].unk_00.y - (60.0f * this->unk_20C);
+ sp44.z = this->unk_1A8[i].unk_00.z;
+ func_80B03A80(globalCtx, this->unk_20C, &sp44);
+ }
+
+ this->actor.draw = func_80B04D34;
+ this->actor.floorPoly = NULL;
+ this->unk_208 = 50;
+ this->actionFunc = func_80B047C0;
+}
+
+void func_80B047C0(ObjSnowball* this, GlobalContext* globalCtx) {
+ static Vec3f D_80B04FD8 = { 0.0f, 1.0f, 0.0f };
+ static Vec3f D_80B04FE4 = { 0.0f, 0.0f, 1.0f };
+ s32 pad;
+ ObjSnowballStruct* ptr;
+ Vec3f sp9C;
+ s32 sp98;
+ s32 i;
+ Vec3f sp88;
+ f32 sp84;
+ f32 phi_f2;
+ f32 sp7C;
+ Vec3f sp70;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) {
+ ptr = &this->unk_1A8[i];
+
+ if (!(ptr->unk_2D & 1)) {
+ ptr->unk_10 -= 6.0f;
+ ptr->unk_10 *= 0.96f;
+ if (ptr->unk_10 < -20.0f) {
+ ptr->unk_10 = -20.0f;
+ }
+
+ ptr->unk_00.x += ptr->unk_0C;
+ ptr->unk_00.y += ptr->unk_10;
+ ptr->unk_00.z += ptr->unk_14;
+
+ ptr->unk_1C.x += ptr->unk_22;
+ ptr->unk_1C.y += ptr->unk_24;
+ ptr->unk_1C.z += ptr->unk_26;
+
+ sp9C.x = ptr->unk_00.x;
+ sp9C.y = ptr->unk_00.y + 25.0f;
+ sp9C.z = ptr->unk_00.z;
+
+ ptr->unk_18 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &ptr->unk_28, &sp98, &this->actor, &sp9C);
+
+ if (ptr->unk_10 <= 0.0f) {
+ Matrix_InsertRotation(ptr->unk_1C.x, ptr->unk_1C.y, ptr->unk_1C.z, MTXMODE_NEW);
+ Matrix_MultiplyVector3fByState(&D_80B04FE4, &sp88);
+
+ sp84 = this->unk_20C * 60.0f * 0.9f;
+ if (sp88.y > 0.0f) {
+ if (Math3D_AngleBetweenVectors(&D_80B04FD8, &sp88, &sp7C)) {
+ phi_f2 = 1.0f;
+ } else {
+ phi_f2 = 1.0f - SQ(sp7C);
+ }
+
+ if (phi_f2 <= 0.0f) {
+ sp84 = 0.0f;
+ } else {
+ sp84 *= sqrtf(phi_f2);
+ }
+ }
+
+ if (((ptr->unk_00.y - sp84) < ptr->unk_18) || (ptr->unk_18 < BGCHECK_Y_MIN + 10.0f)) {
+ ptr->unk_2D |= 1;
+ sp70.x = ptr->unk_00.x;
+ sp70.y = ptr->unk_00.y - sp84;
+ sp70.z = ptr->unk_00.z;
+ func_80B03A80(globalCtx, this->unk_20C, &sp70);
+ }
+ }
+ }
+ }
+
+ this->unk_208--;
+
+ if ((this->unk_208 <= 0) || ((this->unk_1A8[0].unk_2D & 1) && (this->unk_1A8[1].unk_2D & 1))) {
+ if (this->unk_20B != 0) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ }
+
+ if (this->actor.home.rot.y == 1) {
+ func_80B04B48(this, globalCtx);
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ }
+ } else {
+ for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) {
+ ptr = &this->unk_1A8[i];
+
+ if (ptr->unk_2D & 1) {
+ ptr->unk_2C = 0;
+ } else if (ptr->unk_2C < 136) {
+ ptr->unk_2C += 24;
+ } else {
+ ptr->unk_2C = 160;
+ }
+ }
+ }
+}
+
+void func_80B04B48(ObjSnowball* this, GlobalContext* globalCtx) {
+ this->actionFunc = func_80B04B60;
+}
+
+void func_80B04B60(ObjSnowball* this, GlobalContext* globalCtx) {
+}
+
+void ObjSnowball_Update(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjSnowball* this = THIS;
+ s32 sp24 = false;
+
+ if (this->actor.home.rot.y == 1) {
+ if (this->unk_211 != 0) {
+ if (func_800B867C(&this->actor, globalCtx)) {
+ this->actor.flags &= ~0x10;
+ this->unk_211 = 0;
+ }
+ } else if (func_800B84D0(&this->actor, globalCtx)) {
+ this->actor.flags |= 0x10;
+ this->unk_211 = 1;
+ } else if (this->actor.isTargeted) {
+ sp24 = true;
+ }
+ }
+
+ this->actionFunc(this, globalCtx);
+
+ if (sp24 && (this->actionFunc == func_80B04350)) {
+ func_800B8614(&this->actor, globalCtx, 100.0f);
+ }
+
+ if ((this->actor.floorPoly != NULL) && (this->actor.projectedPos.z < 920.0f)) {
+ if (this->actor.projectedPos.z > 400.0f) {
+ this->actor.shape.shadowAlpha = (920 - (s32)this->actor.projectedPos.z) >> 2;
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ } else if (this->actor.projectedPos.z > -30.0f) {
+ this->actor.shape.shadowAlpha = 130;
+ this->actor.shape.shadowDraw = func_800B3FC0;
+ } else {
+ this->actor.shape.shadowDraw = NULL;
+ }
+ } else {
+ this->actor.shape.shadowDraw = NULL;
+ }
+}
+
+void ObjSnowball_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ ObjSnowball* this = THIS;
+
+ func_800BDFC0(globalCtx, object_goroiwa_DL_008B90);
+}
+
+void func_80B04D34(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjSnowball* this = THIS;
+ ObjSnowballStruct* ptr;
+ s32 i;
+ MtxF sp88;
+ Vec3s sp80;
+
+ for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) {
+ ptr = &this->unk_1A8[i];
+
+ if (!(ptr->unk_2D & 1)) {
+ sp80.x = ptr->unk_1C.x;
+ sp80.y = ptr->unk_1C.y;
+ sp80.z = ptr->unk_1C.z;
+
+ Matrix_SetStateRotationAndTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &sp80);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ func_800BDFC0(globalCtx, object_goroiwa_DL_0082D0);
+
+ if ((ptr->unk_28 != NULL) && (ptr->unk_2C > 0)) {
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C448(globalCtx->state.gfxCtx);
+
+ gDPSetCombineLERP(POLY_XLU_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0,
+ 0, COMBINED);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, ptr->unk_2C);
+
+ func_800C0094(ptr->unk_28, ptr->unk_00.x, ptr->unk_18, ptr->unk_00.z, &sp88);
+ Matrix_SetCurrentState(&sp88);
+ Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_076BC0);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+ }
+ }
+}
diff --git a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h
index fc5aafdde..c6bc03100 100644
--- a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h
+++ b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h
@@ -7,11 +7,37 @@ struct ObjSnowball;
typedef void (*ObjSnowballActionFunc)(struct ObjSnowball*, GlobalContext*);
+#define OBJSNOWBALL_GET_3F(thisx) ((thisx)->params & 0x3F)
+#define OBJSNOWBALL_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F)
+
+typedef struct {
+ /* 0x00 */ Vec3f unk_00;
+ /* 0x0C */ f32 unk_0C;
+ /* 0x10 */ f32 unk_10;
+ /* 0x14 */ f32 unk_14;
+ /* 0x18 */ f32 unk_18;
+ /* 0x1C */ Vec3s unk_1C;
+ /* 0x22 */ s16 unk_22;
+ /* 0x24 */ s16 unk_24;
+ /* 0x26 */ s16 unk_26;
+ /* 0x28 */ CollisionPoly* unk_28;
+ /* 0x2C */ u8 unk_2C;
+ /* 0x2D */ u8 unk_2D;
+} ObjSnowballStruct; // size = 0x30
+
typedef struct ObjSnowball {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x60];
- /* 0x01A4 */ ObjSnowballActionFunc actionFunc;
- /* 0x01A8 */ char unk_1A8[0x6C];
+ /* 0x000 */ Actor actor;
+ /* 0x144 */ ColliderJntSph collider;
+ /* 0x164 */ ColliderJntSphElement colliderElements[1];
+ /* 0x1A4 */ ObjSnowballActionFunc actionFunc;
+ /* 0x1A8 */ ObjSnowballStruct unk_1A8[2];
+ /* 0x208 */ s8 unk_208;
+ /* 0x209 */ s8 unk_209;
+ /* 0x20A */ s8 unk_20A;
+ /* 0x20B */ s8 unk_20B;
+ /* 0x20C */ f32 unk_20C;
+ /* 0x210 */ s8 unk_210;
+ /* 0x211 */ s8 unk_211;
} ObjSnowball; // size = 0x214
extern const ActorInit Obj_Snowball_InitVars;
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
index ce8807131..0c0a72279 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
@@ -5,6 +5,7 @@
*/
#include "z_object_kankyo.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0x02000030
@@ -15,12 +16,17 @@ void ObjectKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjectKankyo_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjectKankyo_Draw(Actor* thisx, GlobalContext* globalCtx);
+void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc);
+void func_808DC18C(ObjectKankyo* this, GlobalContext* globalCtx);
void func_808DCB7C(ObjectKankyo* this, GlobalContext* globalCtx);
void func_808DCBF8(ObjectKankyo* this, GlobalContext* globalCtx);
+void func_808DCDB4(ObjectKankyo* this, GlobalContext* globalCtx);
+void func_808DD3C8(Actor* thisx, GlobalContext* globalCtx2);
+void func_808DD970(Actor* thisx, GlobalContext* globalCtx2);
+void func_808DDE9C(Actor* thisx, GlobalContext* globalCtx2);
-void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc);
+static f32 D_808DE5B0;
-#if 0
const ActorInit Object_Kankyo_InitVars = {
ACTOR_OBJECT_KANKYO,
ACTORCAT_ITEMACTION,
@@ -33,42 +39,694 @@ const ActorInit Object_Kankyo_InitVars = {
(ActorFunc)ObjectKankyo_Draw,
};
-#endif
+static u16 D_808DE340 = 0;
-extern UNK_TYPE D_01000000;
+void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc) {
+ this->actionFunc = actionFunc;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_SetupAction.s")
+void func_808DBE8C(ObjectKankyo* this) {
+ ObjectKankyo_SetupAction(this, func_808DC18C);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBE8C.s")
+void func_808DBEB0(ObjectKankyo* this, GlobalContext* globalCtx) {
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBEB0.s")
+ D_808DE5B0 = 0.0f;
+ this->unk_144 = Rand_ZeroOne() * 360.0f;
+ this->unk_148 = Rand_ZeroOne() * 360.0f;
+ if (globalCtx->envCtx.unk_F2[2] == 128) {
+ D_808DE5B0 = 1.0f;
+ this->unk_114E = 1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBFB0.s")
+ for (i = 0; i < globalCtx->envCtx.unk_F2[2]; i++) {
+ this->unk_14C[i].unk_10 = Rand_ZeroOne() * -200.0f;
+ }
+ } else {
+ this->unk_114E = 0;
+ }
+ ObjectKankyo_SetupAction(this, func_808DCB7C);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC038.s")
+void func_808DBFB0(ObjectKankyo* this, GlobalContext* globalCtx) {
+ D_808DE5B0 = 0.0f;
+ this->unk_114E = 0;
+ this->unk_144 = Rand_ZeroOne() * 360.0f;
+ this->unk_148 = Rand_ZeroOne() * 360.0f;
+ this->unk_114C = D_808DE340;
+ D_808DE340++;
+ ObjectKankyo_SetupAction(this, func_808DCBF8);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Init.s")
+void func_808DC038(ObjectKankyo* this, GlobalContext* globalCtx) {
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Destroy.s")
+ this->unk_144 = Rand_ZeroOne() * 360.0f;
+ this->unk_148 = Rand_ZeroOne() * 360.0f;
+ this->unk_114C = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC18C.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_14C); i++) {
+ this->unk_14C[i].unk_1C = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC454.s")
+ ObjectKankyo_SetupAction(this, func_808DCDB4);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCB7C.s")
+void ObjectKankyo_Init(Actor* thisx, GlobalContext* globalCtx) {
+ ObjectKankyo* this = THIS;
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCBF8.s")
+ for (i = 0; i < ARRAY_COUNT(this->unk_14C); i++) {
+ this->unk_14C[i].unk_1C = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCDB4.s")
+ this->actor.room = -1;
+ switch (this->actor.params) {
+ case 0:
+ func_808DBE8C(this);
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Update.s")
+ case 2:
+ globalCtx->envCtx.unk_F2[2] = 0x80;
+ func_808DBFB0(this, globalCtx);
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Draw.s")
+ case 1:
+ case 3:
+ func_808DBEB0(this, globalCtx);
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DD3C8.s")
+ case 4:
+ func_808DC038(this, globalCtx);
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DD970.s")
+void ObjectKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ ObjectKankyo* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DDE74.s")
+ Actor_MarkForDeath(&this->actor);
+}
+void func_808DC18C(ObjectKankyo* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 pad2;
+ s32 pad3;
+ f32 magnitude;
+ f32 y;
+ f32 z;
+ f32 temp_f18;
+ Vec3f sp30;
+ f32 x;
+ f32 sp1C;
+
+ x = globalCtx->view.at.x - globalCtx->view.eye.x;
+ y = globalCtx->view.at.y - globalCtx->view.eye.y;
+ z = globalCtx->view.at.z - globalCtx->view.eye.z;
+ magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z));
+
+ temp_f18 = x / magnitude;
+ x = z / magnitude;
+ sp1C = (y / magnitude) * 120.0f;
+
+ this->unk_14C[0].unk_00 = globalCtx->view.eye.x + (temp_f18 * 50.0f);
+ this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C;
+ this->unk_14C[0].unk_08 = globalCtx->view.eye.z + (x * 50.0f);
+ this->unk_14C[1].unk_00 = globalCtx->view.eye.x + (temp_f18 * 220.0f);
+ this->unk_14C[1].unk_08 = globalCtx->view.eye.z + (x * 220.0f);
+ this->unk_114C = 0;
+ this->unk_144 = 100.0f;
+
+ if ((this->unk_14C[0].unk_00 < -252.0f) && (this->unk_14C[0].unk_00 > -500.0f)) {
+ if ((this->unk_14C[0].unk_08 > 3820.0f) && (this->unk_14C[0].unk_08 < 4150.0f)) {
+ this->unk_114C = 1;
+ this->unk_144 = 400.0f;
+ if (x < 0.0f) {
+ this->unk_14C[0].unk_00 = -350.0f;
+ this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C;
+ this->unk_14C[0].unk_08 = 3680.0f;
+ this->unk_14C[1].unk_00 = -350.0f;
+ this->unk_14C[1].unk_08 = 3680.0f;
+ } else {
+ this->unk_14C[0].unk_00 = -350.0f;
+ this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C;
+ this->unk_14C[0].unk_08 = 4280.0f;
+ this->unk_14C[1].unk_00 = -350.0f;
+ this->unk_14C[1].unk_08 = 4280.0f;
+ }
+ }
+ }
+
+ magnitude = globalCtx->envCtx.windSpeed / 60.0f;
+ magnitude = CLAMP(magnitude, 0.0f, 1.0f);
+
+ sp30.x = globalCtx->envCtx.windDir.x * magnitude;
+ sp30.y = globalCtx->envCtx.windDir.y + 100.0f;
+ sp30.z = globalCtx->envCtx.windDir.z * magnitude;
+ this->unk_14C[2].unk_00 = 0x4000 - Math_Vec3f_Pitch(&gZeroVec3f, &sp30);
+ this->unk_14C[2].unk_04 = Math_Vec3f_Yaw(&gZeroVec3f, &sp30) + 0x8000;
+}
+
+void func_808DC454(ObjectKankyo* this, GlobalContext* globalCtx) {
+ s16 i;
+ u32 tempI;
+ f32 phi_f20;
+ f32 spD0;
+ f32 spCC;
+ f32 spC8;
+ f32 spC4;
+ f32 spC0;
+ f32 spBC;
+ f32 temp_f0_4;
+ f32 temp_f22;
+ f32 temp_f24;
+ f32 temp_f28;
+ f32 x = globalCtx->view.at.x - globalCtx->view.eye.x;
+ f32 y = globalCtx->view.at.y - globalCtx->view.eye.y;
+ f32 z = globalCtx->view.at.z - globalCtx->view.eye.z;
+ f32 magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z));
+ f32 temp_120 = 120.0f;
+ f32 temp_f30;
+ Vec3f sp88;
+ s32 pad;
+
+ spD0 = x / magnitude;
+ spCC = y / magnitude;
+ spC8 = z / magnitude;
+
+ for (i = 0; i < globalCtx->envCtx.unk_F2[2]; i++) {
+ switch (this->unk_14C[i].unk_1C) {
+ case 0:
+ this->unk_14C[i].unk_00 = globalCtx->view.eye.x + (spD0 * 120.0f);
+ this->unk_14C[i].unk_04 = globalCtx->view.eye.y + (spCC * 120.0f);
+ this->unk_14C[i].unk_08 = globalCtx->view.eye.z + (spC8 * 120.0f);
+ this->unk_14C[i].unk_0C = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120);
+
+ temp_f22 = (func_800DFCB4(GET_ACTIVE_CAM(globalCtx)) * 0.004f) + 60.0f;
+ if (temp_f22 < 20.0f) {
+ temp_f22 = 20.0f;
+ }
+
+ if (this->unk_114E == 0) {
+ this->unk_14C[i].unk_10 = temp_f22;
+ } else {
+ this->unk_14C[i].unk_10 += temp_f22;
+ tempI = i;
+ if (globalCtx->envCtx.unk_F2[2] == (tempI + 1)) {
+ this->unk_114E = 0;
+ }
+ }
+
+ this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120);
+ if (globalCtx->envCtx.unk_F2[4] == 0) {
+ this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 1.0f;
+ } else {
+ this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 8.0f;
+ }
+ this->unk_14C[i].unk_1C++;
+ break;
+
+ case 1:
+ temp_f24 = globalCtx->view.eye.x + (spD0 * 120.0f);
+ temp_f28 = globalCtx->view.eye.y + (spCC * 120.0f);
+ temp_f30 = globalCtx->view.eye.z + (spC8 * 120.0f);
+
+ magnitude = sqrtf((f32)SQ(globalCtx->envCtx.windDir.x) + SQ(globalCtx->envCtx.windDir.y) +
+ SQ(globalCtx->envCtx.windDir.z));
+ if (magnitude == 0.0f) {
+ magnitude = 0.001f;
+ }
+ spC4 = -globalCtx->envCtx.windDir.x / magnitude;
+ spC0 = -globalCtx->envCtx.windDir.y / magnitude;
+ spBC = -globalCtx->envCtx.windDir.z / magnitude;
+
+ if (i == 0) {
+ this->unk_144 += 0.049999997f * Rand_ZeroOne();
+ this->unk_148 += 0.049999997f * Rand_ZeroOne();
+ }
+
+ phi_f20 = globalCtx->envCtx.windSpeed / 120.0f;
+ phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f);
+
+ this->unk_14C[i].unk_0C += __sinf((this->unk_144 + (i * 100.0f)) * 0.01f) + (spC4 * 10.0f * phi_f20);
+ this->unk_14C[i].unk_14 += __cosf((this->unk_148 + (i * 100.0f)) * 0.01f) + (spBC * 10.0f * phi_f20);
+ this->unk_14C[i].unk_10 -=
+ this->unk_14C[i].unk_18 - (spC0 * 3.0f * (globalCtx->envCtx.windSpeed / 100.0f));
+
+ temp_f22 = (-func_800DFCB4(GET_ACTIVE_CAM(globalCtx)) * 0.012f) + 40.0f;
+ if (temp_f22 < -40.0f) {
+ temp_f22 = -40.0f;
+ }
+
+ if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) > temp_120) {
+ this->unk_14C[i].unk_00 = temp_f24 - temp_120;
+ }
+
+ if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) < -temp_120) {
+ this->unk_14C[i].unk_00 = temp_f24 + temp_120;
+ }
+
+ sp88.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C;
+ sp88.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10;
+ sp88.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14;
+
+ phi_f20 = Math_Vec3f_DistXZ(&sp88, &globalCtx->view.eye) / 200.0f;
+ phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f);
+ temp_f0_4 = 100.0f + phi_f20 + 60.0f;
+
+ if (temp_f0_4 < (this->unk_14C[i].unk_04 + (this->unk_14C[i].unk_10) - temp_f28)) {
+ this->unk_14C[i].unk_04 = temp_f28 - temp_f0_4;
+ }
+
+ if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_f0_4) {
+ this->unk_14C[i].unk_04 = temp_f28 + temp_f0_4;
+ }
+
+ if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) > temp_120) {
+ this->unk_14C[i].unk_08 = temp_f30 - temp_120;
+ }
+
+ if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) < -temp_120) {
+ this->unk_14C[i].unk_08 = temp_f30 + temp_120;
+ }
+
+ if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) <
+ ((globalCtx->view.eye.y - temp_f22) - 40.0f)) {
+ this->unk_14C[i].unk_1C = 0;
+ }
+ break;
+ }
+ }
+}
+
+void func_808DCB7C(ObjectKankyo* this, GlobalContext* globalCtx) {
+ if (globalCtx->envCtx.unk_F2[2] < globalCtx->envCtx.unk_F2[3]) {
+ if ((globalCtx->state.frames % 16) == 0) {
+ globalCtx->envCtx.unk_F2[2] += 2;
+ }
+ } else if (globalCtx->envCtx.unk_F2[3] < globalCtx->envCtx.unk_F2[2]) {
+ if ((globalCtx->state.frames % 16) == 0) {
+ globalCtx->envCtx.unk_F2[2] -= 2;
+ }
+ }
+ func_808DC454(this, globalCtx);
+}
+
+void func_808DCBF8(ObjectKankyo* this, GlobalContext* globalCtx) {
+ f32 temp_f0;
+
+ if ((globalCtx->envCtx.unk_F2[2] > 0) && (this->unk_114C == 0)) {
+ if ((globalCtx->state.frames % 16) == 0) {
+ globalCtx->envCtx.unk_F2[2] -= 9;
+ if ((s8)globalCtx->envCtx.unk_F2[2] < 0) {
+ globalCtx->envCtx.unk_F2[2] = 0;
+ }
+ }
+ }
+
+ temp_f0 = (f32)globalCtx->envCtx.unk_F2[2] / 128;
+ temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f);
+
+ if (temp_f0 > 0.01f) {
+ D_801F4E30 = 155.0f * temp_f0;
+ globalCtx->envCtx.unk_EA = 10;
+ } else {
+ D_801F4E30 = 0;
+ globalCtx->envCtx.unk_EA = 10;
+ }
+ func_808DC454(this, globalCtx);
+}
+
+void func_808DCDB4(ObjectKankyo* this, GlobalContext* globalCtx) {
+ s16 i;
+ f32 magnitude;
+ f32 temp_80;
+ f32 temp_120;
+ f32 spAC;
+ f32 spA8;
+ f32 spA4;
+ f32 spA0;
+ f32 sp9C;
+ f32 x;
+ f32 y;
+ f32 z;
+ f32 temp_f18;
+ f32 temp_f20;
+ f32 temp_f26;
+ f32 temp_f28;
+
+ if (this->unk_114C < 0x80) {
+ this->unk_114C++;
+ }
+
+ x = globalCtx->view.at.x - globalCtx->view.eye.x;
+ y = globalCtx->view.at.y - globalCtx->view.eye.y;
+ z = globalCtx->view.at.z - globalCtx->view.eye.z;
+
+ magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z));
+
+ spAC = x / magnitude;
+ spA8 = y / magnitude;
+ spA4 = z / magnitude;
+
+ temp_80 = 80.0f;
+ temp_120 = 120.0f;
+
+ for (i = 0; i < this->unk_114C; i++) {
+ switch (this->unk_14C[i].unk_1C) {
+ case 0:
+ this->unk_14C[i].unk_00 = globalCtx->view.eye.x + (spAC * 120.0f);
+ this->unk_14C[i].unk_04 = globalCtx->view.eye.y + (spA8 * 120.0f);
+ this->unk_14C[i].unk_08 = globalCtx->view.eye.z + (spA4 * 120.0f);
+ this->unk_14C[i].unk_0C = (Rand_ZeroOne() - 0.5f) * (temp_120 * 2.0f);
+ if ((i % 2) == 0) {
+ this->unk_14C[i].unk_10 = -100.0f;
+ } else {
+ this->unk_14C[i].unk_10 = 100.0f;
+ }
+ this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (temp_120 * 2.0f);
+ this->unk_14C[i].unk_18 = Rand_ZeroOne() + 0.2f;
+ this->unk_14C[i].unk_1C++;
+ break;
+
+ case 1:
+
+ temp_f26 = globalCtx->view.eye.x + (spAC * 120.0f);
+ temp_f28 = globalCtx->view.eye.y + (spA8 * 120.0f);
+ temp_f18 = globalCtx->view.eye.z + (spA4 * 120.0f);
+
+ magnitude = sqrtf((f32)SQ(globalCtx->envCtx.windDir.x) + SQ(globalCtx->envCtx.windDir.y) +
+ SQ(globalCtx->envCtx.windDir.z));
+ if (magnitude == 0.0f) {
+ magnitude = 0.001f;
+ }
+
+ spA0 = -globalCtx->envCtx.windDir.x / magnitude;
+ sp9C = -globalCtx->envCtx.windDir.z / magnitude;
+
+ if (i == 0) {
+ this->unk_144 += 0.049999997f * Rand_ZeroOne();
+ this->unk_148 += 0.049999997f * Rand_ZeroOne();
+ }
+ temp_f20 = globalCtx->envCtx.windSpeed / 120.0f;
+ temp_f20 = CLAMP(temp_f20, 0.0f, 1.0f);
+
+ this->unk_14C[i].unk_0C += __sinf((this->unk_144 + i) * 0.01f) + (spA0 * 10.0f * temp_f20);
+ this->unk_14C[i].unk_14 += __cosf((this->unk_148 + i) * 0.01f) + (sp9C * 10.0f * temp_f20);
+
+ if ((i % 2) == 0) {
+ this->unk_14C[i].unk_10 += this->unk_14C[i].unk_18;
+ if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) > (globalCtx->view.eye.y + 100.0f)) {
+ this->unk_14C[i].unk_1C = 0;
+ }
+ } else {
+ this->unk_14C[i].unk_10 -= this->unk_14C[i].unk_18;
+ if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) < (globalCtx->view.eye.y - 100.0f)) {
+ this->unk_14C[i].unk_1C = 0;
+ }
+ }
+
+ if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) > temp_80) {
+ this->unk_14C[i].unk_00 = temp_f26 - temp_80;
+ }
+
+ if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) < -temp_80) {
+ this->unk_14C[i].unk_00 = temp_f26 + temp_80;
+ }
+
+ if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) > temp_80) {
+ this->unk_14C[i].unk_04 = temp_f28 - temp_80;
+ }
+
+ if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_80) {
+ this->unk_14C[i].unk_04 = temp_f28 + temp_80;
+ }
+
+ if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) > temp_80) {
+ this->unk_14C[i].unk_08 = temp_f18 - temp_80;
+ }
+
+ if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) < -temp_80) {
+ this->unk_14C[i].unk_08 = temp_f18 + temp_80;
+ }
+ break;
+ }
+ }
+}
+
+void ObjectKankyo_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjectKankyo* this = THIS;
+
+ this->actionFunc(this, globalCtx);
+}
+
+void ObjectKankyo_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ ObjectKankyo* this = THIS;
+
+ switch (this->actor.params) {
+ case 0:
+ func_808DDE9C(thisx, globalCtx);
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ func_808DD3C8(thisx, globalCtx);
+ break;
+
+ case 4:
+ func_808DD970(thisx, globalCtx);
+ break;
+ }
+}
+
+void func_808DD3C8(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ ObjectKankyo* this = THIS;
+ Vec3f spC4;
+ Vec3f spB8;
+ s16 i;
+ u8 pad2;
+ u8 spB4;
+ f32 temp_f0;
+ u8 sp68;
+ s32 pad;
+ f32 temp_f2;
+ f32 tempf;
+
+ if ((globalCtx->cameraPtrs[MAIN_CAM]->flags2 & 0x100) || ((u8)globalCtx->envCtx.unk_E2 == 0)) {
+ return;
+ }
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ spB4 = false;
+
+ if (this->actor.params == 3) {
+ temp_f0 = func_80173B48(&globalCtx->state) / 1.4e7f;
+ temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f);
+ Math_SmoothStepToF(&D_808DE5B0, temp_f0, 0.2f, 0.1f, 0.001f);
+
+ sp68 = globalCtx->envCtx.unk_F2[2];
+ sp68 *= D_808DE5B0;
+
+ if ((globalCtx->envCtx.unk_F2[2] >= 32) && (sp68 < 32)) {
+ sp68 = 32;
+ }
+ } else {
+ sp68 = globalCtx->envCtx.unk_F2[2];
+ }
+
+ for (i = 0; i < sp68; i++) {
+ spC4.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C;
+ spC4.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10;
+ spC4.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14;
+ func_80169474(globalCtx, &spC4, &spB8);
+
+ if ((spB8.x >= 0.0f) && (spB8.x < 320.0f) && (spB8.y >= 0.0f) && (spB8.y < 240.0f)) {
+ if (!spB4) {
+ spB4 = true;
+
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255);
+ gSPClearGeometryMode(POLY_XLU_DISP++, G_LIGHTING);
+
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
+
+ gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2);
+ gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG);
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08EBE0));
+ }
+
+ Matrix_InsertTranslation(spC4.x, spC4.y, spC4.z, MTXMODE_NEW);
+ tempf = (i & 7) * 0.008f;
+ Matrix_Scale(0.05f + tempf, 0.05f + tempf, 0.05f + tempf, MTXMODE_APPLY);
+ temp_f2 = Math_Vec3f_DistXYZ(&spC4, &globalCtx->view.eye) / 300.0f;
+ temp_f2 = ((1.0f < temp_f2) ? 0.0f : (((1.0f - temp_f2) > 1.0f) ? 1.0f : 1.0f - temp_f2));
+
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(160.0f * temp_f2));
+
+ Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_023130);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_808DD970(Actor* thisx, GlobalContext* globalCtx2) {
+ f32 temp_f0;
+ f32 temp_f20;
+ Vec3f spBC;
+ Vec3f spB0;
+ f32 tempf;
+ s16 i;
+ f32 phi_f26;
+ GlobalContext* globalCtx = globalCtx2;
+ ObjectKankyo* this = THIS;
+ f32 tempA;
+
+ if (globalCtx->sceneNum == SCENE_KYOJINNOMA) {
+ phi_f26 = 1.0f;
+ } else {
+ tempA = func_800E031C(GET_ACTIVE_CAM(globalCtx));
+ if (tempA != BGCHECK_Y_MIN) {
+ tempA -= globalCtx->view.eye.y;
+ phi_f26 = tempA / 4000.0f;
+ } else {
+ phi_f26 = 0.0f;
+ }
+
+ phi_f26 = CLAMP_MAX(phi_f26, 1.0f);
+
+ if (!(globalCtx->cameraPtrs[MAIN_CAM]->flags2 & 0x100) || (phi_f26 == 0.0f)) {
+ return;
+ }
+ }
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < this->unk_114C; i++) {
+ spBC.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C;
+ spBC.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10;
+ spBC.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14;
+ func_80169474(globalCtx, &spBC, &spB0);
+
+ if ((spB0.x >= 0.0f) && (spB0.x < 320.0f) && (spB0.y >= 0.0f) && (spB0.y < 240.0f)) {
+ Matrix_InsertTranslation(spBC.x, spBC.y, spBC.z, MTXMODE_NEW);
+ Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY);
+ temp_f0 = Math_Vec3f_DistXYZ(&spBC, &globalCtx->view.eye);
+ temp_f0 = (u8)(255.0f * phi_f26) * (1.0f - (temp_f0 / 300.0f));
+
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 55, temp_f0);
+ gDPSetEnvColor(POLY_XLU_DISP++, 55, 50, 255, temp_f0);
+
+ Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08EBE0));
+ gSPClearGeometryMode(POLY_XLU_DISP++, G_LIGHTING);
+
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
+
+ gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2);
+ gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_023130);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+f32 func_808DDE74(void) {
+ return Rand_ZeroOne() - 0.5f;
+}
+
+#ifdef NON_MATCHING
+// globalCtx->envCtx.unk_F2[1] needs to be laoded into s0 and then copied to s7
+void func_808DDE9C(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ ObjectKankyo* this = THIS;
+ Player* player = GET_PLAYER(globalCtx);
+ s32 i;
+ s16 temp;
+ f32 temp_f12;
+ f32 temp_f20;
+ f32 temp_f22;
+ f32 temp_f2;
+ u8 phi_s5;
+ s32 end = globalCtx->envCtx.unk_F2[1];
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ if (end != 0) {
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 25);
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20);
+ }
+
+ for (i = 0; i < end; i++) {
+ temp_f20 = this->unk_14C[0].unk_00 + ((Rand_ZeroOne() - 0.7f) * this->unk_144);
+ temp_f22 = this->unk_14C[0].unk_04 + ((Rand_ZeroOne() - 0.7f) * this->unk_144);
+ temp_f2 = this->unk_14C[0].unk_08 + ((Rand_ZeroOne() - 0.7f) * this->unk_144);
+
+ if ((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f)) {
+ continue;
+ }
+
+ Matrix_InsertTranslation(temp_f20, temp_f22, temp_f2, MTXMODE_NEW);
+
+ gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
+
+ Matrix_RotateY((s16)this->unk_14C[2].unk_04 + (s16)(i << 5), MTXMODE_APPLY);
+ Matrix_InsertXRotation_s((s16)this->unk_14C[2].unk_00 + (s16)(i << 5), MTXMODE_APPLY);
+
+ if (this->unk_114C == 0) {
+ Matrix_Scale(0.5f, 1.0f, 0.5f, MTXMODE_APPLY);
+ } else {
+ Matrix_Scale(2.0f, 4.0f, 2.0f, MTXMODE_APPLY);
+ }
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_0706E0);
+ }
+
+ phi_s5 = false;
+ if (player->actor.floorHeight < globalCtx->view.eye.y) {
+ for (i = 0; i < end; i++) {
+ if (!phi_s5) {
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 100);
+ phi_s5++;
+ }
+
+ temp_f20 = this->unk_14C[1].unk_00 + (func_808DDE74() * 220.0f);
+ temp_f22 = player->actor.floorHeight + 2.0f;
+ temp_f2 = this->unk_14C[1].unk_08 + (func_808DDE74() * 220.0f);
+
+ if ((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f)) {
+ continue;
+ }
+
+ Matrix_InsertTranslation(temp_f20, temp_f22, temp_f2, MTXMODE_NEW);
+ temp_f12 = (Rand_ZeroOne() * 0.05f) + 0.05f;
+ Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_030100);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DDE9C.s")
+#endif
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
index f61d140d8..646863be0 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
@@ -7,9 +7,24 @@ struct ObjectKankyo;
typedef void (*ObjectKankyoActionFunc)(struct ObjectKankyo*, GlobalContext*);
+typedef struct {
+ /* 0x00 */ f32 unk_00;
+ /* 0x04 */ f32 unk_04;
+ /* 0x08 */ f32 unk_08;
+ /* 0x0C */ f32 unk_0C;
+ /* 0x10 */ f32 unk_10;
+ /* 0x14 */ f32 unk_14;
+ /* 0x18 */ f32 unk_18;
+ /* 0x1C */ u8 unk_1C;
+} ObjectKankyoStruct; // size = 0x20
+
typedef struct ObjectKankyo {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x100C];
+ /* 0x0144 */ f32 unk_144;
+ /* 0x0148 */ f32 unk_148;
+ /* 0x014C */ ObjectKankyoStruct unk_14C[128];
+ /* 0x114C */ u16 unk_114C;
+ /* 0x114E */ u8 unk_114E;
/* 0x1150 */ ObjectKankyoActionFunc actionFunc;
} ObjectKankyo; // size = 0x1154
diff --git a/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c b/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c
index d1a6afb3e..9dcf3ab15 100644
--- a/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c
+++ b/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c
@@ -56,7 +56,7 @@ void TGSw_ActionExecuteOneShot(TGSw* this, GlobalContext* globalCtx) {
if (1) {}
do {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_ENEMY, ACTOR_EN_SW);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_ENEMY, ACTOR_EN_SW);
if (actor == NULL) {
break;
}
@@ -71,7 +71,7 @@ void TGSw_ActionExecuteOneShot(TGSw* this, GlobalContext* globalCtx) {
actor = NULL;
do {
- actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_SW);
+ actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_SW);
if (actor == NULL) {
break;
diff --git a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
index 39f9e51d5..0d26eec89 100644
--- a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
+++ b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
@@ -20,8 +20,6 @@ const EffectSsInit Effect_Ss_Dead_Dd_InitVars = {
#endif
-extern UNK_TYPE D_01000000;
-
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Dead_Dd/EffectSsDeadDd_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Dead_Dd/EffectSsDeadDd_Draw.s")
diff --git a/tools/ZAPDConfigs/MM/Config.xml b/tools/ZAPDConfigs/MM/Config.xml
index 657040010..02656c7df 100644
--- a/tools/ZAPDConfigs/MM/Config.xml
+++ b/tools/ZAPDConfigs/MM/Config.xml
@@ -4,10 +4,5 @@
-
-
diff --git a/tools/actorfixer.py b/tools/actorfixer.py
index 77fe5d38a..979106fb3 100755
--- a/tools/actorfixer.py
+++ b/tools/actorfixer.py
@@ -301,28 +301,13 @@ animdict = {
"func_8017F9C0": "Math3D_XZInSphere",
"func_8017FA34": "Math3D_XYInSphere",
"func_8017FAA8": "Math3D_YZInSphere",
+ "func_8013A7C0": "SubS_FindDoor",
+ "func_8013E640": "SubS_FindActorCustom",
+ "func_ActorCategoryIterateById": "SubS_FindActor",
+ "func_8013BB7C": "SubS_FindNearestActor",
"func_800A81F0": "EffectBlure_AddVertex",
"func_800A8514": "EffectBlure_AddSpace",
"Effect_GetParams": "Effect_GetByIndex",
- "D_0407D590": "gGameplayKeepDrawFlameDL",
-
-
- "skelanime.unk03": "skelanime.taper",
- "skelanime.animCurrentSeg": "skelanime.animation",
- "skelanime.initialFrame": "skelanime.startFrame",
- "skelanime.animFrameCount": "skelanime.endFrame",
- "skelanime.totalFrames": "skelanime.animLength",
- "skelanime.animCurrentFrame": "skelanime.curFrame",
- "skelanime.animPlaybackSpeed": "skelanime.playSpeed",
- "skelanime.limbDrawTbl": "skelanime.jointTable",
- "skelanime.transitionDrawTbl": "skelanime.morphTable",
- "skelanime.transCurrentFrame": "skelanime.morphWeight",
- "skelanime.transitionStep": "skelanime.morphRate",
- "skelanime.animUpdate": "skelanime.update",
- "skelanime.flags": "skelanime.moveFlags",
- "skelanime.prevFrameRot": "skelanime.prevRot",
- "skelanime.prevFramePos": "skelanime.prevTransl",
- "skelanime.unk3E": "skelanime.baseTransl",
"skelAnime.unk03": "skelAnime.taper",
"skelAnime.animCurrentSeg": "skelAnime.animation",
@@ -340,16 +325,16 @@ animdict = {
"skelAnime.prevFrameRot": "skelAnime.prevRot",
"skelAnime.prevFramePos": "skelAnime.prevTransl",
"skelAnime.unk3E": "skelAnime.baseTransl",
- "actor.yDistToWater" : "actor.depthInWater",
- "actor.yDistToPlayer" : "actor.playerHeightRel",
+ "actor.yDistToWater": "actor.depthInWater",
+ "actor.yDistToPlayer": "actor.playerHeightRel",
+ "globalCtx->mf_187FC": "globalCtx->billboardMtxF",
+ "globalCtx->projectionMatrix": "globalCtx->viewProjectionMtxF",
- "globalCtx->mf_187FC" : "globalCtx->billboardMtxF",
- "globalCtx->projectionMatrix" : "globalCtx->viewProjectionMtxF",
-
- "D_801D15B0" : "gZeroVec3f",
- "D_801D15BC" : "gZeroVec3s",
- "D_801D1DE0" : "gIdentityMtx",
- "D_801D1E20" : "gIdentityMtxF",
+ "D_0407D590": "gGameplayKeepDrawFlameDL",
+ "D_801D15B0": "gZeroVec3f",
+ "D_801D15BC": "gZeroVec3s",
+ "D_801D1DE0": "gIdentityMtx",
+ "D_801D1E20": "gIdentityMtxF",
}
def replace_anim(file):
diff --git a/tools/disasm/disasm.py b/tools/disasm/disasm.py
index 42473379e..e0b7705ea 100755
--- a/tools/disasm/disasm.py
+++ b/tools/disasm/disasm.py
@@ -4,9 +4,20 @@ import argparse, ast, math, os, re, struct
import bisect
from mips_isa import *
from multiprocessing import *
+from pathlib import Path
parser = argparse.ArgumentParser()
-parser.add_argument('-j', dest='jobs', type=int, default=1, help='number of processes to run at once')
+parser.add_argument(
+ "-j", dest="jobs", type=int, default=1, help="number of processes to run at once"
+)
+parser.add_argument(
+ "--full",
+ "-f",
+ dest="full",
+ action="store_true",
+ default=False,
+ help="Decompile all files regardless of whether they are used or not",
+)
args = parser.parse_args()
jobs = args.jobs
@@ -14,127 +25,242 @@ jobs = args.jobs
ASM_OUT = "asm/"
DATA_OUT = "data/"
+
+def discard_decomped_files(files_spec):
+ root_path = Path(__file__).parent.parent.parent
+
+ with open(root_path / "spec", "r") as f:
+ spec = f.read()
+ # No need to check anything beyond here
+ spec = spec[: spec.find('name "gameplay_keep"')].splitlines()[:-2]
+
+ new_spec = []
+ for f in files_spec:
+ name, _, type, _, file_list = f
+
+ # Find the beginseg for this file
+ i = 0
+ while i < len(spec):
+ if spec[i].startswith("beginseg") and f'"{name}"' in spec[i + 1]:
+ break
+ i += 1
+
+ # For every file within this segment, look through the seg for lines with this file's name
+ # if found, check whether it's still in build/asm/ or build/data/, in which case it's not decomped
+ # if all references to it are in build/src/ then it should be ok to skip, some code/boot files are a bit different
+
+ seg_start = i
+ new_files = {}
+ included = False
+ saved_off = 0
+ for offset, file in file_list.items():
+ if file == "[PADDING]":
+ continue
+
+ # some files aren't named
+ if file == "":
+ file = f"{type}_{offset:08X}"
+ include = True
+ # flg_set_table is not in the spec, and buffers has its own section, just add them
+ elif file == "flg_set_table" or "buffers" in file:
+ include = True
+ else:
+ include = False
+ i = seg_start
+ last_line = ""
+ while not spec[i].startswith("endseg"):
+ if f"/{file}." in spec[i]:
+ if spec[i].count(".") == 1:
+ last_line = spec[i]
+ if "build/asm/" in spec[i] or "build/data/" in spec[i]:
+ include = True
+ break
+ i += 1
+ else:
+ # Many code/boot files only have a single section (i.e .text)
+ # In that case it will be inside build/src/ and pragma in the asm
+ # For these files, open the source and look for the pragmas to be sure
+ # Overlays always have at least a data section we can check in the spec, so it's not needed for them
+ if type != "overlay" and last_line != "":
+ assert last_line.count(".") == 1
+ last_line = (
+ last_line.strip()
+ .split("build/", 1)[1]
+ .replace(".o", ".c")[:-1]
+ )
+ with open(root_path / last_line, "r") as f2:
+ if "GLOBAL_ASM" in f2.read():
+ include = True
+
+ if include:
+ new_files[offset] = file
+ included = True
+
+ if type == "overlay" and not included:
+ continue
+ if included:
+ f[4] = new_files
+
+ new_spec.append(f)
+
+ return new_spec
+
+
MIPS_BRANCH_LIKELY_INSNS = [
- MIPS_INS_BEQL, MIPS_INS_BGEZALL,
- MIPS_INS_BGEZL, MIPS_INS_BGTZL,
- MIPS_INS_BLEZL, MIPS_INS_BLTZALL,
- MIPS_INS_BLTZL, MIPS_INS_BNEL,
- MIPS_INS_BC1TL, MIPS_INS_BC1FL,
+ MIPS_INS_BEQL,
+ MIPS_INS_BGEZALL,
+ MIPS_INS_BGEZL,
+ MIPS_INS_BGTZL,
+ MIPS_INS_BLEZL,
+ MIPS_INS_BLTZALL,
+ MIPS_INS_BLTZL,
+ MIPS_INS_BNEL,
+ MIPS_INS_BC1TL,
+ MIPS_INS_BC1FL,
]
MIPS_BRANCH_INSNS = [
*MIPS_BRANCH_LIKELY_INSNS,
MIPS_INS_BEQ,
- MIPS_INS_BGEZ, MIPS_INS_BGEZAL,
+ MIPS_INS_BGEZ,
+ MIPS_INS_BGEZAL,
MIPS_INS_BGTZ,
MIPS_INS_BNE,
- MIPS_INS_BLTZ, MIPS_INS_BLTZAL,
+ MIPS_INS_BLTZ,
+ MIPS_INS_BLTZAL,
MIPS_INS_BLEZ,
- MIPS_INS_BC1T, MIPS_INS_BC1F,
-
+ MIPS_INS_BC1T,
+ MIPS_INS_BC1F,
MIPS_INS_BEQZ,
MIPS_INS_BNEZ,
MIPS_INS_B,
]
-MIPS_JUMP_INSNS = [
- MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J, MIPS_INS_JR
-]
+MIPS_JUMP_INSNS = [MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J, MIPS_INS_JR]
-MIPS_FP_LOAD_INSNS = [
- MIPS_INS_LWC1, MIPS_INS_LDC1
-]
+MIPS_FP_LOAD_INSNS = [MIPS_INS_LWC1, MIPS_INS_LDC1]
-MIPS_FP_STORE_INSNS = [
- MIPS_INS_SWC1, MIPS_INS_SDC1
-]
+MIPS_FP_STORE_INSNS = [MIPS_INS_SWC1, MIPS_INS_SDC1]
-MIPS_FP_LOAD_STORE_INSNS = [
- *MIPS_FP_LOAD_INSNS, *MIPS_FP_STORE_INSNS
-]
+MIPS_FP_LOAD_STORE_INSNS = [*MIPS_FP_LOAD_INSNS, *MIPS_FP_STORE_INSNS]
MIPS_STORE_INSNS = [
- MIPS_INS_SB,
- MIPS_INS_SH,
- MIPS_INS_SW, MIPS_INS_SWL, MIPS_INS_SWR,
- MIPS_INS_SD, MIPS_INS_SDL, MIPS_INS_SDR,
- MIPS_INS_SC, MIPS_INS_SCD,
- *MIPS_FP_STORE_INSNS
+ MIPS_INS_SB,
+ MIPS_INS_SH,
+ MIPS_INS_SW,
+ MIPS_INS_SWL,
+ MIPS_INS_SWR,
+ MIPS_INS_SD,
+ MIPS_INS_SDL,
+ MIPS_INS_SDR,
+ MIPS_INS_SC,
+ MIPS_INS_SCD,
+ *MIPS_FP_STORE_INSNS,
]
MIPS_LOAD_STORE_INSNS = [
- MIPS_INS_LB, MIPS_INS_LBU,
- MIPS_INS_LH, MIPS_INS_LHU,
- MIPS_INS_LW, MIPS_INS_LWL, MIPS_INS_LWR, MIPS_INS_LWU,
- MIPS_INS_LD, MIPS_INS_LDL, MIPS_INS_LDR,
- MIPS_INS_LL, MIPS_INS_LLD,
+ MIPS_INS_LB,
+ MIPS_INS_LBU,
+ MIPS_INS_LH,
+ MIPS_INS_LHU,
+ MIPS_INS_LW,
+ MIPS_INS_LWL,
+ MIPS_INS_LWR,
+ MIPS_INS_LWU,
+ MIPS_INS_LD,
+ MIPS_INS_LDL,
+ MIPS_INS_LDR,
+ MIPS_INS_LL,
+ MIPS_INS_LLD,
*MIPS_STORE_INSNS,
- *MIPS_FP_LOAD_STORE_INSNS
+ *MIPS_FP_LOAD_STORE_INSNS,
]
-functions = set() # vram of functions
-data_labels = set() # vram of data labels, TODO this + functions can merge into something more general eventually
+VRAM_BASE = {
+ "code": {"data": 0x801AAAB0, "rodata": 0x801DBDF0, "bss": 0x801E3FA0},
+ "boot": {"data": 0x800969C0, "rodata": 0x80098190, "bss": 0x80099500},
+}
+functions = set() # vram of functions
+# vram of data labels, TODO this + functions can merge into something more general eventually
+data_labels = set()
branch_labels = set() # vram of branch labels via branch/jump instructions
-jtbls = set() # vram of jump tables
-jtbl_labels = set() # vram of branch labels via jtbls, higher output priority than regular branch labels
-floats = set() # vram of floats
-doubles = set() # vram of doubles
-prospective_strings = set() # vram of possible strings
-strings = set() # vram of confirmed strings
-symbols = {} # lui/addiu pairs : {addr of %hi : full symbol} AND {addr of %lo : full symbol} , twice the space complexity but much less time complexity
-constants = {} # lui/ori pairs : {addr of %hi : full constant} AND {addr of %lo : full constant} , twice the space complexity but much less time complexity
-dwords = set() # doublewords
-multiply_referenced_rodata = set() # rodata with more than 1 reference outside of the same function cannot be migrated
+jtbls = set() # vram of jump tables
+# vram of branch labels via jtbls, higher output priority than regular branch labels
+jtbl_labels = set()
+floats = set() # vram of floats
+doubles = set() # vram of doubles
+prospective_strings = set() # vram of possible strings
+strings = set() # vram of confirmed strings
+# lui/addiu pairs : {addr of %hi : full symbol} AND {addr of %lo : full symbol} ,
+# twice the space complexity but much less time complexity
+symbols = {}
+# lui/ori pairs : {addr of %hi : full constant} AND {addr of %lo : full constant} ,
+# twice the space complexity but much less time complexity
+constants = {}
+dwords = set() # doublewords
+# rodata with more than 1 reference outside of the same function cannot be migrated
+multiply_referenced_rodata = set()
+files = set() # vram start of file
-files = set() # vram start of file
-
-vrom_variables = list() # (name,addr)
-vrom_addrs = set() # set of addrs from vrom_variables, for faster lookup
+vrom_variables = list() # (name,addr)
+vrom_addrs = set() # set of addrs from vrom_variables, for faster lookup
functions_ast = None
variables_ast = None
variable_addrs = None
+files_text = {}
+
+
def proper_name(symbol, in_data=False, is_symbol=True):
# hacks
- if symbol == 0x809C46F0: # ovl_En_Encount4 fake symbol at the very end of the data section
+ # ovl_En_Encount4 fake symbol at the very end of the data section
+ if symbol == 0x809C46F0:
return variables_ast[0x809C46DC][0] + " + 0x14"
- elif symbol == 0x801EF66D: # z_message_nes constant-folding stray fairy array
+ elif symbol == 0x801EF66D: # z_message_nes constant-folding stray fairy array
return variables_ast[0x801EF670][0] + f" - 0x{0x801EF670 - 0x801EF66D:X}"
- elif symbol == 0x80A09740: # boss_07 symbol with large addend folded into %lo
+ elif symbol == 0x80A09740: # boss_07 symbol with large addend folded into %lo
return variables_ast[0x80A09A60][0] + f" - 0x{0x80A09A60 - 0x80A09740:X}"
- elif symbol == 0x80B80248: # bg_ikana_mirror symbol with large addend folded into %lo
+ # bg_ikana_mirror symbol with large addend folded into %lo
+ elif symbol == 0x80B80248:
return variables_ast[0x80B801A8][0] + f" + 0x{0x80B80248 - 0x80B801A8:X}"
- elif symbol == 0x8084D2FC: # player symbol with very large addend folded into %lo, since we don't know the real symbol just use the first data symbol for now
+ # player symbol with very large addend folded into %lo, since we don't know the real symbol just use the first data symbol for now
+ elif symbol == 0x8084D2FC:
return variables_ast[0x8085B9F0][0] + f" - 0x{0x8085B9F0 - 0x8084D2FC:X}"
- elif symbol == 0x001ABAB0 or symbol == 0x001E3BB0: # OS_K0_TO_PHYSICAL on rspS2DEX text and data symbols
+ # OS_K0_TO_PHYSICAL on rspS2DEX text and data symbols
+ elif symbol == 0x001ABAB0 or symbol == 0x001E3BB0:
return variables_ast[symbol + 0x80000000][0] + " - 0x80000000"
- elif symbol == 0x00AC0480: # do_action_static + 0x480, this is the only rom segment that has a constant offset folded into it so just hack it
+ # do_action_static + 0x480, this is the only rom segment that has a constant offset folded into it so just hack it
+ elif symbol == 0x00AC0480:
return "_do_action_staticSegmentRomStart + 0x480"
# real names
- if symbol in functions and symbol in functions_ast.keys():
+ if symbol in functions_ast.keys():
return functions_ast[symbol][0]
elif symbol in variables_ast.keys():
return variables_ast[symbol][0]
elif symbol in vrom_addrs:
# prefer "start" vrom symbols
- if symbol in [addr for name,addr in vrom_variables if "SegmentRomStart" in name]:
- return [name for name,addr in vrom_variables if "SegmentRomStart" in name and addr == symbol][0]
+ filteredVromSymbols = {
+ addr: name
+ for name, addr in vrom_variables
+ if "SegmentRomStart" in name and addr == symbol
+ }
+ if symbol in filteredVromSymbols:
+ return filteredVromSymbols[symbol]
else:
- return [name for name,addr in vrom_variables if addr == symbol][0]
+ return [name for name, addr in vrom_variables if addr == symbol][0]
# addends
if is_symbol:
symbol_index = bisect.bisect(variable_addrs, symbol)
if symbol_index:
- vram_addr = variable_addrs[symbol_index-1]
+ vram_addr = variable_addrs[symbol_index - 1]
symbol_name, _, _, symbol_size = variables_ast[vram_addr]
if vram_addr < symbol < vram_addr + symbol_size:
return f"{symbol_name} + 0x{symbol-vram_addr:X}"
-
# generated names
if symbol in functions and not in_data:
return f"func_{symbol:08X}"
@@ -148,63 +274,77 @@ def proper_name(symbol, in_data=False, is_symbol=True):
else:
return f"0x{symbol:08X}"
+
def lookup_name(symbol, word):
# hacks for vrom variables in data
if word in vrom_addrs:
- if word == 0: # no makerom segment start
+ if word == 0: # no makerom segment start
return "0x00000000"
- if symbol in [0x801AE4A0, # effect table
- 0x801C2740, # object table
- 0x801C2650, # elf_message table
- 0x801C3CA0, # scene table
- 0x801AEFD0, # actor table
- 0x801D0B70, # kaleido table
- 0x801D0BB0, # fbdemo table
- 0x801BE4D4, # kankyo skybox table
- 0x801BD910, # gamestate table
- 0x801C2660 # scene textures table
- ]: # data labels that are allowed to have vrom variables
+ if symbol in [
+ 0x801AE4A0, # effect table
+ 0x801C2740, # object table
+ 0x801C2650, # elf_message table
+ 0x801C3CA0, # scene table
+ 0x801AEFD0, # actor table
+ 0x801D0B70, # kaleido table
+ 0x801D0BB0, # fbdemo table
+ 0x801BE4D4, # kankyo skybox table
+ 0x801BD910, # gamestate table
+ 0x801C2660, # scene textures table
+ ]: # data labels that are allowed to have vrom variables
return proper_name(word, is_symbol=False)
else:
return f"0x{word:08X}"
# hacks for variables with references to variables with addends (i.e. gSaveContext + 0x...)
- if symbol in [0x800980C4, 0x801AE8F0]: # __osViNext and flg_set table
+ if symbol in [0x800980C4, 0x801AE8F0]: # __osViNext and flg_set table
return proper_name(word, is_symbol=True)
return proper_name(word, is_symbol=False)
+
def as_double(b):
return struct.unpack(">d", b)[0]
+
def as_float(b):
return struct.unpack(">f", b)[0]
+
def as_dword(b):
return struct.unpack(">Q", b)[0]
+
def as_word(b):
return struct.unpack(">I", b)[0]
+
def as_hword(b):
return struct.unpack(">H", b)[0]
+
def as_double_list(b):
return [i[0] for i in struct.iter_unpack(">d", b)]
+
def as_float_list(b):
return [i[0] for i in struct.iter_unpack(">f", b)]
+
def as_dword_list(b):
return [i[0] for i in struct.iter_unpack(">Q", b)]
+
def as_word_list(b):
return [i[0] for i in struct.iter_unpack(">I", b)]
+
def as_hword_list(b):
return [h[0] for h in struct.iter_unpack(">H", b)]
+
STR_INDENT = " "
-def try_decode_string(data_bytes, output_ends = True, force_ascii = False):
+
+def try_decode_string(data_bytes, output_ends=True, force_ascii=False):
"""
Swiss Cheese
"""
@@ -225,20 +365,49 @@ def try_decode_string(data_bytes, output_ends = True, force_ascii = False):
char = "\\x1B"
index = data_bytes.index(0x1B)
else:
- assert False , "???"
+ assert False, "???"
part1 = try_decode_string(data_bytes[0:index], output_ends=False)
- part2 = try_decode_string(data_bytes[index+1:], output_ends=False)
+ part2 = try_decode_string(data_bytes[index + 1 :], output_ends=False)
if part2 != "":
- result = part1 + (("\"\n" + STR_INDENT + ".ascii \"") if part2[0] in hex_digits and part1 != "" else "") + \
- char + (("\"\n" + STR_INDENT + ".asciz \"") if part2[0] in hex_digits else "") + part2
+ result = (
+ part1
+ + (
+ ('"\n' + STR_INDENT + '.ascii "')
+ if part2[0] in hex_digits and part1 != ""
+ else ""
+ )
+ + char
+ + (('"\n' + STR_INDENT + '.asciz "') if part2[0] in hex_digits else "")
+ + part2
+ )
if output_ends and part2[0] in hex_digits and part1 == "":
directive = "ascii"
else:
- result = part1 + (("\"\n" + STR_INDENT + ".ascii \"") if part2[0] in hex_digits and part1 != "" else "") + char + "\"\n"
+ result = (
+ part1
+ + (
+ ('"\n' + STR_INDENT + '.ascii "')
+ if part2[0] in hex_digits and part1 != ""
+ else ""
+ )
+ + char
+ + '"\n'
+ )
else:
- result = data_bytes.decode("EUC-JP").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\0", "")
+ result = (
+ data_bytes.decode("EUC-JP")
+ .replace("\n", "\\n")
+ .replace("\r", "\\r")
+ .replace("\t", "\\t")
+ .replace("\0", "")
+ )
+
+ return (
+ (("." + directive + ' "') if output_ends else "")
+ + result
+ + ('"' if output_ends else "")
+ )
- return (("." + directive + " \"") if output_ends else "") + result + ("\"" if output_ends else "")
def reduce_float(flt_str, is_double=False):
def n_digits(str):
@@ -249,8 +418,8 @@ def reduce_float(flt_str, is_double=False):
def str_round(string, precision):
if "." not in string or precision < 0:
return string
- int_part = string.split(".")[0]
- frac_part = string.split(".")[1]
+ int_part = string.split(".")[0]
+ frac_part = string.split(".")[1]
while len(frac_part) > precision:
last_digit = int(frac_part[-1])
@@ -271,7 +440,9 @@ def reduce_float(flt_str, is_double=False):
return int_part + "." + frac_part
def to_binary(flt_str):
- return as_dword(struct.pack(">d", float(flt_str))) if is_double else as_word(struct.pack(">f", float(flt_str)))
+ if is_double:
+ return as_dword(struct.pack(">d", float(flt_str)))
+ return as_word(struct.pack(">f", float(flt_str)))
exponent = ""
if "e" in flt_str:
@@ -300,18 +471,20 @@ def reduce_float(flt_str, is_double=False):
return flt_str + exponent
+
def format_f64(d_dwd):
d = as_double(struct.pack(">Q", d_dwd))
if math.isnan(d):
return f".long 0x{d_dwd:016X}"
return f".double {reduce_float(repr(d), is_double=True)}"
+
def format_f32(f_wd):
# GNU AS isn't ieee compliant?
if f_wd in [0xB8E4AECD, 0xB8E4C3AA, 0x38D1B718]:
return f".word 0x{f_wd:08X}"
- if f_wd == 0x7F7FFFFF: # FLT_MAX
+ if f_wd == 0x7F7FFFFF: # FLT_MAX
return ".float 3.4028235e+38"
f = as_float(struct.pack(">I", f_wd))
@@ -319,19 +492,30 @@ def format_f32(f_wd):
return f".word 0x{f_wd:08X}"
return f".float {reduce_float(repr(f))}"
+
def put_symbol(symbols_dict, setname, symbol):
if setname in symbols_dict:
symbols_dict[setname].add(symbol)
else:
symbols_dict[setname] = {symbol}
+
def put_symbols(symbols_dict, setname, symbols):
if setname in symbols_dict:
symbols_dict[setname].update(symbols)
else:
symbols_dict[setname] = symbols.copy()
+
+def put_text(name, text):
+ files_text[name] = text
+
+
def update_symbols_from_dict(symbols_dict):
+ file_text = []
+ if type(symbols_dict) == tuple:
+ symbols_dict, file_text = symbols_dict
+
for setname, symbol in symbols_dict.items():
if setname == "functions":
functions.update(symbol)
@@ -360,10 +544,18 @@ def update_symbols_from_dict(symbols_dict):
elif setname == "files":
files.update(symbol)
-def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, segment_name):
+ for file in file_text:
+ put_text(file[0], file[1])
+
+
+def find_symbols_in_text(section, rodata_section, data_regions):
+ data, rodata = section[4], rodata_section[4] if rodata_section else None
+ vram, vram_rodata = section[0], rodata_section[0] if rodata_section else None
+ relocs, info = section[5], section[-1]
+
symbols_dict = dict()
- print(f"Finding symbols from .text in {segment_name}")
+ print(f"Finding symbols from .text in {info['name']}")
if rodata is not None:
rodata_words = as_word_list(rodata)
@@ -376,14 +568,15 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
put_symbol(symbols_dict, "files", vram)
# lui trackers are saved at branches to be restored when the branch target is reached
- saved_lui_trackers = {} # vram: tracker list
+ saved_lui_trackers = {} # vram: tracker list
+
def save_tracker(restore_at, tracker):
if restore_at in saved_lui_trackers.keys():
saved_lui_trackers[restore_at].update(tracker)
else:
saved_lui_trackers.update({restore_at: tracker})
- lui_tracker = {} # register : (addr, immediate)
+ lui_tracker = {} # register : (addr, immediate)
prospective_jtbls = set()
@@ -391,7 +584,7 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
func_jtbl_labels = set()
individual_jtbl_labels = {}
- clobber_later = {} # addr : reg
+ clobber_later = {} # addr : reg
delay_slot = False
delayed_insn = None
@@ -409,8 +602,14 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
# print(f"insn: {insn.mnemonic}, rt: {insn.rt}, first: {insn.value_forname(insn.fields[0])}")
# assert insn.id not in [MIPS_INS_ORI, MIPS_INS_ADDIU, *MIPS_LOAD_STORE_INSNS] or insn.rt == insn.value_forname(insn.fields[0])
- if delay_slot and delayed_insn is not None and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS:
- clobber_later.update({delayed_insn.offset : insn.value_forname(insn.fields[0])})
+ if (
+ delay_slot
+ and delayed_insn is not None
+ and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS
+ ):
+ clobber_later.update(
+ {delayed_insn.offset: insn.value_forname(insn.fields[0])}
+ )
else:
lui_tracker.pop(insn.value_forname(insn.fields[0]), None)
@@ -420,45 +619,9 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
if region[1] % 0x10 == 0:
put_symbol(symbols_dict, "files", region[1])
- if relocs is not None:
- """
- Relocation info is our friend. Get symbols via relocations first.
- """
- prev_hi = None
- hi_vram = -1
- for reloc in relocs:
- insn = decode_insn(raw_insns[reloc[2]//4], vram + reloc[2])
-
- if reloc[1] == 2: # R_MIPS_32
- assert False , "R_MIPS_32 in .text section?"
- elif reloc[1] == 4: # R_MIPS_26
- """
- Relocated jump targets give us functions in this section
- """
- assert insn.id == MIPS_INS_JAL , f"R_MIPS_26 applied to {insn.mnemonic} when it should be JAL"
- put_symbol(symbols_dict, "functions", insn.target)
- elif reloc[1] == 5: # R_MIPS_HI16
- """
- Relocated %hi gives us %hi values to match with associated %lo
- """
- assert insn.id == MIPS_INS_LUI , f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be LUI"
- prev_hi = insn.imm
- hi_vram = vram + reloc[2]
- elif reloc[1] == 6: # R_MIPS_LO16
- """
- Relocated %lo + a %hi to match with gives us relocated symbols in data sections
- """
- assert insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS , f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be ADDIU or a load/store"
- symbol_value = (prev_hi << 0x10) + insn.imm
- put_symbols(symbols_dict, "symbols", {hi_vram : symbol_value})
- put_symbols(symbols_dict, "symbols", {vram + reloc[2] : symbol_value})
- else:
- assert False , "Invalid relocation type encountered"
-
- for i,raw_insn in enumerate(raw_insns,0):
- i *= 4
- vaddr = vram + i
- insn = decode_insn(raw_insn, vaddr)
+ insns = []
+ for i, raw_insn in enumerate(raw_insns, 0):
+ insn = decode_insn(raw_insn, vram + i * 4)
if insn.id == MIPS_INS_JR and insn.rs != MIPS_REG_RA:
# It's hard to find when two jump tables next to each other end, so do a naive first pass
@@ -469,17 +632,72 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
# addu $at, $at, $reg
# lw $reg, %lo(jtbl)($at)
# jr $reg
- insn_m1 = decode_insn(raw_insns[i//4 - 1], vaddr - 0x4)
- insn_m2 = decode_insn(raw_insns[i//4 - 2], vaddr - 0x8)
- insn_m3 = decode_insn(raw_insns[i//4 - 3], vaddr - 0xC)
-
- if insn_m1.id == MIPS_INS_LW and insn_m2.id == MIPS_INS_ADDU and insn_m3.id == MIPS_INS_LUI:
+ insn_m1 = insns[-1]
+ insn_m2 = insns[-2]
+ insn_m3 = insns[-3]
+ if (
+ insn_m1.id == MIPS_INS_LW
+ and insn_m2.id == MIPS_INS_ADDU
+ and insn_m3.id == MIPS_INS_LUI
+ ):
prospective_jtbls.add((insn_m3.imm << 0x10) + insn_m1.imm)
+ insns.append(insn)
- for i,raw_insn in enumerate(raw_insns,0):
- i *= 4
- vaddr = vram + i
- insn = decode_insn(raw_insn, vaddr)
+ if relocs is not None:
+ """
+ Relocation info is our friend. Get symbols via relocations first.
+ """
+ prev_hi = None
+ hi_vram = -1
+ for reloc in relocs:
+ insn = insns[reloc[2] // 4]
+
+ if reloc[1] == 2: # R_MIPS_32
+ assert False, "R_MIPS_32 in .text section?"
+ elif reloc[1] == 4: # R_MIPS_26
+ """
+ Relocated jump targets give us functions in this section
+ """
+ assert (
+ insn.id == MIPS_INS_JAL
+ ), f"R_MIPS_26 applied to {insn.mnemonic} when it should be JAL"
+ put_symbol(symbols_dict, "functions", insn.target)
+ elif reloc[1] == 5: # R_MIPS_HI16
+ """
+ Relocated %hi gives us %hi values to match with associated %lo
+ """
+ assert (
+ insn.id == MIPS_INS_LUI
+ ), f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be LUI"
+ prev_hi = insn.imm
+ hi_vram = vram + reloc[2]
+ elif reloc[1] == 6: # R_MIPS_LO16
+ """
+ Relocated %lo + a %hi to match with gives us relocated symbols in data sections
+ """
+ assert (
+ insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS
+ ), f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be ADDIU or a load/store"
+ symbol_value = (prev_hi << 0x10) + insn.imm
+ put_symbols(symbols_dict, "symbols", {hi_vram: symbol_value})
+ put_symbols(symbols_dict, "symbols", {vram + reloc[2]: symbol_value})
+ else:
+ assert False, "Invalid relocation type encountered"
+
+ result_files = []
+ results = [asm_header(".text")]
+ raw_insns = as_word_list(data)
+
+ cur_file = ""
+ cur_vaddr = 0
+
+ segment_dirname = ("" if info["type"] != "overlay" else "overlays/") + info["name"]
+
+ delayed_insn = None
+ delay_slot = False
+
+ for i, insn in enumerate(insns, 0):
+ vaddr = vram + i * 4
# sometimes there's data embedded in .text in handwritten asm files that don't respect section contents
in_data = False
@@ -488,6 +706,16 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
in_data = True
break
if in_data:
+ results.append(
+ {
+ "vaddr": vaddr,
+ "insn": {"id": insn.id},
+ "addr": f"/* {i*4:06X} {vaddr:08X} {raw_insns[i]:08X} */ ",
+ "mnem": "",
+ "op": [f" .word 0x{raw_insns[i]:08X}"],
+ "data": True,
+ }
+ )
continue
if vaddr in functions or vaddr in symbols_dict["functions"]:
@@ -525,64 +753,99 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
func_branch_labels.add(insn.target)
elif insn.id == MIPS_INS_JR:
# check if anything branches past it in either branch or jtbl labels
- if vaddr >= max(func_branch_labels, default=0) and vaddr >= max(func_jtbl_labels, default=0): # vaddr being largest in list means nothing branches past here
+ if vaddr >= max(func_branch_labels, default=0) and vaddr >= max(
+ func_jtbl_labels, default=0
+ ): # vaddr being largest in list means nothing branches past here
# mark next function after delay slot and after any nop padding if present
- if len(raw_insns) > i//4 + 2:
+ if len(insns) > i + 2:
n_padding = 0
end = False
- while (raw_insns[i//4 + 2 + n_padding] == 0):
+ while raw_insns[i + 2 + n_padding] == 0:
n_padding += 1
- if len(raw_insns) <= i//4 + 2 + n_padding:
+ if len(raw_insns) <= i + 2 + n_padding:
end = True
break
if not end:
if n_padding > 0:
- assert (vaddr + 8 + n_padding * 4) % 0x10 == 0 , f"padding to non-0x10 alignment?, 0x{vaddr + 8 + n_padding * 4:08X}"
- put_symbol(symbols_dict, "functions", vaddr + 8 + n_padding * 4)
- put_symbol(symbols_dict, "functions", vaddr + 8 + n_padding * 4)
+ assert (
+ vaddr + 8 + n_padding * 4
+ ) % 0x10 == 0, f"padding to non-0x10 alignment?, 0x{vaddr + 8 + n_padding * 4:08X}"
+ put_symbol(
+ symbols_dict, "functions", vaddr + 8 + n_padding * 4
+ )
+ put_symbol(
+ symbols_dict, "functions", vaddr + 8 + n_padding * 4
+ )
delayed_insn = insn
elif insn.id == MIPS_INS_LUI:
"""
Process LUI instruction
-
+
All symbol loading involves LUI, and tracking how %hi values loaded via LUI instructions propagate
through a function is key to identifying symbol references
"""
# add lui to tracker
- if delay_slot and delayed_insn is not None and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS:
+ if (
+ delay_slot
+ and delayed_insn is not None
+ and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS
+ ):
# for branch likelies, the current tracker does not update but the lui is saved to be tracked at the branch target
- save_tracker(delayed_insn.offset, {insn.rt : (vaddr, insn.imm)})
+ save_tracker(delayed_insn.offset, {insn.rt: (vaddr, insn.imm)})
else:
- lui_tracker.update({insn.rt : (vaddr, insn.imm)})
+ lui_tracker.update({insn.rt: (vaddr, insn.imm)})
elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS:
# try match with tracked lui and mark symbol
- hi_vram, imm_value = lui_tracker.get(insn.rs if insn.id == MIPS_INS_ADDIU else insn.base, (None, None))
+ hi_vram, imm_value = lui_tracker.get(
+ insn.rs if insn.id == MIPS_INS_ADDIU else insn.base, (None, None)
+ )
# if a match was found, validate and record the symbol, TODO improve validation
- if hi_vram != None and ((((imm_value >> 0x8) & 0xF) != 0 and imm_value < 0x1000) or \
- (imm_value >= 0x8000 and imm_value < 0x80D0) or \
- (imm_value >= 0xA400 and imm_value < 0xA480) or (imm_value < 0x0400 and insn.id == MIPS_INS_ADDIU)):
+ if hi_vram != None and (
+ (((imm_value >> 0x8) & 0xF) != 0 and imm_value < 0x1000)
+ or (imm_value >= 0x8000 and imm_value < 0x80D0)
+ or (imm_value >= 0xA400 and imm_value < 0xA480)
+ or (imm_value < 0x0400 and insn.id == MIPS_INS_ADDIU)
+ ):
lo_vram = vaddr
symbol_value = (imm_value << 0x10) + insn.imm
- put_symbols(symbols_dict, "symbols", {hi_vram : symbol_value})
- put_symbols(symbols_dict, "symbols", {lo_vram : symbol_value})
+ put_symbols(symbols_dict, "symbols", {hi_vram: symbol_value})
+ put_symbols(symbols_dict, "symbols", {lo_vram: symbol_value})
if insn.id == MIPS_INS_LW:
# try find jr within the same block
- cur_idx = i//4
- lookahead_insn = decode_insn(raw_insns[cur_idx], vram + cur_idx * 4) # TODO fix vaddr here
+ cur_idx = i
+ lookahead_insn = insns[cur_idx] # TODO fix vaddr here
# still in same block unless one of these instructions are found
- while lookahead_insn.id not in [*MIPS_BRANCH_INSNS, MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J]:
+ while lookahead_insn.id not in [
+ *MIPS_BRANCH_INSNS,
+ MIPS_INS_JAL,
+ MIPS_INS_JALR,
+ MIPS_INS_J,
+ ]:
if lookahead_insn.id == MIPS_INS_JR:
- if lookahead_insn.rs == (insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt):
+ if lookahead_insn.rs == (
+ insn.ft
+ if insn.id in MIPS_FP_LOAD_STORE_INSNS
+ else insn.rt
+ ):
# read the jtbl and add targets to func_jtbl_labels
- assert rodata is not None , "A rodata section should be present if functions use jump tables"
+ assert (
+ rodata is not None
+ ), "A rodata section should be present if functions use jump tables"
next_jtbl_jr = vaddr + cur_idx * 4
- individual_jtbl_labels.update({next_jtbl_jr : set()})
+ individual_jtbl_labels.update({next_jtbl_jr: set()})
- offset = (symbol_value - vram_rodata)//4
+ offset = (symbol_value - vram_rodata) // 4
label = rodata_words[offset]
- while label >= vram and label < vram + len(data) and \
- (vram_rodata + offset * 4 not in prospective_jtbls or vram_rodata + offset * 4 == symbol_value):
+ while (
+ label >= vram
+ and label < vram + len(data)
+ and (
+ vram_rodata + offset * 4
+ not in prospective_jtbls
+ or vram_rodata + offset * 4 == symbol_value
+ )
+ ):
func_jtbl_labels.add(label)
individual_jtbl_labels[next_jtbl_jr].add(label)
offset += 1
@@ -593,44 +856,55 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
put_symbol(symbols_dict, "jtbls", symbol_value)
# found a jr that matches, no need to keep searching
break
- elif (insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt) in [lookahead_insn.value_forname(field) for field in lookahead_insn.fields[1:]]:
+ elif (
+ insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt
+ ) in [
+ lookahead_insn.value_forname(field)
+ for field in lookahead_insn.fields[1:]
+ ]:
# register clobbered, no need to keep searching
break
cur_idx += 1
# found end before finding jr insn, not a jtbl
if cur_idx >= len(raw_insns):
break
- lookahead_insn = decode_insn(raw_insns[cur_idx], vram + cur_idx * 4) # TODO fix vaddr here
- elif insn.id == MIPS_INS_LD: # doubleword loads
+ lookahead_insn = insns[cur_idx] # TODO fix vaddr here
+ elif insn.id == MIPS_INS_LD: # doubleword loads
put_symbol(symbols_dict, "dwords", symbol_value)
- elif insn.id in [MIPS_INS_LWC1, MIPS_INS_SWC1]: # float load/stores
+ elif insn.id in [MIPS_INS_LWC1, MIPS_INS_SWC1]: # float load/stores
# add float
put_symbol(symbols_dict, "floats", symbol_value)
- elif insn.id in [MIPS_INS_LDC1, MIPS_INS_SDC1]: # double load/stores
+ elif insn.id in [MIPS_INS_LDC1, MIPS_INS_SDC1]: # double load/stores
# add double
put_symbol(symbols_dict, "doubles", symbol_value)
- elif insn.id == MIPS_INS_ADDIU and vaddr % 4 == 0: # strings seem to only ever be 4-byte aligned
+ elif (
+ insn.id == MIPS_INS_ADDIU and vaddr % 4 == 0
+ ): # strings seem to only ever be 4-byte aligned
# add possible string
put_symbol(symbols_dict, "prospective_strings", symbol_value)
# clear lui tracking state if register is clobbered by the addiu/load instruction itself
- # insn.rt == (insn.rs if insn.id == MIPS_INS_ADDIU else insn.base) and
+ # insn.rt == (insn.rs if insn.id == MIPS_INS_ADDIU else insn.base) and
if insn.id not in MIPS_STORE_INSNS and insn.id not in MIPS_FP_LOAD_INSNS:
clobber_conditionally(insn)
elif insn.id == MIPS_INS_ORI:
# try match with tracked lui and mark constant
hi_vram, imm_value = lui_tracker.get(insn.rs, (None, None))
- if hi_vram != None: # found match
+ if hi_vram != None: # found match
lo_vram = vaddr
const_value = (imm_value << 0x10) | insn.imm
- put_symbols(symbols_dict, "constants", {hi_vram : const_value})
- put_symbols(symbols_dict, "constants", {lo_vram : const_value})
+ put_symbols(symbols_dict, "constants", {hi_vram: const_value})
+ put_symbols(symbols_dict, "constants", {lo_vram: const_value})
# clear lui tracking state if register is clobbered by the ori instruction itself
- # insn.rt == insn.rs or
+ # insn.rt == insn.rs or
if insn.rt in lui_tracker.keys():
clobber_conditionally(insn)
else:
# clear lui tracking if register is clobbered by something unrelated
- if insn.id == MIPS_INS_ADDU and insn.rs in lui_tracker.keys() and (insn.rd == insn.rs):
+ if (
+ insn.id == MIPS_INS_ADDU
+ and insn.rs in lui_tracker.keys()
+ and (insn.rd == insn.rs)
+ ):
# array accesses optimisation:
# lui reg, %hi(symbol)
# addu reg, reg, idx
@@ -639,22 +913,113 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
# if the output is not currently tracked it will behave as intended anyway
pass
# insns listed either write to fprs/cop0 or don't write to any
- elif insn.id not in [MIPS_INS_MTC0, MIPS_INS_MTC1, MIPS_INS_DMTC1,
- MIPS_INS_MULT, MIPS_INS_MULTU, MIPS_INS_DMULT, MIPS_INS_DMULTU,
- MIPS_INS_DIV, MIPS_INS_DIVU, MIPS_INS_DDIV, MIPS_INS_DDIVU,
- MIPS_INS_MTHI, MIPS_INS_MTLO,
- MIPS_INS_CTC1,
- MIPS_INS_NOP,
- MIPS_INS_BREAK,
- MIPS_INS_TLBP, MIPS_INS_TLBR, MIPS_INS_TLBWI,
- MIPS_INS_MOV_S, MIPS_INS_MOV_D, MIPS_INS_C_LT_S, MIPS_INS_C_LT_D,
- MIPS_INS_DIV_S, MIPS_INS_MUL_S, MIPS_INS_TRUNC_W_S, MIPS_INS_CVT_S_W,
- MIPS_INS_SUB_S, MIPS_INS_ADD_S]:
+ elif insn.id not in [
+ MIPS_INS_MTC0,
+ MIPS_INS_MTC1,
+ MIPS_INS_DMTC1,
+ MIPS_INS_MULT,
+ MIPS_INS_MULTU,
+ MIPS_INS_DMULT,
+ MIPS_INS_DMULTU,
+ MIPS_INS_DIV,
+ MIPS_INS_DIVU,
+ MIPS_INS_DDIV,
+ MIPS_INS_DDIVU,
+ MIPS_INS_MTHI,
+ MIPS_INS_MTLO,
+ MIPS_INS_CTC1,
+ MIPS_INS_NOP,
+ MIPS_INS_BREAK,
+ MIPS_INS_TLBP,
+ MIPS_INS_TLBR,
+ MIPS_INS_TLBWI,
+ MIPS_INS_MOV_S,
+ MIPS_INS_MOV_D,
+ MIPS_INS_C_LT_S,
+ MIPS_INS_C_LT_D,
+ MIPS_INS_DIV_S,
+ MIPS_INS_MUL_S,
+ MIPS_INS_TRUNC_W_S,
+ MIPS_INS_CVT_S_W,
+ MIPS_INS_SUB_S,
+ MIPS_INS_ADD_S,
+ ]:
clobber_conditionally(insn)
+ ############# Start text disassembly ##########
+ # Symbols aren't avaialble here yet, so placeholders are added
+ # in each instruction, to be looked up later
+ mnemonic = f" {insn.mnemonic}" if delay_slot else insn.mnemonic
+ op_str = insn.op_str
+ instr = {"id": insn.id}
+
+ if vaddr in full_file_list[info["name"]]:
+ if cur_file != "":
+ if cur_vaddr in info["syms"]:
+ result_files.append([cur_file, results])
+ results = [asm_header(".text")]
+ cur_vaddr = vaddr
+ cur_file = full_file_list[info["name"]][vaddr]
+ if cur_file == "":
+ cur_file = f"{info['name']}_{vaddr:08X}"
+
+ if insn.id in MIPS_BRANCH_INSNS:
+ op_str_parts = []
+ for field in insn.fields:
+ if field == "offset":
+ op_str_parts.append(f".L{insn.offset:08X}")
+ else:
+ op_str_parts.append(insn.format_field(field))
+ op_str = [", ".join(op_str_parts)]
+
+ elif insn.id in MIPS_JUMP_INSNS:
+ op_str = []
+ op_str_parts = []
+ for field in insn.fields:
+ if field == "target":
+ op_str_parts.append([insn.target, False, True])
+ else:
+ op_str_parts.append(insn.format_field(field))
+ for x, part in enumerate(op_str_parts):
+ if x + 1 < len(op_str_parts):
+ part += ", "
+ op_str.append(part)
+
+ elif insn.id == MIPS_INS_LUI:
+ op_str = [op_str]
+ instr["rt"] = insn.rt
+
+ elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS:
+ op_str = [op_str]
+ instr["rt"] = insn.rt
+ instr["rs"] = insn.rs
+ instr["ft"] = insn.ft
+ instr["base"] = insn.base
+
+ elif insn.id == MIPS_INS_ORI:
+ op_str = [op_str]
+ instr["rt"] = insn.rt
+ instr["rs"] = insn.rs
+
+ results.append(
+ {
+ "vaddr": vaddr,
+ "insn": instr,
+ "addr": f"/* {i*4:06X} {vaddr:08X} {raw_insns[i]:08X} */ ",
+ "mnem": mnemonic,
+ "op": op_str,
+ "data": False,
+ }
+ )
+
+ ######### End text disassembly ##############
+
if delay_slot and delayed_insn is not None:
- if delayed_insn.id == MIPS_INS_JAL or delayed_insn.id == MIPS_INS_JALR or \
- (delayed_insn.id == MIPS_INS_JR and delayed_insn.rs == MIPS_REG_RA):
+ if (
+ delayed_insn.id == MIPS_INS_JAL
+ or delayed_insn.id == MIPS_INS_JALR
+ or (delayed_insn.id == MIPS_INS_JR and delayed_insn.rs == MIPS_REG_RA)
+ ):
# destroy lui tracking state
lui_tracker.clear()
elif delayed_insn.id == MIPS_INS_JR and vaddr == next_jtbl_jr + 4:
@@ -673,82 +1038,124 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs,
delay_slot = delayed_insn is not None
+ result_files.append([cur_file, results])
+
put_symbols(symbols_dict, "branch_labels", func_branch_labels)
put_symbols(symbols_dict, "jtbl_labels", func_jtbl_labels)
- return symbols_dict
+ return symbols_dict, result_files
-def find_symbols_in_data(data, vram, end, relocs, segment_name):
+
+def find_symbols_in_data(section):
+ data, vram, end, relocs = section[4], section[0], section[1], section[5]
symbols_dict = dict()
- print(f"Finding symbols from .data in {segment_name}")
+ print(f"Finding symbols from .data in {section[-1]['name']}")
# read relocations for symbols
if relocs is not None:
for reloc in relocs:
- if reloc[1] == 2: # R_MIPS_32
- put_symbol(symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4]))
- elif reloc[1] == 4: # R_MIPS_26
- assert False , "R_MIPS_26 in .data section?"
- elif reloc[1] == 5: # R_MIPS_HI16
- assert False , "R_MIPS_HI16 in .data section?"
- elif reloc[1] == 6: # R_MIPS_LO16
- assert False , "R_MIPS_LO16 in .data section?"
+ if reloc[1] == 2: # R_MIPS_32
+ put_symbol(
+ symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4])
+ )
+ elif reloc[1] == 4: # R_MIPS_26
+ assert False, "R_MIPS_26 in .data section?"
+ elif reloc[1] == 5: # R_MIPS_HI16
+ assert False, "R_MIPS_HI16 in .data section?"
+ elif reloc[1] == 6: # R_MIPS_LO16
+ assert False, "R_MIPS_LO16 in .data section?"
else:
- assert False , "Invalid relocation type encountered"
+ assert False, "Invalid relocation type encountered"
return symbols_dict
# TODO more
-# matches several codepoint regions of EUC-JP
-strings_regex = re.compile(rb'^(?:[\x00\x1A\x1B\n\t\x20-\x7E\x8C\x8D]|\x30[\x00-\xFF]|[\x4E-\x9F][\x00-\xFF]|[\xA4\xA5\xBB][\xA1-\xF6]|[\xA1-\xA3\xB0-\xBF\xC0-\xCF][\xA1-\xFE]|\xFF[\x00-\xEF])+$')
-def find_symbols_in_rodata(data, vram, end, relocs, segment):
+# matches several codepoint regions of EUC-JP
+strings_regex = re.compile(
+ rb"^(?:[\x00\x1A\x1B\n\t\x20-\x7E\x8C\x8D]|\x30[\x00-\xFF]|[\x4E-\x9F][\x00-\xFF]|[\xA4\xA5\xBB][\xA1-\xF6]|[\xA1-\xA3\xB0-\xBF\xC0-\xCF][\xA1-\xFE]|\xFF[\x00-\xEF])+$"
+)
+
+
+def find_symbols_in_rodata(section):
+ data, vram, end, relocs = section[4], section[0], section[1], section[5]
+ symbols_dict = dict()
+
+ print(f"Finding symbols from .rodata in {section[-1]['name']}")
+
# read relocations for symbols
if relocs is not None:
for reloc in relocs:
- if reloc[1] == 2: # R_MIPS_32
- data_labels.add(as_word(data[reloc[2] : reloc[2] + 4]))
- elif reloc[1] == 4: # R_MIPS_26
- assert False , "R_MIPS_26 in .rodata section?"
- elif reloc[1] == 5: # R_MIPS_HI16
- assert False , "R_MIPS_HI16 in .rodata section?"
- elif reloc[1] == 6: # R_MIPS_LO16
- assert False , "R_MIPS_LO16 in .rodata section?"
+ if reloc[1] == 2: # R_MIPS_32
+ put_symbol(
+ symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4])
+ )
+ elif reloc[1] == 4: # R_MIPS_26
+ assert False, "R_MIPS_26 in .rodata section?"
+ elif reloc[1] == 5: # R_MIPS_HI16
+ assert False, "R_MIPS_HI16 in .rodata section?"
+ elif reloc[1] == 6: # R_MIPS_LO16
+ assert False, "R_MIPS_LO16 in .rodata section?"
else:
- assert False , "Invalid relocation type encountered"
+ assert False, "Invalid relocation type encountered"
- section_symbols = set([sym for sym in symbols.values() if sym >= vram and sym < end])
+ section_symbols = set(
+ [sym for sym in symbols.values() if sym >= vram and sym < end]
+ )
section_symbols.add(vram)
- section_symbols.update(set([sym for sym in data_labels if sym >= vram and sym < end]))
+ section_symbols.update(
+ set([sym for sym in data_labels if sym >= vram and sym < end])
+ )
# TODO temp hack, move
- for data_file_st in [sym for sym in segment[4].keys() if sym >= vram and sym < end]:
+ for data_file_st in [
+ sym for sym in section[-1]["syms"].keys() if sym >= vram and sym < end
+ ]:
section_symbols.add(data_file_st)
- rodata_starts = [addr for addr,name in segment[4].items() if addr >= vram and addr < end]
+ rodata_starts = [
+ addr
+ for addr, name in section[-1]["syms"].items()
+ if addr >= vram and addr < end
+ ]
section_symbols.update(set(rodata_starts))
section_symbols = list(section_symbols)
section_symbols.sort()
- section_late_rodata = [sym for sym in section_symbols if sym in floats or sym in doubles or sym in jtbls]
+ section_late_rodata = [
+ sym
+ for sym in section_symbols
+ if sym in floats or sym in doubles or sym in jtbls
+ ]
# string finding is best done per-file as the late_rodata sections are not merged per-segment, so you get stripes of
# rodata - late_rodata -(file boundary)- rodata - late_rodata -(file boundary)- etc.
# all rodata file starts
- for fi,rodata_start in enumerate(rodata_starts,0):
- next_rodata_start = rodata_starts[fi + 1] if fi < len(rodata_starts) - 1 else end
+ for fi, rodata_start in enumerate(rodata_starts, 0):
+ next_rodata_start = (
+ rodata_starts[fi + 1] if fi < len(rodata_starts) - 1 else end
+ )
# symbols in this file
- file_symbols = [sym for sym in section_symbols if sym >= rodata_start and sym < next_rodata_start]
+ file_symbols = [
+ sym
+ for sym in section_symbols
+ if sym >= rodata_start and sym < next_rodata_start
+ ]
# the first (minimum st_value) symbol in section_late_rodata in this file is the start of late_rodata
- late_rodata_start = min([sym for sym in file_symbols if sym in section_late_rodata], default=next_rodata_start)
+ late_rodata_start = min(
+ [sym for sym in file_symbols if sym in section_late_rodata],
+ default=next_rodata_start,
+ )
- for i,symbol in enumerate(file_symbols,0):
- next_symbol = file_symbols[i + 1] if i < len(file_symbols) - 1 else next_rodata_start
+ for i, symbol in enumerate(file_symbols, 0):
+ next_symbol = (
+ file_symbols[i + 1] if i < len(file_symbols) - 1 else next_rodata_start
+ )
# not late_rodata
if symbol >= late_rodata_start:
@@ -759,7 +1166,7 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment):
data_offset = symbol - vram
data_size = next_symbol - symbol
- string_data = data[data_offset:data_offset+data_size]
+ string_data = data[data_offset : data_offset + data_size]
if len(string_data) > 0 and string_data[0] == 0:
# empty strings that are auto-detected are dubious
@@ -769,8 +1176,10 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment):
if strings_regex.match(string_data) != None:
k = 0
done = False
- for j,b in enumerate(string_data,0):
- if b == 0 and (j + 1 >= len(string_data) or string_data[j + 1] != 0):
+ for j, b in enumerate(string_data, 0):
+ if b == 0 and (
+ j + 1 >= len(string_data) or string_data[j + 1] != 0
+ ):
# try:
# decoded = try_decode_string(string_data[k:string_data.index(0)])
# except UnicodeDecodeError:
@@ -778,14 +1187,16 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment):
# done = True
# if done:
# break
- data_labels.add(symbol + k)
- strings.add(symbol + k)
- data_labels.add(symbol + j + 1)
+ put_symbol(symbols_dict, "data_labels", symbol + k)
+ put_symbol(symbols_dict, "data_labels", symbol + j + 1)
+ put_symbol(symbols_dict, "strings", symbol + k)
k = j + 1
# TODO more
+ return symbols_dict
-def asm_header(section_name):
+
+def asm_header(section_name):
return f""".include "macro.inc"
# assembler directives
@@ -798,36 +1209,128 @@ def asm_header(section_name):
.balign 16
"""
-def disassemble_text(data, vram, data_regions, segment):
+
+def fixup_text_symbols(data, vram, data_regions, info):
+ segment_dirname = "" if info["type"] != "overlay" else "overlays/"
+ if info["type"] in ("boot", "code"):
+ segment_dirname += info["type"]
+ else:
+ segment_dirname += info["name"]
+
+ os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True)
+
+ file = files_text[info["name"]]
+ # header
+ text = [file.pop(0)]
+
+ # We didn't have full symbols available during initial disassembly,
+ # so here we loop over each instruction, and do symbol lookups, add labels etc
+
+ for i, entry in enumerate(file):
+ vaddr = entry["vaddr"]
+
+ if vaddr in functions:
+ text.append(f"\nglabel {proper_name(vaddr, in_data=entry['data'])}\n")
+ if vaddr in jtbl_labels:
+ text.append(f"glabel L{vaddr:08X}\n")
+ if vaddr in branch_labels:
+ text.append(f".L{vaddr:08X}:\n")
+
+ line = entry["addr"]
+ if not entry["data"]:
+ line += f"{entry['mnem']:12}"
+
+ insn = entry["insn"]
+ if insn["id"] in MIPS_JUMP_INSNS:
+ for op_part in entry["op"]:
+ if type(op_part) == list:
+ line += proper_name(
+ op_part[0], in_data=op_part[1], is_symbol=op_part[2]
+ )
+ else:
+ line += op_part
+
+ elif insn["id"] == MIPS_INS_LUI:
+ symbol_value = symbols.get(vaddr, None)
+ if symbol_value is not None:
+ line += (
+ f"{mips_gpr_names[insn['rt']]}, %hi({proper_name(symbol_value)})"
+ )
+ else:
+ constant_value = constants.get(vaddr, None)
+ if constant_value is not None:
+ line += (
+ f"{mips_gpr_names[insn['rt']]}, (0x{constant_value:08X} >> 16)"
+ )
+ else:
+ line += entry["op"][0]
+
+ elif insn["id"] == MIPS_INS_ADDIU or insn["id"] in MIPS_LOAD_STORE_INSNS:
+ symbol_value = symbols.get(vaddr, None)
+ if symbol_value is not None:
+ if insn["id"] == MIPS_INS_ADDIU:
+ line += f"{mips_gpr_names[insn['rt']]}, {mips_gpr_names[insn['rs']]}, %lo({proper_name(symbol_value)})"
+ else:
+ line += f"{mips_fpr_names[insn['ft']] if insn['id'] in MIPS_FP_LOAD_STORE_INSNS else mips_gpr_names[insn['rt']]}, %lo({proper_name(symbol_value)})({mips_gpr_names[insn['base']]})"
+ else:
+ line += entry["op"][0]
+
+ elif insn["id"] == MIPS_INS_ORI:
+ constant_value = constants.get(vaddr, None)
+ if constant_value is not None:
+ line += f"{mips_gpr_names[insn['rt']]}, {mips_gpr_names[insn['rs']]}, (0x{constant_value:08X} & 0xFFFF)"
+ else:
+ line += entry["op"][0]
+
+ else:
+ for part in entry["op"]:
+ if type(part) == list:
+ line += (
+ f"{proper_name(part[0], in_data=part[1], is_symbol=part[2])}"
+ )
+ else:
+ line += part
+
+ line += "\n"
+ text.append(line)
+
+ with open(f"{ASM_OUT}/{segment_dirname}/{info['name']}.text.s", "w") as outfile:
+ outfile.write("".join(text))
+
+
+def disassemble_text(data, vram, data_regions, info):
result = asm_header(".text")
raw_insns = as_word_list(data)
cur_file = ""
+ cur_vaddr = 0
- segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0]
+ segment_dirname = ("" if info["type"] != "overlay" else "overlays/") + info["name"]
+ os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True)
delayed_insn = None
delay_slot = False
- for i,raw_insn in enumerate(raw_insns,0):
+ for i, raw_insn in enumerate(raw_insns, 0):
i *= 4
vaddr = vram + i
- insn = decode_insn(raw_insns[i//4], vaddr)
+ insn = decode_insn(raw_insns[i // 4], vaddr)
mnemonic = insn.mnemonic
op_str = insn.op_str
- if vaddr in segment[4].keys():
+ if vaddr in full_file_list[info["name"]]:
if cur_file != "":
- os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w") as outfile:
- outfile.write(result)
+ if cur_vaddr in info["syms"]:
+ os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True)
+ with open(
+ f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w"
+ ) as outfile:
+ outfile.write(result)
result = asm_header(".text")
- cur_file = segment[4][vaddr]
+ cur_vaddr = vaddr
+ cur_file = full_file_list[info["name"]][vaddr]
if cur_file == "":
- cur_file = f"{segment[0]}_{vaddr:08X}"
-
- if cur_file == "[PADDING]": # workaround for assumed linker bug
- continue
+ cur_file = f"{info['name']}_{vaddr:08X}"
# DATA EMBEDDED IN TEXT
in_data = False
@@ -836,9 +1339,12 @@ def disassemble_text(data, vram, data_regions, segment):
in_data = True
break
if in_data:
- if vaddr in functions: # TODO not really a function if it falls in a data region...
+ # TODO not really a function if it falls in a data region...
+ if vaddr in functions:
result += f"\nglabel {proper_name(vaddr, True)}\n"
- result += f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ .word 0x{raw_insn:08X}\n"
+ result += (
+ f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ .word 0x{raw_insn:08X}\n"
+ )
continue
# LABELS
@@ -853,7 +1359,7 @@ def disassemble_text(data, vram, data_regions, segment):
if insn.id in MIPS_BRANCH_INSNS:
op_str_parts = []
for field in insn.fields:
- if field == 'offset':
+ if field == "offset":
op_str_parts.append(f".L{insn.offset:08X}")
else:
op_str_parts.append(insn.format_field(field))
@@ -862,7 +1368,7 @@ def disassemble_text(data, vram, data_regions, segment):
elif insn.id in MIPS_JUMP_INSNS:
op_str_parts = []
for field in insn.fields:
- if field == 'target':
+ if field == "target":
op_str_parts.append(proper_name(insn.target, is_symbol=True))
else:
op_str_parts.append(insn.format_field(field))
@@ -875,7 +1381,9 @@ def disassemble_text(data, vram, data_regions, segment):
else:
constant_value = constants.get(vaddr, None)
if constant_value is not None:
- op_str = f"{mips_gpr_names[insn.rt]}, (0x{constant_value:08X} >> 16)"
+ op_str = (
+ f"{mips_gpr_names[insn.rt]}, (0x{constant_value:08X} >> 16)"
+ )
elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS:
symbol_value = symbols.get(vaddr, None)
if symbol_value is not None:
@@ -897,194 +1405,458 @@ def disassemble_text(data, vram, data_regions, segment):
result += f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ {mnemonic:12}{op_str}\n"
- os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True)
with open(f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w") as outfile:
outfile.write(result)
-def disassemble_data(data, vram, end, segment):
+
+def disassemble_data(data, vram, end, info):
section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end]
section_symbols.append(vram)
section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end])
- section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end])
+ section_symbols.extend(
+ [sym for sym in variables_ast.keys() if sym >= vram and sym < end]
+ )
# TODO temp hack, move
- section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end])
+ section_symbols.extend(
+ [sym for sym in info["syms"].keys() if sym >= vram and sym < end]
+ )
# remove symbols that are addends of other symbols
- section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)]
+ section_symbols = [
+ sym
+ for sym in section_symbols
+ if " + 0x" not in proper_name(sym, True)
+ and " - 0x" not in proper_name(sym, True)
+ ]
section_symbols = list(set(section_symbols))
section_symbols.sort()
- segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0]
-
- result = asm_header(".data")
- cur_file = ""
-
- for i,symbol in enumerate(section_symbols,0):
- next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end
-
- # assert symbol % 4 == 0 , f"Unaligned .data symbol 0x{symbol:08X}"
-
- if symbol in segment[4].keys():
- if cur_file != "":
- os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.data.s", "w") as outfile:
- outfile.write(result)
- result = asm_header(".data")
- cur_file = segment[4][symbol]
- if cur_file == "":
- cur_file = f"{segment[0]}_{symbol:08X}"
-
- data_offset = symbol - vram
- data_size = next_symbol - symbol
-
- if data_offset == len(data):
- continue
-
- result += f"\nglabel {proper_name(symbol, True)}\n"
-
- if symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles:
- result += "\n".join(\
- [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" for j,dbl_dwd in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in dwords:
- result += "\n".join(\
- [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} */ .quad 0x{dword:08X}" for j,dword in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- elif symbol % 4 == 0 and data_size % 4 == 0:
- if symbol in floats:
- result += "\n".join(\
- [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" for j,flt_wd in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- else:
- result += "\n".join(\
- [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" for j,word in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- elif symbol % 2 == 0 and data_size % 2 == 0:
- result += "\n".join(\
- [f"/* {data_offset + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" for j,hword in enumerate(as_hword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- else:
- result += "\n".join(\
- [f"/* {data_offset + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" for j,byte in enumerate(data[data_offset:data_offset + data_size], 0)]) + "\n"
-
- os.makedirs(f"{DATA_OUT}/{segment[0]}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment[0]}/{cur_file}.data.s", "w") as outfile:
- outfile.write(result)
-
-def disassemble_rodata(data, vram, end, segment):
- section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end]
- section_symbols.append(vram)
- section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end])
- section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end])
- # TODO temp hack, move
- section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end])
-
- # remove symbols that are addends of other symbols
- section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)]
-
- section_symbols = list(set(section_symbols))
-
- section_symbols.sort()
-
- segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0]
-
- result = asm_header(".rodata")
- cur_file = ""
-
- force_ascii_str = False # hack for non-null-terminated strings in .data
-
- for i,symbol in enumerate(section_symbols,0):
- next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end
-
- # assert symbol % 4 == 0 , f"Unaligned .data symbol 0x{symbol:08X}"
-
- if symbol in segment[4].keys():
- if cur_file != "":
- os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.rodata.s", "w") as outfile:
- outfile.write(result)
- result = asm_header(".rodata")
- cur_file = segment[4][symbol]
- if cur_file == "":
- cur_file = f"{segment[0]}_{symbol:08X}"
-
- data_offset = symbol - vram
- data_size = next_symbol - symbol
-
- if data_offset == len(data):
- continue
-
- force_ascii_str = symbol in [0x801D0708]
-
- result += f"\nglabel {proper_name(symbol, True)}\n"
-
- if symbol in strings:
- string_data = data[data_offset:data_offset+data_size]
- string_data = string_data[:string_data.index(0)]
- assert all([b != 0 for b in string_data[:-1]]) , f"{symbol:08X} , {data_size:X} , {string_data}" # ensure strings don't have a null char midway through
- result += f"/* {data_offset:06X} {symbol:08X} */ {try_decode_string(string_data, force_ascii=force_ascii_str)}\n{STR_INDENT}.balign 4\n"
- elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles:
- result += "\n".join(\
- [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" for j,dbl_dwd in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- elif symbol % 4 == 0 and data_size % 4 == 0:
- if symbol in floats:
- result += "\n".join(\
- [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" for j,flt_wd in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- else:
- result += "\n".join(\
- [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" for j,word in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- elif symbol % 2 == 0 and data_size % 2 == 0:
- result += "\n".join(\
- [f"/* {data_offset + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" for j,hword in enumerate(as_hword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n"
- else:
- result += "\n".join(\
- [f"/* {data_offset + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" for j,byte in enumerate(data[data_offset:data_offset + data_size], 0)]) + "\n"
-
- os.makedirs(f"{DATA_OUT}/{segment[0]}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment[0]}/{cur_file}.rodata.s", "w") as outfile:
- outfile.write(result)
-
-def disassemble_bss(vram, end, segment):
- section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end]
- section_symbols.append(vram)
- section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end])
- section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end])
- # TODO temp hack, move
- section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end])
-
- # remove symbols that are addends of other symbols
- section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)]
-
- section_symbols = list(set(section_symbols))
-
- section_symbols.sort()
-
- # ("" if segment[2] != "overlay" else "overlays/"
- segment_dirname = segment[0]
-
- result = asm_header(".bss")
- cur_file = ""
-
- for i,symbol in enumerate(section_symbols,0):
- next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end
-
- if symbol in segment[4].keys():
- if cur_file != "":
- os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.bss.s", "w") as outfile:
- outfile.write(result)
- result = asm_header(".bss")
- cur_file = segment[4][symbol]
- if cur_file == "":
- cur_file = f"{segment[0]}_{symbol:08X}"
-
- result += f"\nglabel {proper_name(symbol, True)}\n"
- result += f"/* {symbol - vram:06X} {symbol:08X} */ .space 0x{next_symbol - symbol:X}\n"
+ segment_dirname = info["name"]
+ if info["type"] in ("boot", "code"):
+ segment_dirname = info["type"]
os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.bss.s", "w") as outfile:
- outfile.write(result)
+
+ if info["type"] in ("boot", "code"):
+ sym_list = full_file_list[info["type"]]
+ else:
+ sym_list = full_file_list[info["name"]]
+
+ file_syms = []
+ syms = []
+ file_name = ""
+ for i, sym in enumerate(section_symbols):
+ if i == 0:
+ if info["type"] == "overlay":
+ file_name = info["name"]
+ else:
+ file_name = sym_list[sym]
+
+ if sym in sym_list:
+ new_file = sym_list[sym]
+ if file_name != new_file:
+ file_syms.append(
+ {"name": file_name, "first_sym": syms[0], "syms": syms}
+ )
+ syms = []
+ file_name = new_file
+ syms.append(sym)
+ if len(syms) > 0:
+ file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms})
+
+ for i, file in enumerate(file_syms):
+ if file["first_sym"] not in info["syms"]:
+ continue
+
+ result = [asm_header(".data")]
+
+ for x, symbol in enumerate(file["syms"]):
+ if symbol >= end:
+ break
+ if x + 1 < len(file["syms"]):
+ next_symbol = file["syms"][x + 1]
+ elif i + 1 < len(file_syms):
+ next_symbol = file_syms[i + 1]["first_sym"]
+ else:
+ next_symbol = end
+
+ data_base = symbol - info["base"]
+ data_offset = symbol - vram
+ data_size = next_symbol - symbol
+
+ if data_offset == len(data):
+ continue
+
+ r = f"\nglabel {proper_name(symbol, True)}\n"
+
+ if symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}"
+ for j, dbl_dwd in enumerate(
+ as_dword_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in dwords:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} */ .quad 0x{dword:08X}"
+ for j, dword in enumerate(
+ as_dword_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ elif symbol % 4 == 0 and data_size % 4 == 0:
+ if symbol in floats:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}"
+ for j, flt_wd in enumerate(
+ as_word_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ else:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}"
+ for j, word in enumerate(
+ as_word_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ elif symbol % 2 == 0 and data_size % 2 == 0:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}"
+ for j, hword in enumerate(
+ as_hword_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ else:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}"
+ for j, byte in enumerate(
+ data[data_offset : data_offset + data_size], 0
+ )
+ ]
+ )
+ + "\n"
+ )
+ result.append(r)
+
+ if len(result) > 1:
+ with open(
+ f"{DATA_OUT}/{segment_dirname}/{file['name']}.data.s", "w"
+ ) as outfile:
+ outfile.write("".join(result))
+
+
+def disassemble_rodata(data, vram, end, info):
+ section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end]
+ section_symbols.append(vram)
+ section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end])
+ section_symbols.extend(
+ [sym for sym in variables_ast.keys() if sym >= vram and sym < end]
+ )
+ # TODO temp hack, move
+ section_symbols.extend(
+ [sym for sym in info["syms"].keys() if sym >= vram and sym < end]
+ )
+
+ # remove symbols that are addends of other symbols
+ section_symbols = [
+ sym
+ for sym in section_symbols
+ if " + 0x" not in proper_name(sym, True)
+ and " - 0x" not in proper_name(sym, True)
+ ]
+
+ section_symbols = list(set(section_symbols))
+
+ if len(section_symbols) == 0:
+ return
+
+ section_symbols.sort()
+
+ segment_dirname = info["name"]
+ if info["type"] in ("boot", "code"):
+ segment_dirname = info["type"]
+ os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
+
+ if info["type"] in ("boot", "code"):
+ sym_list = full_file_list[info["type"]]
+ else:
+ sym_list = full_file_list[info["name"]]
+
+ force_ascii_str = False # hack for non-null-terminated strings in .data
+
+ file_syms = []
+ syms = []
+ file_name = ""
+ for i, sym in enumerate(section_symbols):
+ if i == 0:
+ if info["type"] == "overlay":
+ file_name = info["name"]
+ else:
+ file_name = sym_list[sym]
+
+ if sym in sym_list:
+ new_file = sym_list[sym]
+ if file_name != new_file:
+ file_syms.append(
+ {"name": file_name, "first_sym": syms[0], "syms": syms}
+ )
+ syms = []
+ file_name = new_file
+ syms.append(sym)
+ if len(syms) > 0:
+ file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms})
+
+ for i, file in enumerate(file_syms):
+ if file["first_sym"] not in info["syms"]:
+ continue
+
+ result = [asm_header(".rodata")]
+
+ for x, symbol in enumerate(file["syms"]):
+ if symbol >= end:
+ break
+ if x + 1 < len(file["syms"]):
+ next_symbol = file["syms"][x + 1]
+ elif i + 1 < len(file_syms):
+ next_symbol = file_syms[i + 1]["first_sym"]
+ else:
+ next_symbol = end
+
+ data_base = symbol - info["base"]
+ data_offset = symbol - vram
+ data_size = next_symbol - symbol
+
+ if data_offset == len(data):
+ continue
+
+ force_ascii_str = symbol in [0x801D0708]
+
+ r = f"\nglabel {proper_name(symbol, True)}\n"
+
+ if symbol in strings:
+ string_data = data[data_offset : data_offset + data_size]
+ string_data = string_data[: string_data.index(0)]
+ # ensure strings don't have a null char midway through
+ assert all(
+ [b != 0 for b in string_data[:-1]]
+ ), f"{symbol:08X} , {data_size:X} , {string_data}"
+ r += f"/* {data_base:06X} {symbol:08X} */ {try_decode_string(string_data, force_ascii=force_ascii_str)}\n{STR_INDENT}.balign 4\n"
+ elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}"
+ for j, dbl_dwd in enumerate(
+ as_dword_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ elif symbol % 4 == 0 and data_size % 4 == 0:
+ if symbol in floats:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}"
+ for j, flt_wd in enumerate(
+ as_word_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ else:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}"
+ for j, word in enumerate(
+ as_word_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ elif symbol % 2 == 0 and data_size % 2 == 0:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}"
+ for j, hword in enumerate(
+ as_hword_list(
+ data[data_offset : data_offset + data_size]
+ ),
+ 0,
+ )
+ ]
+ )
+ + "\n"
+ )
+ else:
+ r += (
+ "\n".join(
+ [
+ f"/* {data_base + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}"
+ for j, byte in enumerate(
+ data[data_offset : data_offset + data_size], 0
+ )
+ ]
+ )
+ + "\n"
+ )
+
+ result.append(r)
+
+ if len(result) > 1:
+ with open(
+ f"{DATA_OUT}/{segment_dirname}/{file['name']}.rodata.s", "w"
+ ) as outfile:
+ outfile.write("".join(result))
+
+
+def disassemble_bss(vram, end, info):
+ section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end]
+ section_symbols.append(vram)
+ section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end])
+ section_symbols.extend(
+ [sym for sym in variables_ast.keys() if sym >= vram and sym < end]
+ )
+ # TODO temp hack, move
+ section_symbols.extend(
+ [sym for sym in info["syms"].keys() if sym >= vram and sym < end]
+ )
+
+ # remove symbols that are addends of other symbols
+ section_symbols = [
+ sym
+ for sym in section_symbols
+ if " + 0x" not in proper_name(sym, True)
+ and " - 0x" not in proper_name(sym, True)
+ ]
+
+ section_symbols = list(set(section_symbols))
+
+ section_symbols.sort()
+
+ # ("" if info["type"] != "overlay" else "overlays/"
+ segment_dirname = (
+ info["name"] if info["type"] not in ("boot", "code") else info["type"]
+ )
+ os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
+
+ if info["type"] in ("boot", "code"):
+ sym_list = full_file_list[info["type"]]
+ else:
+ sym_list = full_file_list[info["name"]]
+
+ file_syms = []
+ syms = []
+ file_name = ""
+ for i, sym in enumerate(section_symbols):
+ if i == 0:
+ if info["type"] == "overlay":
+ file_name = info["name"]
+ else:
+ file_name = sym_list[sym]
+
+ if sym in sym_list:
+ new_file = sym_list[sym]
+ if file_name != new_file:
+ file_syms.append(
+ {"name": file_name, "first_sym": syms[0], "syms": syms}
+ )
+ syms = []
+ file_name = new_file
+ syms.append(sym)
+ if len(syms) > 0:
+ file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms})
+
+ for i, file in enumerate(file_syms):
+ if file["first_sym"] not in info["syms"]:
+ continue
+
+ result = [asm_header(".bss")]
+
+ for x, symbol in enumerate(file["syms"]):
+ if symbol >= end:
+ break
+ if x + 1 < len(file["syms"]):
+ next_symbol = file["syms"][x + 1]
+ elif i + 1 < len(file_syms):
+ next_symbol = file_syms[i + 1]["first_sym"]
+ else:
+ next_symbol = end
+
+ result.append(f"\nglabel {proper_name(symbol, True)}\n")
+ result.append(
+ f"/* {symbol - vram:06X} {symbol:08X} */ .space 0x{next_symbol - symbol:X}\n"
+ )
+
+ if len(result) > 1:
+ with open(
+ f"{DATA_OUT}/{segment_dirname}/{file['name']}.bss.s", "w"
+ ) as outfile:
+ outfile.write("".join(result))
+
def get_overlay_sections(vram, overlay):
header_loc = len(overlay) - as_word_list(overlay)[-1]
- text_size, data_size, rodata_size, bss_size, n_relocs = as_word_list(overlay[header_loc:header_loc + 0x14])
+ text_size, data_size, rodata_size, bss_size, n_relocs = as_word_list(
+ overlay[header_loc : header_loc + 0x14]
+ )
text_vram = vram
data_vram = vram + text_size
rodata_vram = data_vram + data_size
@@ -1092,154 +1864,66 @@ def get_overlay_sections(vram, overlay):
bss_vram = vram + len(overlay)
bss_end_vram = bss_vram + bss_size
- reloc = as_word_list(overlay[header_loc + 0x14: header_loc + 0x14 + n_relocs * 4])
- reloc = [((rel >> 30) & ((1 << 2) - 1), (rel >> 24) & ((1 << 6) - 1), (rel) & ((1 << 24) - 1)) for rel in reloc]
+ reloc = as_word_list(overlay[header_loc + 0x14 : header_loc + 0x14 + n_relocs * 4])
+ reloc = [
+ (
+ (rel >> 30) & ((1 << 2) - 1),
+ (rel >> 24) & ((1 << 6) - 1),
+ (rel) & ((1 << 24) - 1),
+ )
+ for rel in reloc
+ ]
rel_text = [r for r in reloc if r[0] == 1]
rel_data = [r for r in reloc if r[0] == 2]
rel_rodata = [r for r in reloc if r[0] == 3]
rel_bss = [r for r in reloc if r[0] == 4]
- return [[text_vram, data_vram, 'text', None, overlay[0:text_size], rel_text], \
- [data_vram, rodata_vram, 'data', None, overlay[text_size:text_size+data_size], rel_data], \
- [rodata_vram, bss_vram, 'rodata', None, overlay[text_size+data_size:text_size+data_size+rodata_size], rel_rodata], \
- [bss_vram, bss_end_vram, 'bss', None, None, rel_bss], \
- [bss_end_vram, bss_end_vram, 'reloc', None, overlay[header_loc:], None]]
+ return [
+ [text_vram, data_vram, "text", None, overlay[0:text_size], rel_text],
+ [
+ data_vram,
+ rodata_vram,
+ "data",
+ None,
+ overlay[text_size : text_size + data_size],
+ rel_data,
+ ],
+ [
+ rodata_vram,
+ bss_vram,
+ "rodata",
+ None,
+ overlay[text_size + data_size : text_size + data_size + rodata_size],
+ rel_rodata,
+ ],
+ [bss_vram, bss_end_vram, "bss", None, None, rel_bss],
+ [bss_end_vram, bss_end_vram, "reloc", None, overlay[header_loc:], None],
+ ]
-#
-print("Setting Up")
-
-files_spec = None
-with open("tools/disasm/files.txt", "r") as infile:
- files_spec = ast.literal_eval(infile.read())
-
-with open("tools/disasm/functions.txt", "r") as infile:
- functions_ast = ast.literal_eval(infile.read())
-
-with open("tools/disasm/variables.txt", "r") as infile:
- variables_ast = ast.literal_eval(infile.read())
-
-# Find floats, doubles, and strings
-for var in sorted(variables_ast.keys()):
- var_type = variables_ast[var][1]
-
- if var_type == "f64":
- doubles.add(var)
- elif var_type == "f32":
- floats.add(var)
- elif var_type == "char" and variables_ast[var][2].startswith("["):
- strings.add(var)
-
-# Read in binary and relocation data for each segment
-for segment in files_spec:
- binary = None
- with open(segment[1] + "/" + segment[0],"rb") as infile:
- binary = bytes(infile.read())
-
- if segment[2] == "overlay":
- segment_start = list(segment[4])[0] # start addr of first file in segment
- segment[3] = get_overlay_sections(segment_start, binary)
- segment[4] = {}
- for section in segment[3]:
- segment[4].update({ section[0] : segment[0] })
- else:
- segment_start = segment[3][0][0] # start addr of first section of segment's sections
- # read section binary regions
- for section in segment[3]:
- if section[2] == 'bss':
- continue
- section.append(binary[section[0] - segment_start:section[1] - segment_start]) # section[4]
- section.append(None) # section[5]
-
-print(f"Finding Symbols")
-
-for segment in files_spec:
- if segment[2] == 'makerom':
- continue
-
- print(f"Finding segment positions in {segment[0]}")
-
- # vram segment start
- if segment[3][0][0] not in variables_ast:
- variables_ast.update({segment[3][0][0] : (f"_{segment[0]}SegmentStart","u8","[]",0x1)})
- # vram segment end
- if segment[3][-1][1] not in variables_ast:
- variables_ast.update({segment[3][-1][1] : (f"_{segment[0]}SegmentEnd","u8","[]",0x1)})
-
-# Construct variable_addrs, now that variable_addrs is fully constructed
-variable_addrs = sorted(variables_ast.keys())
-
-pool = get_context("fork").Pool(jobs)
-# Find symbols for each segment
-for segment in files_spec:
- if segment[2] == 'makerom':
- continue
-
- #print(f"Finding symbols from .text and .data in {segment[0]}")
-
- for section in segment[3]:
- if section[2] == 'text':
- data_regions = []
- if section[3] is not None:
- for override_region in section[3]:
- if override_region[2] == 'data':
- data_regions.append((override_region[0], override_region[1]))
- # try find a rodata section
- for find_section in segment[3]:
- if find_section[2] == 'rodata' and find_section[1] != find_section[0]:
- rodata_section = find_section
- break
- else:
- rodata_section = None
- pool.apply_async(find_symbols_in_text, args=(section[4], rodata_section[4] if rodata_section is not None else None,
- section[0], rodata_section[0] if rodata_section is not None else None, data_regions, section[5], segment[0]), callback=update_symbols_from_dict)
- elif section[2] == 'data':
- pool.apply_async(find_symbols_in_data, args=(section[4], section[0], section[1], section[5], segment[0]), callback=update_symbols_from_dict)
-
-pool.close()
-pool.join()
-
-for segment in files_spec:
- if segment[2] == 'makerom':
- continue
-
- print(f"Finding symbols from .rodata and .dmadata in {segment[0]}")
-
- for section in segment[3]:
- if section[2] == 'rodata':
- find_symbols_in_rodata(section[4], section[0], section[1], section[5], segment)
- elif section[2] == 'dmadata':
- filenames = []
- with open("tools/disasm/dma_filenames.txt","r") as infile:
- filenames = ast.literal_eval(infile.read())
-
- dmadata = segment[3][0][4]
- i = 0
- dmadata_entry = dmadata[i*0x10:(i+1)*0x10]
- while any([word != 0 for word in as_word_list(dmadata_entry)]):
- vrom_start,vrom_end,prom_start,prom_end = as_word_list(dmadata_entry)
- # print(f"{vrom_start:08X},{vrom_end:08X},{prom_start:08X},{prom_end:08X} : {filenames[i]}")
- vrom_variables.append(("_" + filenames[i] + "SegmentRomStart", vrom_start))
- vrom_variables.append(("_" + filenames[i] + "SegmentRomEnd", vrom_end))
- i += 1
- dmadata_entry = dmadata[i*0x10:(i+1)*0x10]
-
-# Construct vrom_addrs, now that vrom_variables is fully constructed
-vrom_addrs = {addr for _, addr in vrom_variables}
-
-def disassemble_makerom(segment):
+def disassemble_makerom(section):
os.makedirs(f"{ASM_OUT}/makerom/", exist_ok=True)
- rom_header = segment[3][0][4]
- ipl3 = segment[3][1][4]
- entry = segment[3][2][4]
- pi_dom1_reg, clockrate, entrypoint, revision, \
- chksum1, chksum2, pad1, pad2, \
- rom_name, pad3, cart, cart_id, \
- region, version = struct.unpack(">IIIIIIII20sII2s1sB", rom_header)
+ if section[2] == "rom_header":
+ (
+ pi_dom1_reg,
+ clockrate,
+ entrypoint,
+ revision,
+ chksum1,
+ chksum2,
+ pad1,
+ pad2,
+ rom_name,
+ pad3,
+ cart,
+ cart_id,
+ region,
+ version,
+ ) = struct.unpack(">IIIIIIII20sII2s1sB", section[4])
- out = f"""/*
+ out = f"""/*
* The Legend of Zelda: Majora's Mask ROM header
*/
@@ -1258,49 +1942,51 @@ def disassemble_makerom(segment):
.ascii "{region.decode('ascii')}" /* Region */
.byte 0x{version:02X} /* Version */
"""
- with open(ASM_OUT + "/makerom/rom_header.s", "w") as outfile:
- outfile.write(out)
+ with open(ASM_OUT + "/makerom/rom_header.s", "w") as outfile:
+ outfile.write(out)
- # TODO disassemble this eventually, low priority
- out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x40, 0xFC0\n"
+ elif section[-1]["type"] == "ipl3":
+ # TODO disassemble this eventually, low priority
+ out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x40, 0xFC0\n"
- with open(ASM_OUT + "/makerom/ipl3.s", "w") as outfile:
- outfile.write(out)
+ with open(ASM_OUT + "/makerom/ipl3.s", "w") as outfile:
+ outfile.write(out)
- # hack: add symbol relocations manually
- entry_addr = 0x80080000
+ elif section[-1]["type"] == "entry":
+ # hack: add symbol relocations manually
+ entry_addr = 0x80080000
- functions.add(entry_addr)
- symbols.update({entry_addr + 0x00 : 0x80099500,
- entry_addr + 0x04 : 0x80099500,
- entry_addr + 0x20 : 0x80080060,
- entry_addr + 0x24 : 0x80099EF0,
- entry_addr + 0x28 : 0x80080060,
- entry_addr + 0x30 : 0x80099EF0})
- branch_labels.add(entry_addr + 0xC)
+ functions.add(entry_addr)
+ symbols.update(
+ {
+ entry_addr + 0x00: 0x80099500,
+ entry_addr + 0x04: 0x80099500,
+ entry_addr + 0x20: 0x80080060,
+ entry_addr + 0x24: 0x80099EF0,
+ entry_addr + 0x28: 0x80080060,
+ entry_addr + 0x30: 0x80099EF0,
+ }
+ )
+ branch_labels.add(entry_addr + 0xC)
+ disassemble_text(section[4], entry_addr, [], section[-1])
- disassemble_text(entry, entry_addr, [], segment)
+ # manually set boot bss size...
+ entry_asm = ""
+ with open(f"{ASM_OUT}/makerom/entry.text.s") as infile:
+ entry_asm = infile.read()
- # manually set boot bss size...
- entry_asm = ""
- with open(f"{ASM_OUT}/makerom/entry.text.s") as infile:
- entry_asm = infile.read()
+ entry_asm = entry_asm.replace("0x63b0", "%lo(_bootSegmentBssSize)")
+ with open(f"{ASM_OUT}/makerom/entry.s", "w") as outfile:
+ outfile.write(entry_asm)
- entry_asm = entry_asm.replace("0x63b0", "%lo(_bootSegmentBssSize)")
- with open(f"{ASM_OUT}/makerom/entry.s", "w") as outfile:
- outfile.write(entry_asm)
+ os.remove(f"{ASM_OUT}/makerom/entry.text.s")
- os.remove(f"{ASM_OUT}/makerom/entry.text.s")
- #out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x1000, 0x60\n"
-
- #with open(ASM_OUT + "/makerom/entry.s", "w") as outfile:
- # outfile.write(out)
-
-def disassemble_segment(segment):
- if segment[2] == 'dmadata':
- os.makedirs(f"{ASM_OUT}/dmadata/", exist_ok=True)
- out = f""".include "macro.inc"
+def disassemble_dmadata(section):
+ if section[2] == "bss":
+ return
+ os.makedirs(f"{ASM_OUT}/dmadata/", exist_ok=True)
+ out = f""".include "macro.inc"
.macro DMA_TABLE_ENTRY segment
.4byte _\segment\()SegmentRomStart
@@ -1318,137 +2004,132 @@ def disassemble_segment(segment):
glabel {variables_ast[0x8009F8B0][0]}
"""
- filenames = []
- with open("tools/disasm/dma_filenames.txt","r") as infile:
- filenames = ast.literal_eval(infile.read())
+ filenames = []
+ with open("tools/disasm/dma_filenames.txt", "r") as infile:
+ filenames = ast.literal_eval(infile.read())
- dmadata = segment[3][0][4]
- i = 0
- dmadata_entry = dmadata[i*0x10:(i+1)*0x10]
- while any([word != 0 for word in as_word_list(dmadata_entry)]):
- vrom_start,vrom_end,prom_start,prom_end = as_word_list(dmadata_entry)
- if prom_start == 0xFFFFFFFF and prom_end == 0xFFFFFFFF:
- out += f"DMA_TABLE_ENTRY_UNSET {filenames[i]}\n"
- else:
- out += f"DMA_TABLE_ENTRY {filenames[i]}\n"
- i += 1
- dmadata_entry = dmadata[i*0x10:(i+1)*0x10]
+ dmadata = section[4]
+ i = 0
+ dmadata_entry = dmadata[i * 0x10 : (i + 1) * 0x10]
+ while any([word != 0 for word in as_word_list(dmadata_entry)]):
+ vrom_start, vrom_end, prom_start, prom_end = as_word_list(dmadata_entry)
+ if prom_start == 0xFFFFFFFF and prom_end == 0xFFFFFFFF:
+ out += f"DMA_TABLE_ENTRY_UNSET {filenames[i]}\n"
+ else:
+ out += f"DMA_TABLE_ENTRY {filenames[i]}\n"
- out += """
+ vrom_variables.append(("_" + filenames[i] + "SegmentRomStart", vrom_start))
+ vrom_variables.append(("_" + filenames[i] + "SegmentRomEnd", vrom_end))
+
+ i += 1
+ dmadata_entry = dmadata[i * 0x10 : (i + 1) * 0x10]
+
+ out += """
.space 0x100
.section .bss
.space 0x10
"""
- with open(ASM_OUT + "/dmadata/dmadata.s", "w") as outfile:
- outfile.write(out)
+ with open(ASM_OUT + "/dmadata/dmadata.s", "w") as outfile:
+ outfile.write(out)
+
+
+def disassemble_segment(section):
+ if section[-1]["name"] == "[PADDING]":
return
- for section in segment[3]:
- if (section[0] == section[1] and section[2] != 'reloc') or (section[2] != 'bss' and len(section[4]) == 0):
- continue
- print(f"Disassembling {segment[0]} .{section[2]}")
- if section[2] == 'text':
- data_regions = []
- if section[3] is not None:
- for override_region in section[3]:
- if override_region[2] == 'data':
- data_regions.append((override_region[0], override_region[1]))
+ print(f"Disassembling {section[-1]['name']} .{section[2]}")
- disassemble_text(section[4], section[0], data_regions, segment)
- elif section[2] == 'data':
- disassemble_data(section[4], section[0], section[1], segment)
- elif section[2] == 'rodata':
- disassemble_rodata(section[4], section[0], section[1], segment)
- elif section[2] == 'bss':
- disassemble_bss(section[0], section[1], segment)
- elif section[2] == 'reloc':
- words = as_word_list(section[4])
+ if section[2] == "text":
+ fixup_text_symbols(section[4], section[0], data_regions, section[-1])
+ elif section[2] == "data":
+ disassemble_data(section[4], section[0], section[1], section[-1])
+ elif section[2] == "rodata":
+ disassemble_rodata(section[4], section[0], section[1], section[-1])
+ elif section[2] == "bss":
+ disassemble_bss(section[0], section[1], section[-1])
+ elif section[2] == "reloc":
+ words = as_word_list(section[4])
- # ("" if segment[2] != "overlay" else "overlays/") +
- segment_dirname = segment[0]
+ segment_dirname = section[-1]["name"]
- result = asm_header(".rodata")
- result += f"\nglabel {segment[0]}_Reloc\n"
+ result = asm_header(".rodata")
+ result += f"\nglabel {section[-1]['name']}_Reloc\n"
- lines = [words[i*8:(i+1)*8] for i in range(0, (len(words) // 8) + 1)]
- for line in [line for line in lines if len(line) != 0]:
- result += f" .word {', '.join([f'0x{word:08X}' for word in line])}\n"
+ lines = [words[i * 8 : (i + 1) * 8] for i in range(0, (len(words) // 8) + 1)]
+ for line in [line for line in lines if len(line) != 0]:
+ result += f" .word {', '.join([f'0x{word:08X}' for word in line])}\n"
- os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
- with open(f"{DATA_OUT}/{segment_dirname}/{segment[0]}.reloc.s", "w") as outfile:
- outfile.write(result)
+ os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True)
+ with open(
+ f"{DATA_OUT}/{segment_dirname}/{section[-1]['name']}.reloc.s", "w"
+ ) as outfile:
+ outfile.write(result)
-print("Disassembling Segments")
-
-disassemble_makerom(next(segment for segment in files_spec if segment[2] == 'makerom'))
-
-# Textual disassembly for each segment
-with get_context("fork").Pool(jobs) as p:
- p.map(disassemble_segment, (segment for segment in files_spec if segment[2] != 'makerom'))
-
-print("Splitting text and migrating rodata")
-
-func_regex = re.compile(r'\n\nglabel \S+\n')
-rodata_symbols_regex = re.compile(r'(?<=\n)glabel (.+)(?=\n)')
-asm_symbols_regex = re.compile(r'%(?:lo|hi)\((.+?)\)')
def rodata_block_size(block):
def align(x, n):
- while (x % n != 0):
+ while x % n != 0:
x += 1
return x
accumulator = 0
- for part in block.split(' */ .'):
+ for part in block.split(" */ ."):
part = part.strip()
- if part.startswith('# '):
+ if part.startswith("# "):
continue
- elif part.startswith('asciz '):
- part = part[len('asciz '):]
- string = part[1:-1].encode('utf-8', 'ignore').decode('unicode_escape')
- accumulator += len(string.encode('euc-jp') + b'\x00')
- elif part.startswith('ascii'):
- part = part[len('ascii '):]
- string = part[1:-1].encode('utf-8', 'ignore').decode('unicode_escape')
- accumulator += len(string.encode('euc-jp'))
- elif part.startswith('balign '):
- part = part[len('balign '):]
- accumulator = align(accumulator, int(part, 16 if part.startswith('0x') else 10))
- elif part.startswith('double '):
- part = part[len('double '):]
+ elif part.startswith("asciz "):
+ part = part[len("asciz ") :]
+ string = part[1:-1].encode("utf-8", "ignore").decode("unicode_escape")
+ accumulator += len(string.encode("euc-jp") + b"\x00")
+ elif part.startswith("ascii"):
+ part = part[len("ascii ") :]
+ string = part[1:-1].encode("utf-8", "ignore").decode("unicode_escape")
+ accumulator += len(string.encode("euc-jp"))
+ elif part.startswith("balign "):
+ part = part[len("balign ") :]
+ accumulator = align(
+ accumulator, int(part, 16 if part.startswith("0x") else 10)
+ )
+ elif part.startswith("double "):
+ part = part[len("double ") :]
accumulator = align(accumulator, 8)
- accumulator += 8 * (part.count(',') + 1)
- elif part.startswith('float '):
- part = part[len('float '):]
+ accumulator += 8 * (part.count(",") + 1)
+ elif part.startswith("float "):
+ part = part[len("float ") :]
accumulator = align(accumulator, 4)
- accumulator += 4 * (part.count(',') + 1)
- elif part.startswith('word '):
- part = part[len('word '):]
+ accumulator += 4 * (part.count(",") + 1)
+ elif part.startswith("word "):
+ part = part[len("word ") :]
accumulator = align(accumulator, 4)
- accumulator += 4 * (part.count(',') + 1)
- elif part.startswith('half '):
- part = part[len('half '):]
+ accumulator += 4 * (part.count(",") + 1)
+ elif part.startswith("half "):
+ part = part[len("half ") :]
accumulator = align(accumulator, 2)
- accumulator += 2 * (part.count(',') + 1)
- elif part.startswith('byte '):
- part = part[len('byte '):]
- accumulator += 1 * (part.count(',') + 1)
+ accumulator += 2 * (part.count(",") + 1)
+ elif part.startswith("byte "):
+ part = part[len("byte ") :]
+ accumulator += 1 * (part.count(",") + 1)
return accumulator
+
def late_rodata_size(blocks):
return sum([rodata_block_size(block) for block in blocks])
+
def text_block_size(asm):
- return 4*len([line for line in asm.split("\n") if line.startswith("/*")])
+ return 4 * len([line for line in asm.split("\n") if line.startswith("/*")])
+
def rodata_syms(rodata):
return re.findall(rodata_symbols_regex, rodata)
+
def rodata_blocks(rodata):
return ["glabel" + b for b in rodata.split("glabel")[1:]]
+
def find_late_rodata_start(rodata):
"""
Returns the symbol that is the first late_rodata symbol, or None if there is no late_rodata
@@ -1460,7 +2141,7 @@ def find_late_rodata_start(rodata):
"""
first = None
- for sym,body in rodata:
+ for sym, body in rodata:
if sym.startswith("jtbl_") and ".word L" in body:
# jump tables are always late_rodata, so we can return early
# floats and doubles are very rarely not late_rodata, this is mostly seen in libultra, so we cannot return early for those
@@ -1472,25 +2153,281 @@ def find_late_rodata_start(rodata):
# may be late_rodata, but we aren't sure yet
# it is confirmed either by reaching the end or by finding a jumptable, and it is proven wrong if something that is not late_rodata occurs after it
first = sym
- elif (".asciz" in body or (".word " in body and ".float" not in body) or ".half " in body or ".byte " in body) and first is not None:
+ elif (
+ ".asciz" in body
+ or (".word " in body and ".float" not in body)
+ or ".half " in body
+ or ".byte " in body
+ ) and first is not None:
# reset first if something that is definitely not late_rodata is found
# word and not float is due to some floats needing to be output as words either due to being a specific NaN value, or GAS can't convert it properly
first = None
# May still be None at this point, that just means there is no late_rodata
return first
+
+# ==========================================#
+
+print("Setting Up")
+
+files_spec = None
+with open("tools/disasm/files.txt", "r") as infile:
+ files_spec = ast.literal_eval(infile.read())
+
+with open("tools/disasm/functions.txt", "r") as infile:
+ functions_ast = ast.literal_eval(infile.read())
+
+with open("tools/disasm/variables.txt", "r") as infile:
+ variables_ast = ast.literal_eval(infile.read())
+
+# We need to keep a full list of original file offsets to know where to split files later
+full_file_list = {}
+for segment in files_spec:
+ new = {}
+ for offset, name in segment[4].items():
+ if name == "":
+ name = f"{segment[2]}_{offset:08X}"
+ new[offset] = name
+ full_file_list[segment[0]] = new
+
+if args.full:
+ for segment in files_spec:
+ for offset, name in segment[4].items():
+ if name == "":
+ name = f"{segment[2]}_{offset:08X}"
+ segment[4][offset] = name
+else:
+ # Prune
+ old_file_count = sum([len(f[4].keys()) for f in files_spec])
+
+ files_spec = discard_decomped_files(files_spec)
+
+ new_file_count = sum([len(f[4].keys()) for f in files_spec])
+
+ pruned = old_file_count - new_file_count
+ print(f"Pruned {pruned}/{old_file_count} files ({pruned / old_file_count:.02%})")
+
+# Find floats, doubles, and strings
+for var in sorted(variables_ast.keys()):
+ var_type = variables_ast[var][1]
+
+ if var_type == "f64":
+ doubles.add(var)
+ elif var_type == "f32":
+ floats.add(var)
+ elif var_type == "char" and variables_ast[var][2].startswith("["):
+ strings.add(var)
+
+# Read in binary and relocation data for each segment
+for seg, segment in enumerate(files_spec):
+ binary = None
+ with open(segment[1] + "/" + segment[0], "rb") as infile:
+ binary = bytes(infile.read())
+
+ if segment[2] == "overlay":
+ segment_start = list(segment[4])[0] # start addr of first file in segment
+ segment[3] = get_overlay_sections(segment_start, binary)
+ segment[4] = {}
+ for section in segment[3]:
+ segment[4].update({section[0]: segment[0]})
+ else:
+ # start addr of first section of segment's sections
+ segment_start = segment[3][0][0]
+ # read section binary regions
+ for i, section in enumerate(segment[3]):
+ if section[2] == "bss":
+ continue
+ # section[4]
+ section.append(
+ binary[section[0] - segment_start : section[1] - segment_start]
+ )
+ section.append(None) # section[5]
+
+print(f"Finding segment positions")
+
+for segment in files_spec:
+ if segment[2] == "makerom":
+ continue
+
+ print(f"Finding segment positions in {segment[0]}")
+
+ # vram segment start
+ if segment[3][0][0] not in variables_ast:
+ variables_ast.update(
+ {segment[3][0][0]: (f"_{segment[0]}SegmentStart", "u8", "[]", 0x1)}
+ )
+ # vram segment end
+ if segment[3][-2][1] not in variables_ast:
+ variables_ast.update(
+ {segment[3][-2][1]: (f"_{segment[0]}SegmentEnd", "u8", "[]", 0x1)}
+ )
+
+# Construct variable_addrs, now that variable_addrs is fully constructed
+variable_addrs = sorted(variables_ast.keys())
+
+# Flatten out files_spec so we can process everything evenly
+# Otherwise the entire code and boot sections are done by a single thread
+all_sections = []
+for segment in files_spec:
+ if segment[0] == "boot" or segment[0] == "code":
+ file_list = list(full_file_list[segment[0]])
+ section_starts = [x[0] for x in segment[3]]
+
+ for off, name in segment[4].items():
+ # loop over the vram starts for this segment's sections to find where it belongs (text, data, etc)
+ for i, s in enumerate(section_starts):
+ if off < s:
+ break
+ else:
+ i = len(section_starts)
+ i -= 1
+
+ # Calculate the offset and size of this section relative to the section
+ data_offset = off - segment[3][i][0]
+ full_index = file_list.index(off)
+ if segment[0] == "code" and name == "buffers" and segment[3][i][2] == "bss":
+ # This is the end of code, hardcode it
+ data_size = 0x80800000 - file_list[full_index]
+ elif segment[0] == "boot" and name == "vimgr" and segment[3][i][2] == "bss":
+ # This is the end of boot, hardcode it
+ data_size = 0x800A5AC0 - file_list[full_index]
+ else:
+ data_size = file_list[full_index + 1] - file_list[full_index]
+
+ # Create the section entry for this file
+ new_entry = [
+ off,
+ off + data_size,
+ segment[3][i][2],
+ None,
+ segment[3][i][4][data_offset : data_offset + data_size]
+ if segment[3][i][2] not in ("bss")
+ else None,
+ None if segment[3][i][2] in ["text", "reloc", "data"] else [],
+ {
+ "name": name,
+ "type": segment[2],
+ "base": segment[3][0][0],
+ "syms": {
+ x: name for x in segment[4] if x >= off and x < off + data_size
+ },
+ },
+ ]
+
+ all_sections.append(new_entry)
+
+ # I don't remember what this is for but it's still needed
+ for i, entry in enumerate(segment[3]):
+ if segment[0] == "makerom" and i == 1:
+ segment[2] = "ipl3"
+ elif segment[0] == "makerom" and i == 2:
+ segment[2] = "entry"
+ entry.append(
+ {
+ "name": segment[0],
+ "type": segment[2],
+ "base": segment[3][0][0],
+ "syms": segment[4],
+ }
+ )
+
+ all_sections.extend(segment[3])
+
+del files_spec[:]
+
+pool = get_context("fork").Pool(jobs)
+# Find symbols for each segment
+for section in all_sections:
+ if section[-1]["name"] == "makerom":
+ continue
+
+ if section[2] == "text":
+ data_regions = []
+ if section[3] is not None:
+ for override_region in section[3]:
+ if override_region[2] == "data":
+ data_regions.append((override_region[0], override_region[1]))
+ # try find a rodata section
+ for s in all_sections:
+ if (
+ s[-1]["name"] == section[-1]["name"]
+ and s[2] == "rodata"
+ and s[0] != s[1]
+ ):
+ rodata_section = s
+ break
+ else:
+ rodata_section = None
+ pool.apply_async(
+ find_symbols_in_text,
+ args=(section, rodata_section if rodata_section else None, data_regions),
+ callback=update_symbols_from_dict,
+ )
+ elif section[2] == "data":
+ pool.apply_async(
+ find_symbols_in_data, args=(section), callback=update_symbols_from_dict
+ )
+
+pool.close()
+pool.join()
+
+pool = get_context("fork").Pool(jobs)
+for section in all_sections:
+ if section[-1]["type"] == "makerom":
+ continue
+
+ if section[2] == "rodata":
+ pool.apply_async(
+ find_symbols_in_rodata, args=(section), callback=update_symbols_from_dict
+ )
+
+pool.close()
+pool.join()
+
+for section in all_sections:
+ if section[-1]["name"] == "makerom":
+ print(f"Disassembling makerom")
+ disassemble_makerom(section)
+ elif section[-1]["name"] == "dmadata":
+ print(f"Disassembling dmadata")
+ disassemble_dmadata(section)
+
+# Construct vrom_addrs, now that vrom_variables is fully constructed
+vrom_addrs = {addr for _, addr in vrom_variables}
+
+# Textual disassembly for each segment
+with get_context("fork").Pool(jobs) as p:
+ p.map(
+ disassemble_segment,
+ [
+ sec
+ for sec in all_sections
+ if sec[-1]["name"] not in ("boot", "code", "makerom", "dmadata")
+ ],
+ )
+
+print("Splitting text and migrating rodata")
+
+func_regex = re.compile(r"\n\nglabel \S+\n")
+rodata_symbols_regex = re.compile(r"(?<=\n)glabel (.+)(?=\n)")
+asm_symbols_regex = re.compile(r"%(?:lo|hi)\((.+?)\)")
+
# Split files and migrate rodata that should be migrated
-for root,dirs,files in os.walk(ASM_OUT):
+for root, dirs, files in os.walk(ASM_OUT):
for f in files:
if "non_matchings" in root:
continue
- asm_path = os.path.join(root,f)
- rodata_path = asm_path.replace(ASM_OUT + "overlays/", DATA_OUT).replace(ASM_OUT, DATA_OUT).replace(".text.s", ".rodata.s")
+ asm_path = os.path.join(root, f)
+ rodata_path = (
+ asm_path.replace(ASM_OUT + "overlays/", DATA_OUT)
+ .replace(ASM_OUT, DATA_OUT)
+ .replace(".text.s", ".rodata.s")
+ )
print(asm_path)
asm = ""
- with open(asm_path,"r") as infile:
+ with open(asm_path, "r") as infile:
asm = infile.read()
rodata = ""
@@ -1505,15 +2442,21 @@ for root,dirs,files in os.walk(ASM_OUT):
first_late_rodata = find_late_rodata_start(rodata_info)
rdata_info = []
late_rodata_info = []
- target = rdata_info # first populate rdata
- for sym,block in rodata_info:
- if sym == first_late_rodata: # now populate late_rodata, if there is any
+ target = rdata_info # first populate rdata
+ for sym, block in rodata_info:
+ # now populate late_rodata, if there is any
+ if sym == first_late_rodata:
target = late_rodata_info
- target.append((sym,block))
+ target.append((sym, block))
# print([(sym,block.split("\n")[1:]) for sym,block in zip(rdata_syms,rdata_blocks)])
- function_info = list(zip([s.replace("glabel","").strip() for s in func_regex.findall(asm)], func_regex.split(asm)[1:]))
+ function_info = list(
+ zip(
+ [s.replace("glabel", "").strip() for s in func_regex.findall(asm)],
+ func_regex.split(asm)[1:],
+ )
+ )
rdata_map = {}
late_rodata_map = {}
@@ -1522,18 +2465,20 @@ for root,dirs,files in os.walk(ASM_OUT):
if rodata != "":
last_fn = None
- referenced_in = {} # key=rodata label , value=function label
+ referenced_in = {} # key=rodata label , value=function label
- for sym,_ in rodata_info:
- all_refs = [label for label,body in function_info if "%lo(" + sym + ")" in body]
+ for sym, _ in rodata_info:
+ all_refs = [
+ label for label, body in function_info if "%lo(" + sym + ")" in body
+ ]
# ignore multiple refs, take only the first
- referenced_in.update({ sym : all_refs[0] if len(all_refs) != 0 else None })
+ referenced_in.update({sym: all_refs[0] if len(all_refs) != 0 else None})
def do_splits(out_dict, info):
first = True
last_ref = None
cr = None
- for sym,block in info:
+ for sym, block in info:
ref = referenced_in[sym]
if first:
cr = ref or sym
@@ -1545,11 +2490,11 @@ for root,dirs,files in os.walk(ASM_OUT):
elif last_ref is not None:
# new GLOBAL_ASM
cr = sym
-
+
# add to output
if cr not in out_dict.keys():
- out_dict.update({cr : []})
- out_dict[cr].append((sym,block))
+ out_dict.update({cr: []})
+ out_dict[cr].append((sym, block))
# setup next iter
last_ref = ref
@@ -1559,7 +2504,9 @@ for root,dirs,files in os.walk(ASM_OUT):
do_splits(late_rodata_map, late_rodata_info)
# all output files, order is irrelevant at this point
- all_output = set([label for label,_ in function_info]).union(set(rdata_map.keys()),set(late_rodata_map.keys()))
+ all_output = set([label for label, _ in function_info]).union(
+ set(rdata_map.keys()), set(late_rodata_map.keys())
+ )
# pass 2 to output splits
for label in all_output:
@@ -1567,7 +2514,7 @@ for root,dirs,files in os.walk(ASM_OUT):
text_out = ""
rodata_out = ""
-
+
if fn_body is not None:
text_out = "glabel " + label.strip() + "\n" + fn_body.strip() + "\n"
@@ -1578,43 +2525,81 @@ for root,dirs,files in os.walk(ASM_OUT):
# check for late_rodata_alignment
late_rodata_alignment = ""
if fn_body is not None and late_rodata is not None:
- ratio = late_rodata_size([block for _,block in late_rodata]) / text_block_size(fn_body)
- if ratio > 1./3:
+ ratio = late_rodata_size(
+ [block for _, block in late_rodata]
+ ) / text_block_size(fn_body)
+ if ratio > 1.0 / 3:
# print(f"{label} : {ratio}")
# TODO hack: getting the address from a comment
first_block_split = late_rodata[0][1].split(" */ .")
vaddr = None
- if first_block_split[1].startswith("float") or first_block_split[1].startswith("double"):
+ if first_block_split[1].startswith(
+ "float"
+ ) or first_block_split[1].startswith("double"):
vaddr = first_block_split[0].split(" ")[-2]
else:
vaddr = first_block_split[0].split(" ")[-1]
assert vaddr is not None
- vaddr = int(vaddr,16)
- if vaddr not in [0x801E0E28, 0x80C1C2B0, 0x80AA7820, 0x80AA3CC0,
- 0x80AA418C, 0x80BE0160, 0x80B591D8, 0x80B59610,
- 0x80B59780, 0x80964E00, 0x80964F10, 0x80BB40A0,
- 0x80952038, 0x80AFB920, 0x80AFBBFC, 0x80AFBE28,
- 0x80983320]: # hacks for especially badly behaved rodata, TODO these are ALL jumptables associated with
- # comparatively tiny functions, can we swat these programmatically?
+ vaddr = int(vaddr, 16)
+ if vaddr not in [
+ 0x801E0E28,
+ 0x80C1C2B0,
+ 0x80AA7820,
+ 0x80AA3CC0,
+ 0x80AA418C,
+ 0x80BE0160,
+ 0x80B591D8,
+ 0x80B59610,
+ 0x80B59780,
+ 0x80964E00,
+ 0x80964F10,
+ 0x80BB40A0,
+ 0x80952038,
+ 0x80AFB920,
+ 0x80AFBBFC,
+ 0x80AFBE28,
+ 0x80983320,
+ ]:
+ # hacks for especially badly behaved rodata, TODO these are ALL jumptables associated with
+ # comparatively tiny functions, can we swat these programmatically?
late_rodata_alignment = f".late_rodata_alignment {'8' if vaddr % 8 == 0 else '4'}\n"
rdata_out = ""
if rdata is not None:
- rdata_out = ".rdata\n" + "".join([block for _,block in rdata])
+ rdata_out = ".rdata\n" + "".join([block for _, block in rdata])
late_rodata_out = ""
if late_rodata is not None:
- late_rodata_out = ".late_rodata\n" + late_rodata_alignment + "".join([block for _,block in late_rodata])
+ late_rodata_out = (
+ ".late_rodata\n"
+ + late_rodata_alignment
+ + "".join([block for _, block in late_rodata])
+ )
- rodata_out = rdata_out + late_rodata_out + ("\n.text\n" if ((rdata is not None or late_rodata is not None) and fn_body is not None) else "")
+ rodata_out = (
+ rdata_out
+ + late_rodata_out
+ + (
+ "\n.text\n"
+ if (
+ (rdata is not None or late_rodata is not None)
+ and fn_body is not None
+ )
+ else ""
+ )
+ )
all_out = rodata_out + text_out
# write it out
- out_path = root.replace(ASM_OUT, f"{ASM_OUT}/non_matchings/") + "/" + ((f.replace(".text.s","") + "/") if "overlays" not in root else "")
+ out_path = (
+ root.replace(ASM_OUT, f"{ASM_OUT}/non_matchings/")
+ + "/"
+ + ((f.replace(".text.s", "") + "/") if "overlays" not in root else "")
+ )
os.makedirs(out_path, exist_ok=True)
with open(out_path + label + ".s", "w") as outfile:
outfile.write(all_out.strip() + "\n")
-
+
# remove rodata and unsplit file
# TODO
diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt
index 175bea733..24c1d65ef 100644
--- a/tools/disasm/files.txt
+++ b/tools/disasm/files.txt
@@ -511,6 +511,7 @@
0x801AE330 : "",
0x801AE3A0 : "z_effect_soft_sprite",
0x801AE3B0 : "z_effect_soft_sprite_old_init",
+ 0x801AE4A0 : "z_effect_soft_sprite_dlftbls",
0x801AE8F0 : "flg_set_table",
0x801AEC70 : "flg_set",
0x801AEC80 : "z_actor",
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 64915df39..c3ee0a05c 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -2655,7 +2655,7 @@
0x8013A4C4:("func_8013A4C4",),
0x8013A504:("func_8013A504",),
0x8013A530:("func_8013A530",),
- 0x8013A7C0:("func_8013A7C0",),
+ 0x8013A7C0:("SubS_FindDoor",),
0x8013A860:("func_8013A860",),
0x8013AB00:("func_8013AB00",),
0x8013AD6C:("func_8013AD6C",),
@@ -2668,7 +2668,7 @@
0x8013B6B0:("func_8013B6B0",),
0x8013B878:("func_8013B878",),
0x8013BB34:("func_8013BB34",),
- 0x8013BB7C:("func_8013BB7C",),
+ 0x8013BB7C:("SubS_FindNearestActor",),
0x8013BC6C:("func_8013BC6C",),
0x8013BD40:("func_8013BD40",),
0x8013BEDC:("func_8013BEDC",),
@@ -2689,7 +2689,7 @@
0x8013D83C:("func_8013D83C",),
0x8013D8DC:("func_8013D8DC",),
0x8013D924:("func_8013D924",),
- 0x8013D960:("func_ActorCategoryIterateById",),
+ 0x8013D960:("SubS_FindActor",),
0x8013D9C8:("func_8013D9C8",),
0x8013DB90:("func_8013DB90",),
0x8013DC40:("func_8013DC40",),
@@ -2705,7 +2705,7 @@
0x8013E3B8:("func_8013E3B8",),
0x8013E4B0:("func_8013E4B0",),
0x8013E5CC:("func_8013E5CC",),
- 0x8013E640:("func_8013E640",),
+ 0x8013E640:("SubS_FindActorCustom",),
0x8013E748:("func_8013E748",),
0x8013E7C0:("func_8013E7C0",),
0x8013E8F8:("func_8013E8F8",),
@@ -5527,8 +5527,8 @@
0x808986A4:("func_808986A4",),
0x8089874C:("func_8089874C",),
0x80898A28:("EnPeehat_Update",),
- 0x80898E74:("func_80898E74",),
- 0x80899024:("func_80899024",),
+ 0x80898E74:("EnPeehat_OverrideLimbDraw",),
+ 0x80899024:("EnPeehat_PostLimbDraw",),
0x80899218:("EnPeehat_Draw",),
0x80899960:("EnHoll_SetupAction",),
0x808999B0:("EnHoll_SetPlayerSide",),
@@ -5736,7 +5736,7 @@
0x808A7138:("EnSt_Init",),
0x808A71D0:("EnSt_Destroy",),
0x808A7230:("EnSt_Update",),
- 0x808A73E8:("func_808A73E8",),
+ 0x808A73E8:("EnSt_OverrideLimbDraw",),
0x808A7478:("func_808A7478",),
0x808A7930:("ObjWturn_Init",),
0x808A7954:("func_808A7954",),
@@ -6818,52 +6818,52 @@
0x808FC550:("EnFr_Init",),
0x808FC5AC:("EnFr_Destroy",),
0x808FC5BC:("EnFr_Update",),
- 0x808FC6C0:("func_808FC6C0",),
- 0x808FC770:("func_808FC770",),
- 0x808FC790:("func_808FC790",),
- 0x808FC8B8:("func_808FC8B8",),
- 0x808FC964:("func_808FC964",),
- 0x808FCABC:("func_808FCABC",),
- 0x808FCC0C:("func_808FCC0C",),
- 0x808FCDBC:("func_808FCDBC",),
- 0x808FCF60:("func_808FCF60",),
- 0x808FD054:("func_808FD054",),
+ 0x808FC6C0:("EnFishing_SetColliderElement",),
+ 0x808FC770:("EnFishing_SeedRand",),
+ 0x808FC790:("EnFishing_RandZeroOne",),
+ 0x808FC8B8:("EnFishing_SmoothStepToS",),
+ 0x808FC964:("EnFishing_SpawnRipple",),
+ 0x808FCABC:("EnFishing_SpawnDustSplash",),
+ 0x808FCC0C:("EnFishing_SpawnWaterDust",),
+ 0x808FCDBC:("EnFishing_SpawnBubble",),
+ 0x808FCF60:("EnFishing_SpawnRainDrop",),
+ 0x808FD054:("EnFishing_InitPondProps",),
0x808FD368:("EnFishing_Init",),
0x808FDC64:("EnFishing_Destroy",),
- 0x808FDCDC:("func_808FDCDC",),
- 0x808FE3F8:("func_808FE3F8",),
- 0x808FEE1C:("func_808FEE1C",),
+ 0x808FDCDC:("EnFishing_UpdateEffects",),
+ 0x808FE3F8:("EnFishing_DrawEffects",),
+ 0x808FEE1C:("EnFishing_DrawStreamSplash",),
0x808FEF70:("func_808FEF70",),
- 0x808FF064:("func_808FF064",),
- 0x808FF5E0:("func_808FF5E0",),
- 0x808FF750:("func_808FF750",),
- 0x808FFC44:("func_808FFC44",),
- 0x808FFF3C:("func_808FFF3C",),
- 0x80900228:("func_80900228",),
- 0x80900A04:("func_80900A04",),
- 0x80901480:("func_80901480",),
+ 0x808FF064:("EnFishing_UpdateLine",),
+ 0x808FF5E0:("EnFishing_UpdateLinePos",),
+ 0x808FF750:("EnFishing_DrawLureHook",),
+ 0x808FFC44:("EnFishing_UpdateSinkingLure",),
+ 0x808FFF3C:("EnFishing_DrawSinkingLure",),
+ 0x80900228:("EnFishing_DrawLureAndLine",),
+ 0x80900A04:("EnFishing_DrawRod",),
+ 0x80901480:("EnFishing_UpdateLure",),
0x809033F0:("func_809033F0",),
0x809036BC:("func_809036BC",),
0x809038A4:("func_809038A4",),
0x80903C60:("func_80903C60",),
- 0x80903E20:("func_80903E20",),
- 0x80903FE0:("EnFishing_Update",),
- 0x80908554:("func_80908554",),
- 0x80908674:("func_80908674",),
- 0x809086B4:("func_809086B4",),
- 0x80908734:("func_80908734",),
- 0x80908774:("EnFishing_Draw",),
- 0x809089B8:("func_809089B8",),
- 0x80908A64:("func_80908A64",),
- 0x80908B4C:("func_80908B4C",),
- 0x80908E08:("func_80908E08",),
- 0x80909234:("func_80909234",),
- 0x80909AD0:("func_80909AD0",),
- 0x80909CC0:("func_80909CC0",),
- 0x8090AB6C:("func_8090AB6C",),
- 0x8090C884:("func_8090C884",),
- 0x8090C8BC:("func_8090C8BC",),
- 0x8090C96C:("func_8090C96C",),
+ 0x80903E20:("EnFishing_HandleAquariumDialog",),
+ 0x80903FE0:("EnFishing_UpdateFish",),
+ 0x80908554:("EnFishing_FishOverrideLimbDraw",),
+ 0x80908674:("EnFishing_FishPostLimbDraw",),
+ 0x809086B4:("EnFishing_LoachOverrideLimbDraw",),
+ 0x80908734:("EnFishing_LoachPostLimbDraw",),
+ 0x80908774:("EnFishing_DrawFish",),
+ 0x809089B8:("EnFishing_HandleReedContact",),
+ 0x80908A64:("EnFishing_HandleLilyPadContact",),
+ 0x80908B4C:("EnFishing_UpdatePondProps",),
+ 0x80908E08:("EnFishing_DrawPondProps",),
+ 0x80909234:("EnFishing_UpdateGroupFishes",),
+ 0x80909AD0:("EnFishing_DrawGroupFishes",),
+ 0x80909CC0:("EnFishing_HandleOwnerDialog",),
+ 0x8090AB6C:("EnFishing_UpdateOwner",),
+ 0x8090C884:("EnFishing_OwnerOverrideLimbDraw",),
+ 0x8090C8BC:("EnFishing_OwnerPostLimbDraw",),
+ 0x8090C96C:("EnFishing_DrawOwner",),
0x80917290:("func_80917290",),
0x809172E4:("func_809172E4",),
0x8091734C:("func_8091734C",),
@@ -8077,51 +8077,51 @@
0x80973DE0:("func_80973DE0",),
0x80973E60:("ObjRoomtimer_Update",),
0x80973EF0:("EnSsh_SetupAction",),
- 0x80973EFC:("func_80973EFC",),
- 0x80973F84:("func_80973F84",),
- 0x80974080:("func_80974080",),
- 0x80974118:("func_80974118",),
- 0x80974220:("func_80974220",),
- 0x8097424C:("func_8097424C",),
- 0x80974374:("func_80974374",),
- 0x809744A8:("func_809744A8",),
- 0x809744C8:("func_809744C8",),
- 0x809744FC:("func_809744FC",),
- 0x80974540:("func_80974540",),
- 0x80974590:("func_80974590",),
- 0x809745BC:("func_809745BC",),
- 0x80974730:("func_80974730",),
- 0x8097480C:("func_8097480C",),
- 0x809748DC:("func_809748DC",),
- 0x8097497C:("func_8097497C",),
- 0x809749B8:("func_809749B8",),
- 0x80974A24:("func_80974A24",),
- 0x80974B0C:("func_80974B0C",),
- 0x80974B44:("func_80974B44",),
- 0x80974B84:("func_80974B84",),
- 0x80974CC8:("func_80974CC8",),
- 0x80974D3C:("func_80974D3C",),
- 0x80974E44:("func_80974E44",),
- 0x80974EA0:("func_80974EA0",),
- 0x80974F78:("func_80974F78",),
- 0x8097502C:("func_8097502C",),
- 0x80975070:("func_80975070",),
- 0x80975128:("func_80975128",),
- 0x80975300:("func_80975300",),
+ 0x80973EFC:("EnSsh_SpawnShockwave",),
+ 0x80973F84:("EnSsh_CreateBlureEffect",),
+ 0x80974080:("EnSsh_CheckCeilingPos",),
+ 0x80974118:("EnSsh_AddBlureVertex",),
+ 0x80974220:("EnSsh_AddBlureSpace",),
+ 0x8097424C:("EnSsh_InitColliders",),
+ 0x80974374:("EnSsh_SetAnimation",),
+ 0x809744A8:("EnSsh_SetWaitAnimation",),
+ 0x809744C8:("EnSsh_SetReturnAnimation",),
+ 0x809744FC:("EnSsh_SetLandAnimation",),
+ 0x80974540:("EnSsh_SetDropAnimation",),
+ 0x80974590:("EnSsh_SetStunned",),
+ 0x809745BC:("EnSsh_SetColliderScale",),
+ 0x80974730:("EnSsh_Damaged",),
+ 0x8097480C:("EnSsh_Turn",),
+ 0x809748DC:("EnSsh_Stunned",),
+ 0x8097497C:("EnSsh_UpdateYaw",),
+ 0x809749B8:("EnSsh_Bob",),
+ 0x80974A24:("EnSsh_IsCloseToLink",),
+ 0x80974B0C:("EnSsh_IsCloseToHome",),
+ 0x80974B44:("EnSsh_IsCloseToGround",),
+ 0x80974B84:("EnSsh_Sway",),
+ 0x80974CC8:("EnSsh_CheckBodyStickHit",),
+ 0x80974D3C:("EnSsh_CheckHitPlayer",),
+ 0x80974E44:("EnSsh_CheckHitFront",),
+ 0x80974EA0:("EnSsh_CheckHitBack",),
+ 0x80974F78:("EnSsh_CollisionCheck",),
+ 0x8097502C:("EnSsh_SetBodyCylinderAC",),
+ 0x80975070:("EnSsh_SetLegsCylinderAC",),
+ 0x80975128:("EnSsh_SetCylinderOC",),
+ 0x80975300:("EnSsh_SetColliders",),
0x809753C8:("EnSsh_Init",),
0x80975540:("EnSsh_Destroy",),
- 0x809755C0:("func_809755C0",),
- 0x8097561C:("func_8097561C",),
+ 0x809755C0:("EnSsh_Wait",),
+ 0x8097561C:("EnSsh_Talk",),
0x809756D0:("func_809756D0",),
- 0x80975720:("func_80975720",),
- 0x809758B0:("func_809758B0",),
- 0x80975998:("func_80975998",),
- 0x80975A98:("func_80975A98",),
- 0x80975B6C:("func_80975B6C",),
- 0x80975C14:("func_80975C14",),
+ 0x80975720:("EnSsh_Idle",),
+ 0x809758B0:("EnSsh_Land",),
+ 0x80975998:("EnSsh_Drop",),
+ 0x80975A98:("EnSsh_Return",),
+ 0x80975B6C:("EnSsh_UpdateColliderScale",),
+ 0x80975C14:("EnSsh_Start",),
0x80975C9C:("EnSsh_Update",),
- 0x80975DBC:("func_80975DBC",),
- 0x80975EB8:("func_80975EB8",),
+ 0x80975DBC:("EnSsh_OverrideLimbDraw",),
+ 0x80975EB8:("EnSsh_PostLimbDraw",),
0x80975F38:("EnSsh_Draw",),
0x809764B0:("OceffWipe_Init",),
0x8097650C:("OceffWipe_Destroy",),
@@ -8678,8 +8678,8 @@
0x809A1E60:("EnZl4_Draw",),
0x809A2030:("EnMm2_Init",),
0x809A2070:("EnMm2_Destroy",),
- 0x809A2080:("func_809A2080",),
- 0x809A20FC:("func_809A20FC",),
+ 0x809A2080:("EnMm2_Reading",),
+ 0x809A20FC:("EnMm2_WaitForRead",),
0x809A2194:("EnMm2_Update",),
0x809A21B8:("EnMm2_Draw",),
0x809A2B60:("DoorSpiral_SetupAction",),
@@ -9375,8 +9375,8 @@
0x809ED45C:("func_809ED45C",),
0x809ED50C:("func_809ED50C",),
0x809ED8BC:("Boss04_Update",),
- 0x809EDCCC:("func_809EDCCC",),
- 0x809EDECC:("func_809EDECC",),
+ 0x809EDCCC:("Boss04_OverrideLimbDraw",),
+ 0x809EDECC:("Boss04_PostLimbDraw",),
0x809EDF58:("Boss04_Draw",),
0x809EE4E0:("func_809EE4E0",),
0x809EE668:("func_809EE668",),
@@ -9742,8 +9742,8 @@
0x80A15960:("EnGo_Destroy",),
0x80A159B0:("EnGo_Update",),
0x80A15B80:("func_80A15B80",),
- 0x80A15D04:("func_80A15D04",),
- 0x80A15E38:("func_80A15E38",),
+ 0x80A15D04:("EnGo_OverrideLimbDraw",),
+ 0x80A15E38:("EnGo_UnkDraw",),
0x80A15FEC:("func_80A15FEC",),
0x80A16D40:("func_80A16D40",),
0x80A16D6C:("func_80A16D6C",),
@@ -11100,10 +11100,10 @@
0x80A7BC70:("ObjEtcetera_Init",),
0x80A7BD80:("ObjEtcetera_Destroy",),
0x80A7BDC8:("ObjEtcetera_DoNormalOscillation",),
- 0x80A7BE8C:("ObjEtcetera_StartSmallFlutterAnimation",),
+ 0x80A7BE8C:("ObjEtcetera_StartRustleAnimation",),
0x80A7BF08:("ObjEtcetera_Idle",),
- 0x80A7C168:("ObjEtcetera_PlaySmallFlutterAnimation",),
- 0x80A7C1F0:("ObjEtcetera_DoIntenseOscillation",),
+ 0x80A7C168:("ObjEtcetera_PlayRustleAnimation",),
+ 0x80A7C1F0:("ObjEtcetera_DoBounceOscillation",),
0x80A7C308:("ObjEtcetera_Setup",),
0x80A7C5EC:("ObjEtcetera_Update",),
0x80A7C690:("ObjEtcetera_DrawIdle",),
@@ -12276,7 +12276,7 @@
0x80AD8A48:("func_80AD8A48",),
0x80AD8AF8:("func_80AD8AF8",),
0x80AD8BC0:("EnKame_Draw",),
- 0x80AD8CEC:("func_80AD8CEC",),
+ 0x80AD8CEC:("Enkame_OverrideLimbDraw",),
0x80AD8D64:("func_80AD8D64",),
0x80AD9240:("func_80AD9240",),
0x80AD92FC:("func_80AD92FC",),
@@ -12805,7 +12805,7 @@
0x80AFDD34:("EnColMan_Destroy",),
0x80AFDD60:("func_80AFDD60",),
0x80AFDE00:("func_80AFDE00",),
- 0x80AFDF00:("func_80AFDF00",),
+ 0x80AFDF00:("EnColMan_SetHeartPieceCollectedAndKill",),
0x80AFDF60:("func_80AFDF60",),
0x80AFDFB4:("func_80AFDFB4",),
0x80AFE234:("func_80AFE234",),
@@ -13021,8 +13021,8 @@
0x80B1137C:("EnGb2_Init",),
0x80B116E4:("EnGb2_Destroy",),
0x80B11710:("EnGb2_Update",),
- 0x80B1179C:("func_80B1179C",),
- 0x80B117FC:("func_80B117FC",),
+ 0x80B1179C:("EnGb2_OverrideLimbDraw",),
+ 0x80B117FC:("EnGb2_PostLimbDraw",),
0x80B11858:("EnGb2_Draw",),
0x80B11E60:("EnOnpuman_Init",),
0x80B11F18:("EnOnpuman_Destroy",),
@@ -16483,7 +16483,7 @@
0x80C00234:("func_80C00234",),
0x80C00284:("func_80C00284",),
0x80C00644:("EnBomjima_Update",),
- 0x80C007F4:("func_80C007F4",),
+ 0x80C007F4:("EnBomjima_OverrideLimbDraw",),
0x80C008B4:("EnBomjima_Draw",),
0x80C00EA0:("EnBomjimb_Init",),
0x80C01110:("EnBomjimb_Destroy",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index 608c3ea5e..ac13bf90a 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -398,7 +398,7 @@
0x801AE2DC:("D_801AE2DC","UNK_TYPE4","",0x4),
0x801AE2F0:("sEffectShieldParticleVertices","F3DVertex","[4]",0x40),
0x801AE330:("sEffectInfoTable","EffectInfo","[5]",0x64),
- 0x801AE3A0:("EffectSS2Info","EffectSsInfo","",0xc),
+ 0x801AE3A0:("sEffectSsInfo","EffectSsInfo","",0xc),
0x801AE3B0:("D_801AE3B0","Color_RGBA8","",0x4),
0x801AE3B4:("D_801AE3B4","Color_RGBA8","",0x4),
0x801AE3B8:("D_801AE3B8","Color_RGBA8","",0x4),
@@ -419,11 +419,9 @@
0x801AE480:("D_801AE480","Color_RGBA8","",0x4),
0x801AE484:("D_801AE484","Color_RGBA8","",0x4),
0x801AE488:("D_801AE488","Color_RGBA8","",0x4),
- 0x801AE489:("D_801AE489","UNK_TYPE1","",0x1),
- 0x801AE48A:("D_801AE48A","UNK_TYPE1","",0x1),
0x801AE48C:("D_801AE48C","Color_RGBA8","",0x4),
0x801AE490:("D_801AE490","Color_RGBA8","[4]",0x10),
- 0x801AE4A0:("particleOverlayTable","EffectSsOverlay","[39]",0x444),
+ 0x801AE4A0:("gParticleOverlayTable","EffectSsOverlay","[39]",0x444),
0x801AE8F0:("sFlagEntries","FlagSetEntry","[112]",0x8),
0x801AEC70:("sEntryIndex","s32","",0x4),
0x801AEC74:("sCurrentBit","u32","",0x4),
@@ -7530,12 +7528,11 @@
0x808FC670:("En_Fr_InitVars","UNK_TYPE1","",0x1),
0x8090CCB0:("En_Fishing_InitVars","UNK_TYPE1","",0x1),
0x8090CCD0:("D_8090CCD0","f32","",0x4),
- 0x8090CCD4:("D_8090CCD4","UNK_TYPE1","",0x1),
+ 0x8090CCD4:("D_8090CCD4","u8","",0x1),
0x8090CCD8:("D_8090CCD8","f32","",0x4),
- 0x8090CCDC:("D_8090CCDC","UNK_TYPE1","",0x1),
- 0x8090CCE4:("D_8090CCE4","UNK_TYPE4","",0x4),
- 0x8090CCE8:("D_8090CCE8","UNK_TYPE4","",0x4),
- 0x8090CCEC:("D_8090CCEC","UNK_TYPE1","",0x1),
+ 0x8090CCDC:("D_8090CCDC","Vec3f","",0xC),
+ 0x8090CCE8:("D_8090CCE8","f32","",0x4),
+ 0x8090CCEC:("sSinkingLureLocation","u8","",0x1),
0x8090CCF0:("D_8090CCF0","f32","",0x4),
0x8090CCF4:("D_8090CCF4","UNK_TYPE1","",0x1),
0x8090CCF8:("D_8090CCF8","UNK_TYPE2","",0x2),
@@ -7546,18 +7543,17 @@
0x8090CD0C:("D_8090CD0C","UNK_TYPE1","",0x1),
0x8090CD10:("D_8090CD10","UNK_TYPE1","",0x1),
0x8090CD14:("D_8090CD14","UNK_TYPE2","",0x2),
- 0x8090CD18:("D_8090CD18","UNK_TYPE1","",0x1),
- 0x8090CD1C:("D_8090CD1C","f32","",0x4),
+ 0x8090CD18:("sFishMouthOffset","Vec3f","",0xC),
0x8090CD24:("D_8090CD24","UNK_TYPE1","",0x1),
0x8090CD28:("D_8090CD28","f32","",0x4),
0x8090CD2C:("D_8090CD2C","f32","",0x4),
0x8090CD30:("D_8090CD30","f32","",0x4),
0x8090CD34:("D_8090CD34","f32","",0x4),
- 0x8090CD38:("D_8090CD38","UNK_TYPE4","",0x4),
+ 0x8090CD38:("D_8090CD38","f32","",0x4),
0x8090CD3C:("D_8090CD3C","f32","",0x4),
0x8090CD40:("D_8090CD40","f32","",0x4),
- 0x8090CD44:("D_8090CD44","UNK_TYPE2","",0x2),
- 0x8090CD48:("D_8090CD48","UNK_TYPE2","",0x2),
+ 0x8090CD44:("D_8090CD44","s16","",0x2),
+ 0x8090CD48:("D_8090CD48","s16","",0x2),
0x8090CD4C:("D_8090CD4C","UNK_TYPE1","",0x1),
0x8090CD50:("D_8090CD50","UNK_TYPE1","",0x1),
0x8090CD54:("D_8090CD54","UNK_TYPE1","",0x1),
@@ -7567,7 +7563,8 @@
0x8090CD8C:("D_8090CD8C","UNK_TYPE1","",0x1),
0x8090CF08:("D_8090CF08","UNK_TYPE1","",0x1),
0x8090CF18:("D_8090CF18","UNK_TYPE1","",0x1),
- 0x8090CF1C:("D_8090CF1C","UNK_TYPE4","",0x4),
+ 0x8090CF1C:("sZeroVec","Vec3f","",0xC),
+ 0x8090CF28:("D_8090CF28","Vec3f","",0xC),
0x8090CF34:("D_8090CF34","UNK_TYPE4","",0x4),
0x8090CF40:("D_8090CF40","UNK_TYPE4","",0x4),
0x8090CF4C:("D_8090CF4C","UNK_TYPE4","",0x4),
@@ -7581,14 +7578,14 @@
0x8090D508:("D_8090D508","UNK_TYPE1","",0x1),
0x8090D558:("D_8090D558","UNK_TYPE1","",0x1),
0x8090D5B0:("D_8090D5B0","UNK_TYPE4","",0x4),
- 0x8090D608:("D_8090D608","UNK_TYPE1","",0x1),
- 0x8090D614:("D_8090D614","UNK_TYPE1","",0x1),
- 0x8090D620:("D_8090D620","UNK_TYPE4","",0x4),
+ 0x8090D608:("sRodTipOffset","Vec3f","",0xC),
+ 0x8090D614:("D_8090D614","Vec3f","",0xC),
+ 0x8090D620:("D_8090D620","Vec3f","",0xC),
0x8090D62C:("D_8090D62C","UNK_TYPE1","",0x1),
0x8090D638:("D_8090D638","UNK_TYPE1","",0x1),
- 0x8090D644:("D_8090D644","UNK_TYPE1","",0x1),
- 0x8090D650:("D_8090D650","UNK_TYPE1","",0x1),
- 0x8090D65C:("D_8090D65C","UNK_TYPE1","",0x1),
+ 0x8090D644:("D_8090D644","s16","[5]",0xA),
+ 0x8090D650:("sStreamSoundPos","Vec3f","",0xC),
+ 0x8090D65C:("sSinkingLureLocationPos","Vec3s","[4]",0x18),
0x8090D674:("D_8090D674","UNK_TYPE1","",0x1),
0x8090D680:("D_8090D680","f32","",0x4),
0x8090D684:("D_8090D684","f32","",0x4),
@@ -7874,46 +7871,37 @@
0x809101C8:("D_809101C8","f32","",0x4),
0x809101CC:("D_809101CC","UNK_TYPE1","",0x1),
0x809101D0:("D_809101D0","UNK_TYPE1","",0x1),
- 0x809101D8:("D_809101D8","UNK_TYPE1","",0x1),
- 0x809101E8:("D_809101E8","UNK_TYPE1","",0x1),
- 0x80910B3C:("D_80910B3C","f32","",0x4),
- 0x80910B40:("D_80910B40","f32","",0x4),
- 0x80910B44:("D_80910B44","f32","",0x4),
- 0x80910B48:("D_80910B48","UNK_TYPE1","",0x1),
- 0x809114A8:("D_809114A8","UNK_TYPE1","",0x1),
- 0x80911E08:("D_80911E08","UNK_TYPE1","",0x1),
- 0x80911E14:("D_80911E14","UNK_TYPE1","",0x1),
- 0x80911E20:("D_80911E20","UNK_TYPE1","",0x1),
+ 0x809101D8:("sRodTipPos","Vec3f","",0xC),
+ 0x809101E8:("sReelLinePos","Vec3f","[200]",0x960),
+ 0x80910B48:("sReelLineRot","Vec3f","[200]",0x960),
+ 0x809114A8:("sReelLineUnk","Vec3f","[200]",0x960),
+ 0x80911E08:("sLureHookRefPos","Vec3f","[2]",0x18),
+ 0x80911E20:("sLureHookRotY","f32","[2]",0x8),
0x80911E28:("D_80911E28","UNK_TYPE1","",0x1),
- 0x80911E30:("D_80911E30","UNK_TYPE1","",0x1),
- 0x80911E3C:("D_80911E3C","UNK_TYPE1","",0x1),
+ 0x80911E30:("sSinkingLurePos","Vec3f","[20]",0xF0),
0x80911F20:("D_80911F20","UNK_TYPE1","",0x1),
- 0x80911F24:("D_80911F24","UNK_TYPE1","",0x1),
- 0x80911F28:("D_80911F28","f32","",0x4),
- 0x80911F2C:("D_80911F2C","f32","",0x4),
- 0x80911F30:("D_80911F30","UNK_TYPE1","",0x1),
- 0x80911F38:("D_80911F38","f32","",0x4),
- 0x80911F3C:("D_80911F3C","f32","",0x4),
- 0x80911F40:("D_80911F40","f32","",0x4),
- 0x80911F44:("D_80911F44","UNK_TYPE1","",0x1),
+ 0x80911F24:("sProjectedW","f32","",0x4),
+ 0x80911F28:("sCameraEye","Vec3f","",0xC),
+ 0x80911F38:("sCameraAt","Vec3f","",0xC),
+ 0x80911F44:("sCameraId","s32","",0x4),
0x80911F48:("D_80911F48","f32","",0x4),
0x80911F4C:("D_80911F4C","f32","",0x4),
0x80911F50:("D_80911F50","UNK_TYPE1","",0x1),
- 0x80911F58:("D_80911F58","UNK_TYPE1","",0x1),
+ 0x80911F58:("sSinkingLureBasePos","Vec3f","",0xC),
0x80911F64:("D_80911F64","f32","",0x4),
- 0x80911F68:("D_80911F68","UNK_TYPE1","",0x1),
- 0x80911F6C:("D_80911F6C","UNK_TYPE1","",0x1),
- 0x80911F70:("D_80911F70","UNK_TYPE1","",0x1),
- 0x80911F78:("D_80911F78","UNK_TYPE1","",0x1),
- 0x80914048:("D_80914048","UNK_TYPE1","",0x1),
- 0x80915128:("D_80915128","f32","",0x4),
- 0x8091512C:("D_8091512C","f32","",0x4),
- 0x80915130:("D_80915130","UNK_TYPE1","",0x1),
- 0x80915138:("D_80915138","UNK_TYPE1","",0x1),
- 0x809171B8:("D_809171B8","UNK_TYPE1","",0x1),
- 0x809171C4:("D_809171C4","UNK_TYPE1","",0x1),
+ 0x80911F68:("sRandSeed0","s32","",0x4),
+ 0x80911F6C:("sRandSeed1","s32","",0x4),
+ 0x80911F70:("sRandSeed2","s32","",0x4),
+ 0x80911F78:("sPondProps","UNK_TYPE1","[140]",0x20D0),
+ 0x80914048:("sGroupFishes","UNK_TYPE1","[60]",0x10E0),
+ 0x80915128:("sFishGroupAngle1","f32","",0x4),
+ 0x8091512C:("sFishGroupAngle2","f32","",0x4),
+ 0x80915130:("sFishGroupAngle3","f32","",0x4),
+ 0x80915138:("sFishingEffects","UNK_TYPE1","[130]",0x2080),
+ 0x809171B8:("sStreamSoundProjectedPos","Vec3f","",0xC),
+ 0x809171C4:("sFishingMain","UNK_TYPE","",0x4),
0x809171C8:("D_809171C8","UNK_TYPE1","",0x1),
- 0x809171C9:("D_809171C9","UNK_TYPE1","",0x1),
+ 0x809171C9:("sLinkAge","UNK_TYPE1","",0x1),
0x809171CA:("D_809171CA","UNK_TYPE1","",0x1),
0x809171CB:("D_809171CB","UNK_TYPE1","",0x1),
0x809171CC:("D_809171CC","f32","",0x4),
@@ -7925,29 +7913,23 @@
0x809171D8:("D_809171D8","UNK_TYPE1","",0x1),
0x809171DA:("D_809171DA","UNK_TYPE1","",0x1),
0x809171DC:("D_809171DC","UNK_TYPE1","",0x1),
- 0x809171E0:("D_809171E0","UNK_TYPE1","",0x1),
- 0x809171EC:("D_809171EC","UNK_TYPE1","",0x1),
- 0x809171EE:("D_809171EE","UNK_TYPE1","",0x1),
- 0x809171F0:("D_809171F0","UNK_TYPE1","",0x1),
+ 0x809171E0:("sOwnerHeadPos","Vec3f","",0xC),
+ 0x809171EC:("sEffOwnerHatRot","Vec3s","",0x6),
0x809171F2:("D_809171F2","UNK_TYPE1","",0x1),
0x809171F4:("D_809171F4","UNK_TYPE1","",0x1),
0x809171F6:("D_809171F6","UNK_TYPE1","",0x1),
- 0x809171F8:("D_809171F8","UNK_TYPE1","",0x1),
+ 0x809171F8:("sFishingHookedFish","UNK_TYPE","",0x4),
0x809171FC:("D_809171FC","UNK_TYPE1","",0x1),
0x809171FE:("D_809171FE","UNK_TYPE1","",0x1),
0x80917200:("D_80917200","UNK_TYPE1","",0x1),
0x80917202:("D_80917202","UNK_TYPE1","",0x1),
0x80917204:("D_80917204","UNK_TYPE1","",0x1),
0x80917206:("D_80917206","UNK_TYPE1","",0x1),
- 0x80917208:("D_80917208","f32","",0x4),
- 0x8091720C:("D_8091720C","f32","",0x4),
- 0x80917210:("D_80917210","UNK_TYPE1","",0x1),
+ 0x80917208:("sLurePos","Vec3f","",0xC),
0x80917218:("D_80917218","UNK_TYPE1","",0x1),
- 0x80917228:("D_80917228","UNK_TYPE1","",0x1),
- 0x8091722C:("D_8091722C","UNK_TYPE1","",0x1),
- 0x80917238:("D_80917238","UNK_TYPE1","",0x1),
- 0x8091723C:("D_8091723C","UNK_TYPE1","",0x1),
- 0x80917248:("D_80917248","UNK_TYPE1","",0x1),
+ 0x80917228:("sLureRot","Vec3f","",0xC),
+ 0x80917238:("D_80917238","Vec3f","",0xC),
+ 0x80917248:("D_80917248","Vec3f","",0xC),
0x80917254:("D_80917254","f32","",0x4),
0x80917258:("D_80917258","UNK_TYPE1","",0x1),
0x8091725C:("D_8091725C","f32","",0x4),
@@ -7959,8 +7941,7 @@
0x80917270:("D_80917270","UNK_TYPE1","",0x1),
0x80917272:("D_80917272","UNK_TYPE1","",0x1),
0x80917274:("D_80917274","UNK_TYPE1","",0x1),
- 0x80917278:("D_80917278","UNK_TYPE1","",0x1),
- 0x8091727C:("D_8091727C","UNK_TYPE1","",0x1),
+ 0x80917278:("D_80917278","Vec3f","",0xC),
0x80918830:("Obj_Oshihiki_InitVars","UNK_TYPE1","",0x1),
0x80918850:("D_80918850","UNK_TYPE1","",0x1),
0x80918868:("D_80918868","UNK_TYPE1","",0x1),
@@ -12034,10 +12015,8 @@
0x80A5EAFE:("D_80A5EAFE","UNK_TYPE2","",0x2),
0x80A5EB00:("D_80A5EB00","UNK_TYPE2","",0x2),
0x80A5EB04:("D_80A5EB04","UNK_TYPE2","",0x2),
- 0x80A5EB0C:("D_80A5EB0C","f32","",0x4),
- 0x80A5EB14:("D_80A5EB14","f32","",0x4),
- 0x80A5EB18:("D_80A5EB18","f32","",0x4),
- 0x80A5EB20:("D_80A5EB20","f32","",0x4),
+ 0x80A5EB0C:("D_80A5EB0C","Vec3f","",0xC),
+ 0x80A5EB18:("D_80A5EB18","Vec3f","",0xC),
0x80A5EB24:("D_80A5EB24","UNK_TYPE1","",0x1),
0x80A5EB48:("D_80A5EB48","UNK_TYPE4","",0x4),
0x80A5EB4C:("D_80A5EB4C","UNK_TYPE1","",0x1),
diff --git a/tools/filelists/mm.us.rev1/interface.csv b/tools/filelists/mm.us.rev1/interface.csv
index db78965de..726df5467 100644
--- a/tools/filelists/mm.us.rev1/interface.csv
+++ b/tools/filelists/mm.us.rev1/interface.csv
@@ -9,3 +9,5 @@
26,message_static
27,message_texture_static
28,nes_font_static
+1126,parameter_static
+1127,week_static
diff --git a/tools/filelists/mm.us.rev1/misc.csv b/tools/filelists/mm.us.rev1/misc.csv
index caebc3bb1..1d2c8bfa3 100644
--- a/tools/filelists/mm.us.rev1/misc.csv
+++ b/tools/filelists/mm.us.rev1/misc.csv
@@ -12,8 +12,6 @@
1123,title_static
1124,memerrmsg
1125,locerrmsg
-1126,parameter_static
-1127,week_static
1128,daytelop_static
1129,ger_daytelop_static
1130,fra_daytelop_static
@@ -21,4 +19,3 @@
1132,d2_fine_static
1133,d2_cloud_static
1134,d2_fine_pal_static
-1538,bump_texture_static
diff --git a/tools/filelists/mm.us.rev1/segments.csv b/tools/filelists/mm.us.rev1/segments.csv
index b22534d94..4362b8db6 100644
--- a/tools/filelists/mm.us.rev1/segments.csv
+++ b/tools/filelists/mm.us.rev1/segments.csv
@@ -1,4 +1,5 @@
652,gameplay_object_exchange_static
+1538,bump_texture_static
1539,anime_model_1_static
1540,anime_model_2_static
1541,anime_model_3_static
diff --git a/tools/ido_recomp/linux/5.3/as1 b/tools/ido_recomp/linux/5.3/as1
index 17ff2aa7c..41c2545af 100755
Binary files a/tools/ido_recomp/linux/5.3/as1 and b/tools/ido_recomp/linux/5.3/as1 differ
diff --git a/tools/ido_recomp/linux/5.3/cc b/tools/ido_recomp/linux/5.3/cc
index 6dbb85eb1..3dcc53798 100755
Binary files a/tools/ido_recomp/linux/5.3/cc and b/tools/ido_recomp/linux/5.3/cc differ
diff --git a/tools/ido_recomp/linux/5.3/cfe b/tools/ido_recomp/linux/5.3/cfe
index d742f7b2e..e9594fafc 100755
Binary files a/tools/ido_recomp/linux/5.3/cfe and b/tools/ido_recomp/linux/5.3/cfe differ
diff --git a/tools/ido_recomp/linux/5.3/ugen b/tools/ido_recomp/linux/5.3/ugen
index 692086f0c..b2b662f1d 100755
Binary files a/tools/ido_recomp/linux/5.3/ugen and b/tools/ido_recomp/linux/5.3/ugen differ
diff --git a/tools/ido_recomp/linux/5.3/ujoin b/tools/ido_recomp/linux/5.3/ujoin
new file mode 100644
index 000000000..f9c90b8be
Binary files /dev/null and b/tools/ido_recomp/linux/5.3/ujoin differ
diff --git a/tools/ido_recomp/linux/5.3/uld b/tools/ido_recomp/linux/5.3/uld
new file mode 100644
index 000000000..f227222bc
Binary files /dev/null and b/tools/ido_recomp/linux/5.3/uld differ
diff --git a/tools/ido_recomp/linux/5.3/umerge b/tools/ido_recomp/linux/5.3/umerge
new file mode 100644
index 000000000..00a8281d2
Binary files /dev/null and b/tools/ido_recomp/linux/5.3/umerge differ
diff --git a/tools/ido_recomp/linux/5.3/uopt b/tools/ido_recomp/linux/5.3/uopt
index 49558be9f..5afe7a11c 100755
Binary files a/tools/ido_recomp/linux/5.3/uopt and b/tools/ido_recomp/linux/5.3/uopt differ
diff --git a/tools/ido_recomp/linux/5.3/usplit b/tools/ido_recomp/linux/5.3/usplit
new file mode 100644
index 000000000..a1c5ebad6
Binary files /dev/null and b/tools/ido_recomp/linux/5.3/usplit differ
diff --git a/tools/ido_recomp/linux/7.1/as1 b/tools/ido_recomp/linux/7.1/as1
index a7bb3adc3..01dbc6f6b 100755
Binary files a/tools/ido_recomp/linux/7.1/as1 and b/tools/ido_recomp/linux/7.1/as1 differ
diff --git a/tools/ido_recomp/linux/7.1/cc b/tools/ido_recomp/linux/7.1/cc
index e926b545e..a7f06afa8 100755
Binary files a/tools/ido_recomp/linux/7.1/cc and b/tools/ido_recomp/linux/7.1/cc differ
diff --git a/tools/ido_recomp/linux/7.1/cfe b/tools/ido_recomp/linux/7.1/cfe
index 3a3e98313..2c6767e69 100755
Binary files a/tools/ido_recomp/linux/7.1/cfe and b/tools/ido_recomp/linux/7.1/cfe differ
diff --git a/tools/ido_recomp/linux/7.1/ugen b/tools/ido_recomp/linux/7.1/ugen
index e8e875635..f5c1a2e20 100755
Binary files a/tools/ido_recomp/linux/7.1/ugen and b/tools/ido_recomp/linux/7.1/ugen differ
diff --git a/tools/ido_recomp/linux/7.1/umerge b/tools/ido_recomp/linux/7.1/umerge
new file mode 100644
index 000000000..b0c8c1778
Binary files /dev/null and b/tools/ido_recomp/linux/7.1/umerge differ
diff --git a/tools/ido_recomp/linux/7.1/uopt b/tools/ido_recomp/linux/7.1/uopt
index fd93d2dc5..ecf7eab72 100755
Binary files a/tools/ido_recomp/linux/7.1/uopt and b/tools/ido_recomp/linux/7.1/uopt differ
diff --git a/tools/ido_recomp/macos/5.3/acpp b/tools/ido_recomp/macos/5.3/acpp
new file mode 100755
index 000000000..043162770
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/acpp differ
diff --git a/tools/ido_recomp/macos/5.3/as0 b/tools/ido_recomp/macos/5.3/as0
new file mode 100755
index 000000000..9cff1dcd7
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/as0 differ
diff --git a/tools/ido_recomp/macos/5.3/as1 b/tools/ido_recomp/macos/5.3/as1
index 692fe600c..df0142e86 100755
Binary files a/tools/ido_recomp/macos/5.3/as1 and b/tools/ido_recomp/macos/5.3/as1 differ
diff --git a/tools/ido_recomp/macos/5.3/cc b/tools/ido_recomp/macos/5.3/cc
index 90ffc7409..e9b599bda 100755
Binary files a/tools/ido_recomp/macos/5.3/cc and b/tools/ido_recomp/macos/5.3/cc differ
diff --git a/tools/ido_recomp/macos/5.3/cfe b/tools/ido_recomp/macos/5.3/cfe
index 753be0d6c..30e514947 100755
Binary files a/tools/ido_recomp/macos/5.3/cfe and b/tools/ido_recomp/macos/5.3/cfe differ
diff --git a/tools/ido_recomp/macos/5.3/copt b/tools/ido_recomp/macos/5.3/copt
new file mode 100755
index 000000000..243c37a29
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/copt differ
diff --git a/tools/ido_recomp/macos/5.3/err.english.cc b/tools/ido_recomp/macos/5.3/err.english.cc
old mode 100755
new mode 100644
diff --git a/tools/ido_recomp/macos/5.3/ugen b/tools/ido_recomp/macos/5.3/ugen
index c7020aa49..7f18bf44b 100755
Binary files a/tools/ido_recomp/macos/5.3/ugen and b/tools/ido_recomp/macos/5.3/ugen differ
diff --git a/tools/ido_recomp/macos/5.3/ujoin b/tools/ido_recomp/macos/5.3/ujoin
new file mode 100755
index 000000000..30503f95d
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/ujoin differ
diff --git a/tools/ido_recomp/macos/5.3/uld b/tools/ido_recomp/macos/5.3/uld
new file mode 100755
index 000000000..13aa261f5
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/uld differ
diff --git a/tools/ido_recomp/macos/5.3/umerge b/tools/ido_recomp/macos/5.3/umerge
new file mode 100755
index 000000000..c31c866d5
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/umerge differ
diff --git a/tools/ido_recomp/macos/5.3/uopt b/tools/ido_recomp/macos/5.3/uopt
index e23f6beda..7bbaac298 100755
Binary files a/tools/ido_recomp/macos/5.3/uopt and b/tools/ido_recomp/macos/5.3/uopt differ
diff --git a/tools/ido_recomp/macos/5.3/usplit b/tools/ido_recomp/macos/5.3/usplit
new file mode 100755
index 000000000..a95984803
Binary files /dev/null and b/tools/ido_recomp/macos/5.3/usplit differ
diff --git a/tools/ido_recomp/macos/7.1/as1 b/tools/ido_recomp/macos/7.1/as1
index 358712e33..88b9f1f7e 100755
Binary files a/tools/ido_recomp/macos/7.1/as1 and b/tools/ido_recomp/macos/7.1/as1 differ
diff --git a/tools/ido_recomp/macos/7.1/cc b/tools/ido_recomp/macos/7.1/cc
index fb6810347..ae54cdbcd 100755
Binary files a/tools/ido_recomp/macos/7.1/cc and b/tools/ido_recomp/macos/7.1/cc differ
diff --git a/tools/ido_recomp/macos/7.1/cfe b/tools/ido_recomp/macos/7.1/cfe
index 1e1322862..6c468c336 100755
Binary files a/tools/ido_recomp/macos/7.1/cfe and b/tools/ido_recomp/macos/7.1/cfe differ
diff --git a/tools/ido_recomp/macos/7.1/err.english.cc b/tools/ido_recomp/macos/7.1/err.english.cc
old mode 100755
new mode 100644
diff --git a/tools/ido_recomp/macos/7.1/ugen b/tools/ido_recomp/macos/7.1/ugen
index fe90904a4..3fa7d48fc 100755
Binary files a/tools/ido_recomp/macos/7.1/ugen and b/tools/ido_recomp/macos/7.1/ugen differ
diff --git a/tools/ido_recomp/macos/7.1/umerge b/tools/ido_recomp/macos/7.1/umerge
new file mode 100755
index 000000000..3a9d5440c
Binary files /dev/null and b/tools/ido_recomp/macos/7.1/umerge differ
diff --git a/tools/ido_recomp/macos/7.1/uopt b/tools/ido_recomp/macos/7.1/uopt
index bb68f5d53..b025fa2c5 100755
Binary files a/tools/ido_recomp/macos/7.1/uopt and b/tools/ido_recomp/macos/7.1/uopt differ
diff --git a/tools/rename_sym.sh b/tools/rename_sym.sh
index e68966ca7..227db4df7 100755
--- a/tools/rename_sym.sh
+++ b/tools/rename_sym.sh
@@ -10,4 +10,4 @@ fi
#echo "Replace $1 with $2?"
#read
-grep -rl "$1" asm/**/*.s src/**/*.{c,h} include/**/*.h tools/disasm/functions.txt tools/disasm/variables.txt | xargs sed -i "s/\b$1\b/$2/g"
\ No newline at end of file
+grep -rl "$1" asm/**/*.s src/**/*.{c,h} include/**/*.h tools/disasm/functions.txt tools/disasm/variables.txt tools/sizes/*.csv | xargs sed -i "s/\b$1\b/$2/g"
diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv
index 02824b114..4b4eb72f3 100644
--- a/tools/sizes/code_functions.csv
+++ b/tools/sizes/code_functions.csv
@@ -2169,7 +2169,7 @@ asm/non_matchings/code/z_snap/func_8013A46C.s,func_8013A46C,0x8013A46C,0x16
asm/non_matchings/code/z_snap/func_8013A4C4.s,func_8013A4C4,0x8013A4C4,0x10
asm/non_matchings/code/z_snap/func_8013A504.s,func_8013A504,0x8013A504,0xB
asm/non_matchings/code/z_snap/func_8013A530.s,func_8013A530,0x8013A530,0xA4
-asm/non_matchings/code/z_sub_s/func_8013A7C0.s,func_8013A7C0,0x8013A7C0,0x28
+asm/non_matchings/code/z_sub_s/SubS_FindDoor.s,SubS_FindDoor,0x8013A7C0,0x28
asm/non_matchings/code/z_sub_s/func_8013A860.s,func_8013A860,0x8013A860,0xA8
asm/non_matchings/code/z_sub_s/func_8013AB00.s,func_8013AB00,0x8013AB00,0x9B
asm/non_matchings/code/z_sub_s/func_8013AD6C.s,func_8013AD6C,0x8013AD6C,0xC
@@ -2182,7 +2182,7 @@ asm/non_matchings/code/z_sub_s/func_8013B350.s,func_8013B350,0x8013B350,0xD8
asm/non_matchings/code/z_sub_s/func_8013B6B0.s,func_8013B6B0,0x8013B6B0,0x72
asm/non_matchings/code/z_sub_s/func_8013B878.s,func_8013B878,0x8013B878,0xAF
asm/non_matchings/code/z_sub_s/func_8013BB34.s,func_8013BB34,0x8013BB34,0x12
-asm/non_matchings/code/z_sub_s/func_8013BB7C.s,func_8013BB7C,0x8013BB7C,0x3C
+asm/non_matchings/code/z_sub_s/SubS_FindNearestActor.s,SubS_FindNearestActor,0x8013BB7C,0x3C
asm/non_matchings/code/z_sub_s/func_8013BC6C.s,func_8013BC6C,0x8013BC6C,0x35
asm/non_matchings/code/z_sub_s/func_8013BD40.s,func_8013BD40,0x8013BD40,0x67
asm/non_matchings/code/z_sub_s/func_8013BEDC.s,func_8013BEDC,0x8013BEDC,0x63
@@ -2203,7 +2203,7 @@ asm/non_matchings/code/z_sub_s/func_8013D768.s,func_8013D768,0x8013D768,0x35
asm/non_matchings/code/z_sub_s/func_8013D83C.s,func_8013D83C,0x8013D83C,0x28
asm/non_matchings/code/z_sub_s/func_8013D8DC.s,func_8013D8DC,0x8013D8DC,0x12
asm/non_matchings/code/z_sub_s/func_8013D924.s,func_8013D924,0x8013D924,0xF
-asm/non_matchings/code/z_sub_s/func_ActorCategoryIterateById.s,func_ActorCategoryIterateById,0x8013D960,0x1A
+asm/non_matchings/code/z_sub_s/SubS_FindActor.s,SubS_FindActor,0x8013D960,0x1A
asm/non_matchings/code/z_sub_s/func_8013D9C8.s,func_8013D9C8,0x8013D9C8,0x72
asm/non_matchings/code/z_sub_s/func_8013DB90.s,func_8013DB90,0x8013DB90,0x2C
asm/non_matchings/code/z_sub_s/func_8013DC40.s,func_8013DC40,0x8013DC40,0x23
@@ -2219,7 +2219,7 @@ asm/non_matchings/code/z_sub_s/func_8013E2D4.s,func_8013E2D4,0x8013E2D4,0x39
asm/non_matchings/code/z_sub_s/func_8013E3B8.s,func_8013E3B8,0x8013E3B8,0x3E
asm/non_matchings/code/z_sub_s/func_8013E4B0.s,func_8013E4B0,0x8013E4B0,0x47
asm/non_matchings/code/z_sub_s/func_8013E5CC.s,func_8013E5CC,0x8013E5CC,0x1D
-asm/non_matchings/code/z_sub_s/func_8013E640.s,func_8013E640,0x8013E640,0x42
+asm/non_matchings/code/z_sub_s/SubS_FindActorCustom.s,SubS_FindActorCustom,0x8013E640,0x42
asm/non_matchings/code/z_sub_s/func_8013E748.s,func_8013E748,0x8013E748,0x1E
asm/non_matchings/code/z_sub_s/func_8013E7C0.s,func_8013E7C0,0x8013E7C0,0x4E
asm/non_matchings/code/z_sub_s/func_8013E8F8.s,func_8013E8F8,0x8013E8F8,0x16
diff --git a/undefined_syms.txt b/undefined_syms.txt
index b20f97bd7..5fe1bfcac 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -1087,13 +1087,6 @@ D_06009C14 = 0x06009C14;
D_06009CF8 = 0x06009CF8;
D_0600A6C8 = 0x0600A6C8;
-// ovl_Boss_04
-
-D_0600004C = 0x0600004C;
-D_06004510 = 0x06004510;
-D_06004550 = 0x06004550;
-D_060045E8 = 0x060045E8;
-
// ovl_Boss_05
D_060006A4 = 0x060006A4;
@@ -1488,6 +1481,7 @@ D_06013EA8 = 0x06013EA8;
// ovl_Door_Warp1
+D_06003230 = 0x06003230;
D_060044D8 = 0x060044D8;
D_06004690 = 0x06004690;
D_060057D8 = 0x060057D8;
@@ -1696,7 +1690,7 @@ D_06000340 = 0x06000340;
D_06000408 = 0x06000408;
D_06000530 = 0x06000530;
-// ovl_En_Bomjima
+// ovl_En_Bomjimb
D_060064B8 = 0x060064B8;
D_0600F82C = 0x0600F82C;
@@ -2211,48 +2205,8 @@ D_06006190 = 0x06006190;
// ovl_En_Fishing
-D_0600007C = 0x0600007C;
-D_060029C0 = 0x060029C0;
-D_06003230 = 0x06003230;
-D_06003460 = 0x06003460;
-D_060034C0 = 0x060034C0;
-D_06003610 = 0x06003610;
-D_06003680 = 0x06003680;
-D_06003710 = 0x06003710;
-D_06003760 = 0x06003760;
-D_060039A8 = 0x060039A8;
-D_06003A18 = 0x06003A18;
-D_0600453C = 0x0600453C;
-D_06007350 = 0x06007350;
-D_060074C8 = 0x060074C8;
-D_060085F8 = 0x060085F8;
-D_06008610 = 0x06008610;
-D_06008678 = 0x06008678;
-D_060088C0 = 0x060088C0;
-D_06008970 = 0x06008970;
-D_0600B950 = 0x0600B950;
-D_0600B9C0 = 0x0600B9C0;
-D_0600C220 = 0x0600C220;
-D_0600C298 = 0x0600C298;
D_0600CFE0 = 0x0600CFE0;
D_06011058 = 0x06011058;
-D_06011070 = 0x06011070;
-D_06011170 = 0x06011170;
-D_06011270 = 0x06011270;
-D_060113D0 = 0x060113D0;
-D_06011410 = 0x06011410;
-D_06012160 = 0x06012160;
-D_060121F0 = 0x060121F0;
-D_06013330 = 0x06013330;
-D_060133B0 = 0x060133B0;
-D_06013590 = 0x06013590;
-D_06013610 = 0x06013610;
-D_06013F50 = 0x06013F50;
-D_06013FD0 = 0x06013FD0;
-D_06014030 = 0x06014030;
-D_060140B0 = 0x060140B0;
-D_060153D0 = 0x060153D0;
-D_06015470 = 0x06015470;
// ovl_En_Floormas
@@ -2317,11 +2271,6 @@ D_060015C0 = 0x060015C0;
D_060023D4 = 0x060023D4;
D_06002720 = 0x06002720;
-// ovl_En_Gb2
-
-D_0600049C = 0x0600049C;
-D_06007230 = 0x06007230;
-
// ovl_En_Ge1
D_06002B98 = 0x06002B98;
@@ -2352,30 +2301,6 @@ D_0600F6C0 = 0x0600F6C0;
D_0600F578 = 0x0600F578;
D_0600F6C0 = 0x0600F6C0;
-// ovl_En_Giant
-
-D_06002168 = 0x06002168;
-D_06005A80 = 0x06005A80;
-D_06006280 = 0x06006280;
-D_06006A80 = 0x06006A80;
-D_06007610 = 0x06007610;
-D_060079B0 = 0x060079B0;
-D_06008394 = 0x06008394;
-D_060096E4 = 0x060096E4;
-D_0600A1C4 = 0x0600A1C4;
-D_0600ACA4 = 0x0600ACA4;
-D_0600B784 = 0x0600B784;
-D_0600C5D4 = 0x0600C5D4;
-D_0600D040 = 0x0600D040;
-D_0600DE84 = 0x0600DE84;
-D_060102A4 = 0x060102A4;
-D_060116E4 = 0x060116E4;
-D_06012A38 = 0x06012A38;
-D_06013004 = 0x06013004;
-D_06013FE8 = 0x06013FE8;
-D_06015334 = 0x06015334;
-D_06017944 = 0x06017944;
-
// ovl_En_Ginko_Man
D_060008C0 = 0x060008C0;
@@ -2414,22 +2339,6 @@ D_0600B990 = 0x0600B990;
D_0600BA80 = 0x0600BA80;
D_0600C03C = 0x0600C03C;
-// ovl_En_Go
-
-D_060003D0 = 0x060003D0;
-D_06000458 = 0x06000458;
-D_060008C0 = 0x060008C0;
-D_06000948 = 0x06000948;
-D_06000D50 = 0x06000D50;
-D_06000DD8 = 0x06000DD8;
-D_06001560 = 0x06001560;
-D_060031A0 = 0x060031A0;
-D_06003258 = 0x06003258;
-D_060091A8 = 0x060091A8;
-D_06011AC8 = 0x06011AC8;
-D_06014CF0 = 0x06014CF0;
-D_06014D00 = 0x06014D00;
-
// ovl_En_Goroiwa
D_060032E0 = 0x060032E0;
@@ -2691,10 +2600,6 @@ D_06012FC8 = 0x06012FC8;
D_06013928 = 0x06013928;
D_06016588 = 0x06016588;
-// ovl_En_Ishi
-
-D_060009B0 = 0x060009B0;
-
// ovl_En_Ja
D_0600BA30 = 0x0600BA30;
@@ -2754,23 +2659,6 @@ D_0600686C = 0x0600686C;
D_060081A4 = 0x060081A4;
D_06000214 = 0x06000214;
-// ovl_En_Kame
-
-D_060008B4 = 0x060008B4;
-D_06000AF4 = 0x06000AF4;
-D_06000B30 = 0x06000B30;
-D_06001A50 = 0x06001A50;
-D_06001C68 = 0x06001C68;
-D_06002510 = 0x06002510;
-D_060027D8 = 0x060027D8;
-D_06002F88 = 0x06002F88;
-D_060031DC = 0x060031DC;
-D_060035EC = 0x060035EC;
-D_060039C0 = 0x060039C0;
-D_06004210 = 0x06004210;
-D_06007C70 = 0x06007C70;
-D_0600823C = 0x0600823C;
-
// ovl_En_Kanban
D_06000C30 = 0x06000C30;
@@ -3179,14 +3067,6 @@ D_060073E8 = 0x060073E8;
D_0600D5A0 = 0x0600D5A0;
-// ovl_En_Peehat
-
-D_06000350 = 0x06000350;
-D_060005C4 = 0x060005C4;
-D_06000844 = 0x06000844;
-D_060009C4 = 0x060009C4;
-D_06001C80 = 0x06001C80;
-
// ovl_En_Pm
D_06008348 = 0x06008348;
@@ -3379,11 +3259,6 @@ D_06009220 = 0x06009220;
D_0600C700 = 0x0600C700;
-// ovl_En_Ruppecrow
-
-D_060000F0 = 0x060000F0;
-D_060010C0 = 0x060010C0;
-
// ovl_En_Rz
D_06003A20 = 0x06003A20;
@@ -3497,17 +3372,7 @@ D_06011038 = 0x06011038;
// ovl_En_Ssh
-D_060000D8 = 0x060000D8;
D_06000304 = 0x06000304;
-D_06001494 = 0x06001494;
-D_06005210 = 0x06005210;
-D_06005850 = 0x06005850;
-D_06005F78 = 0x06005F78;
-D_06006470 = 0x06006470;
-
-// ovl_En_St
-
-D_06005298 = 0x06005298;
// ovl_En_Sth
@@ -3530,10 +3395,6 @@ D_0600D640 = 0x0600D640;
D_06006C18 = 0x06006C18;
D_0600D640 = 0x0600D640;
-// ovl_En_Stream
-
-D_06000950 = 0x06000950;
-
// ovl_En_Suttari
D_0600071C = 0x0600071C;
@@ -3792,22 +3653,6 @@ D_0600A054 = 0x0600A054;
D_06000EC0 = 0x06000EC0;
-// ovl_En_Water_Effect
-
-D_06000420 = 0x06000420;
-D_06000730 = 0x06000730;
-D_06000A48 = 0x06000A48;
-D_06000CD8 = 0x06000CD8;
-D_06000DE0 = 0x06000DE0;
-D_06000E0C = 0x06000E0C;
-D_06000E40 = 0x06000E40;
-D_06000E58 = 0x06000E58;
-D_06004260 = 0x06004260;
-D_060042B0 = 0x060042B0;
-D_060042F8 = 0x060042F8;
-D_06004340 = 0x06004340;
-D_060043E8 = 0x060043E8;
-
// ovl_En_Wdhand
D_060000F4 = 0x060000F4;
@@ -3852,18 +3697,6 @@ D_06001690 = 0x06001690;
D_06005870 = 0x06005870;
D_06005C64 = 0x06005C64;
-// ovl_En_Wiz_Fire
-
-D_06000E70 = 0x06000E70;
-D_06000FD8 = 0x06000FD8;
-D_06002630 = 0x06002630;
-D_06002B40 = 0x06002B40;
-D_06003120 = 0x06003120;
-D_06003640 = 0x06003640;
-D_06003FC0 = 0x06003FC0;
-D_06005190 = 0x06005190;
-D_06005750 = 0x06005750;
-
// ovl_En_Wood02
D_06000700 = 0x06000700;
@@ -4063,13 +3896,6 @@ D_06003440 = 0x06003440;
D_06000158 = 0x06000158;
D_06001C00 = 0x06001C00;
-// ovl_Obj_Flowerpot
-
-D_060012E0 = 0x060012E0;
-D_06001408 = 0x06001408;
-D_060014F0 = 0x060014F0;
-D_060015B0 = 0x060015B0;
-
// ovl_Obj_Funen
D_060000D0 = 0x060000D0;
@@ -4112,14 +3938,6 @@ D_06001D10 = 0x06001D10;
D_060003B8 = 0x060003B8;
D_060011B0 = 0x060011B0;
-// ovl_Obj_Hugebombiwa
-
-D_060009E0 = 0x060009E0;
-D_06001820 = 0x06001820;
-D_06001990 = 0x06001990;
-D_06002F60 = 0x06002F60;
-D_06003110 = 0x06003110;
-
// ovl_Obj_Hunsui
D_06000220 = 0x06000220;
@@ -4146,17 +3964,6 @@ D_06000180 = 0x06000180;
D_06003478 = 0x06003478;
D_0600805C = 0x0600805C;
-// ovl_Obj_Kibako
-
-D_06001180 = 0x06001180;
-D_06001A70 = 0x06001A70;
-
-// ovl_Obj_Kibako2
-
-D_06000960 = 0x06000960;
-D_06000B70 = 0x06000B70;
-D_06001040 = 0x06001040;
-
// ovl_Obj_Kzsaku
D_06000040 = 0x06000040;
@@ -4228,11 +4035,6 @@ D_060011E0 = 0x060011E0;
D_06001C00 = 0x06001C00;
-// ovl_Obj_Snowball
-
-D_060082D0 = 0x060082D0;
-D_06008B90 = 0x06008B90;
-
// ovl_Obj_Snowball2
D_06008B90 = 0x06008B90;