diff --git a/assets/xml/objects/object_tru.xml b/assets/xml/objects/object_tru.xml
index 34bc82f39b..0ca1acff45 100644
--- a/assets/xml/objects/object_tru.xml
+++ b/assets/xml/objects/object_tru.xml
@@ -70,7 +70,9 @@
-
+
+
+
diff --git a/assets/xml/overlays/ovl_En_Tru.xml b/assets/xml/overlays/ovl_En_Tru.xml
new file mode 100644
index 0000000000..e242db4c34
--- /dev/null
+++ b/assets/xml/overlays/ovl_En_Tru.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/functions.h b/include/functions.h
index 9e4809bb81..1b0ee74c73 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -2162,7 +2162,7 @@ s32 func_80123590(GlobalContext* globalCtx, Actor* actor);
s32 func_80123810(GlobalContext* globalCtx);
// void func_80123960(void);
// void func_801239AC(void);
-// void func_80123AA4(void);
+void func_80123AA4(Player* player, s32 arg1);
// void func_80123BD4(void);
// void func_80123C58(void);
// void func_80123C90(void);
@@ -3012,7 +3012,7 @@ s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx);
// void func_8016A0AC(void);
s32 func_8016A168(void);
// void func_8016A178(void);
-// void func_8016A268(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6);
+void func_8016A268(GlobalContext* globalCtx, s32 param_2, s32 param_3, s32 param_4, s32 param_5, s32 param_6);
void Play_Init(GameState* gameState);
// void func_8016AC10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10);
// void func_8016AE1C(void);
@@ -3963,7 +3963,7 @@ void func_801A5CFC(u16 sfxId, Vec3f* param_2, u8 param_3, f32* param_4, f32* par
void func_801A72CC(Vec3f* uParm1);
void func_801A7328(Vec3f* pos, u16 sfxId);
// void func_801A7484(void);
-// void func_801A75E8(void);
+void func_801A75E8(u16 sfxId);
// void func_801A7720(void);
void func_801A7794(u32 param_1, u32 param_2, u32 param_3);
// void func_801A7828(void);
diff --git a/spec b/spec
index 7e142f3bba..3cbed2222b 100644
--- a/spec
+++ b/spec
@@ -3215,8 +3215,11 @@ beginseg
name "ovl_En_Tru"
compress
include "build/src/overlays/actors/ovl_En_Tru/z_en_tru.o"
- include "build/data/ovl_En_Tru/ovl_En_Tru.data.o"
- include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o"
+ #ifdef NON_MATCHING
+ include "build/src/overlays/actors/ovl_En_Tru/ovl_En_Tru_reloc.o"
+ #else
+ include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o"
+ #endif
endseg
beginseg
diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c
index 240a4f2363..4874ac2496 100644
--- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c
+++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c
@@ -5,6 +5,7 @@
*/
#include "z_en_tru.h"
+#include "objects/object_tru/object_tru.h"
#define FLAGS 0x00000039
@@ -15,10 +16,46 @@ void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnTru_Update(Actor* thisx, GlobalContext* globalCtx);
void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx);
+s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx);
+s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx);
+s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx);
+s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx);
+s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx);
void func_80A87FD0(EnTru* this, GlobalContext* globalCtx);
void func_80A881E0(EnTru* this, GlobalContext* globalCtx);
-#if 0
+static UNK_TYPE D_80A88910[] = {
+ 0x0E08520C,
+ 0x16100000,
+};
+
+static UNK_TYPE D_80A88918[] = {
+ 0x0900000E,
+ 0x08630C12,
+ 0x16100000,
+};
+
+static UNK_TYPE D_80A88924[] = {
+ 0x0E08660C,
+ 0x10000000,
+};
+
+static UNK_TYPE D_80A8892C[] = {
+ 0x09000004, 0x00050E08, 0x650C1000, 0x1010000B, 0x0E08530C, 0x0F08540C, 0x1900040E, 0x08560C11,
+ 0x10100E00, 0xFF2B0000, 0x001E0027, 0x2C08640C, 0x2F00000C, 0x15090000, 0x0E08570C, 0x15090000,
+ 0x0E08580C, 0x15090000, 0x12102C08, 0x550C2F00, 0x000C100E, 0x08550C10,
+};
+
+static UNK_TYPE D_80A88984[] = {
+ 0x2CFFFF09, 0x00000E08, 0x640C1509, 0x00000E08, 0x570C1509, 0x00000E08, 0x580C1509, 0x00001210,
+};
+
+static UNK_TYPE D_80A889A4[] = {
+ 0x2CFFFF09,
+ 0x00000E08,
+ 0x550C1000,
+};
+
const ActorInit En_Tru_InitVars = {
ACTOR_EN_TRU,
ACTORCAT_NPC,
@@ -31,91 +68,1193 @@ const ActorInit En_Tru_InitVars = {
(ActorFunc)EnTru_Draw,
};
-// static ColliderSphereInit sSphereInit = {
-static ColliderSphereInit D_80A8B2A0 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+#include "overlays/ovl_En_Tru/ovl_En_Tru.c"
+
+static Vec3f D_80A8B250 = { 0.0f, 0.02f, 0.0f };
+
+static Color_RGBA8 D_80A8B25C[] = {
+ { 255, 20, 60, 0 }, { 255, 235, 160, 0 }, { 20, 60, 255, 0 },
+ { 100, 100, 100, 0 }, { 255, 255, 200, 0 }, { 100, 100, 100, 0 },
+};
+
+static f32 D_80A8B274[] = { 60.0f, 255.0f, 60.0f };
+
+static UNK_TYPE D_80A8B280[] = {
+ &D_0408F7E0, &D_0408F3E0, &D_0408EFE0, &D_0408EBE0, &D_0408E7E0, &D_0408E3E0, &D_0408DFE0, &D_0408DBE0,
+};
+
+static ColliderSphereInit sSphereInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_SPHERE,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 0, { { 0, 0, 0 }, 32 }, 100 },
};
-// sColChkInfoInit
-static CollisionCheckInfoInit2 D_80A8B2CC = { 1, 20, 0, 0, MASS_IMMOVABLE };
+static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 20, 0, 0, MASS_IMMOVABLE };
+static ActorAnimationEntryS D_80A8B2D8[] = {
+ { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, -4 },
+ { &object_tru_Anim_0108AC, 1.0f, 0, -1, 2, -4 }, { &object_tru_Anim_009348, 1.0f, 0, -1, 2, 0 },
+ { &object_tru_Anim_00EEDC, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, 0 },
+ { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_014728, 1.0f, 0, -1, 2, 0 },
+ { &object_tru_Anim_01B5C4, 1.0f, 0, -1, 2, 0 }, { &object_tru_Anim_007FA0, 1.0f, 0, -1, 2, -4 },
+ { &object_tru_Anim_016B4C, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_011F88, 1.0f, 0, -1, 2, -4 },
+ { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_003698, 1.0f, 0, -1, 2, -4 },
+ { &object_tru_Anim_002BD8, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 },
+};
+
+static Vec3f D_80A8B3D8 = { 0.0f, 24.0f, 16.0f };
+static Vec3f D_80A8B3E4 = { 0.0f, -3.0f, 3.0f };
+static Vec3f D_80A8B3F0 = { 0.0f, 0.5f, 0.0f };
+static Vec3f D_80A8B3FC = { 3000.0f, -800.0f, 0.0f };
+
+void func_80A85620(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) {
+ s16 i;
+
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_00 == 0) {
+ arg0->unk_02 = Rand_ZeroFloat(20.0f) + arg4;
+ arg0->unk_01 = arg0->unk_02;
+ arg0->unk_00 = 1;
+ arg0->unk_04 = *arg1;
+ arg0->unk_1C = D_801D15B0;
+ arg0->unk_10 = D_80A8B250;
+ arg0->unk_28 = arg2;
+ arg0->unk_2C = arg3;
+ break;
+ }
+ }
+}
+
+void func_80A85788(EnTruUnkStruct* arg0, GlobalContext* globalCtx) {
+ s32 i;
+ s32 flag = false;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_00 == 1) {
+ f32 alpha;
+
+ if (!flag) {
+ gSPDisplayList(POLY_XLU_DISP++, D_80A89000);
+ flag = true;
+ }
+
+ do {
+ alpha = (f32)arg0->unk_02 / arg0->unk_01;
+ alpha *= 255.0f;
+ } while (0);
+
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)alpha);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -arg0->unk_02 * 5, 32, 64, 1, 0, 0, 32, 32));
+
+ Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY);
+ Matrix_InsertTranslation(0.0f, 14.0f, 0.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++, D_80A890A8);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A85AA4(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) {
+ s16 i;
+
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_00 == 0) {
+ arg0->unk_02 = arg4;
+ arg0->unk_01 = arg0->unk_02;
+ arg0->unk_00 = 2;
+ arg0->unk_04 = *arg1;
+ arg0->unk_1C = D_801D15B0;
+ arg0->unk_10 = D_801D15B0;
+ arg0->unk_28 = arg2;
+ arg0->unk_2C = arg3;
+ break;
+ }
+ }
+}
+
+void func_80A85BCC(EnTruUnkStruct* arg0, GlobalContext* globalCtx) {
+ s32 i;
+ s32 flag = false;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ if (globalCtx) {}
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_00 == 2) {
+ f32 alpha;
+
+ if (!flag) {
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 200, 0);
+ flag = true;
+ }
+
+ do {
+ alpha = (f32)arg0->unk_02 / arg0->unk_01;
+ alpha *= 255.0f;
+ } while (0);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)alpha);
+
+ Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW);
+ Matrix_NormalizeXYZ(&globalCtx->billboardMtxF);
+ Matrix_Scale(arg0->unk_28, arg0->unk_28, 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++, D_80A8A108);
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void func_80A85E2C(EnTruUnkStruct* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, f32 arg5, f32 arg6, u8 arg7) {
+ s32 i;
+
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_00 == 0) {
+ arg0->unk_02 = Rand_ZeroFloat(4.0f) + arg6;
+ arg0->unk_01 = arg0->unk_02;
+ arg0->unk_00 = arg7;
+ arg0->unk_04 = *arg1;
+ arg0->unk_1C = *arg3;
+ arg0->unk_10 = *arg2;
+ arg0->unk_28 = arg4;
+ arg0->unk_2C = arg5;
+ break;
+ }
+ }
+}
+
+#ifdef NON_MATCHING
+// s8/s6 flipped, same deal as above functions but the same fixes don't work
+void func_80A85F84(EnTruUnkStruct* arg0, GlobalContext* globalCtx) {
+ u8 flag = false;
+ s32 i;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ for (i = 0; i < 30; i++, arg0++) {
+ f32 alpha;
+ s32 idx;
+
+ if ((arg0->unk_00 == 3) || (arg0->unk_00 == 4) || (arg0->unk_00 == 5)) {
+ if (!flag) {
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, sizeof(Gfx) * 0);
+ gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A820);
+ flag = true;
+ }
+
+ Matrix_StatePush();
+
+ do {
+ alpha = (f32)arg0->unk_02 / arg0->unk_01;
+ alpha *= D_80A8B274[arg0->unk_00 - 3];
+ } while (0);
+
+ gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0,
+ COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED);
+ gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2);
+ gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING);
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g,
+ D_80A8B25C[arg0->unk_00 - 3].b, (u8)alpha);
+ gDPSetEnvColor(POLY_XLU_DISP++, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g,
+ D_80A8B25C[arg0->unk_00 - 3].b, 0);
+
+ Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW);
+ Matrix_Scale(arg0->unk_28, arg0->unk_28, 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);
+ idx = ((f32)arg0->unk_02 / arg0->unk_01) * 8.0f;
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B280[idx]));
+ gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A830);
+
+ Matrix_StatePop();
+ }
+ }
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s")
#endif
-extern ColliderSphereInit D_80A8B2A0;
-extern CollisionCheckInfoInit2 D_80A8B2CC;
+s32 func_80A86384(EnTruUnkStruct* arg0, Vec3f* arg1) {
+ s32 i;
-extern UNK_TYPE D_060020C8;
-extern UNK_TYPE D_0601A830;
-extern UNK_TYPE D_0601AA60;
+ for (i = 0; i < 30; i++, arg0++) {
+ if (arg0->unk_02 != 0) {
+ if (arg0->unk_00 == 2) {
+ arg0->unk_04 = *arg1;
+ } else {
+ arg0->unk_04.x += arg0->unk_1C.x;
+ arg0->unk_04.y += arg0->unk_1C.y;
+ arg0->unk_04.z += arg0->unk_1C.z;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85620.s")
+ arg0->unk_1C.x += arg0->unk_10.x;
+ arg0->unk_1C.y += arg0->unk_10.y;
+ arg0->unk_1C.z += arg0->unk_10.z;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85788.s")
+ arg0->unk_02--;
+ arg0->unk_28 += arg0->unk_2C;
+ } else {
+ arg0->unk_00 = 0;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85AA4.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85BCC.s")
+s32 func_80A86460(EnTru* this) {
+ s32 i;
+ Vec3f spB0;
+ Vec3f spA4;
+ Vec3f sp98;
+ Vec3f sp8C;
+ f32 temp_f6;
+ s16 phi_s1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85E2C.s")
+ Math_Vec3f_Copy(&spB0, &D_801D15B0);
+ Math_Vec3f_Copy(&sp8C, &D_801D15B0);
+ Math_Vec3f_Copy(&spA4, &D_801D15B0);
+ Math_Vec3f_Copy(&sp98, &D_801D15B0);
+ phi_s1 = (Rand_ZeroOne() * 360.0f) * 182.0f;
+ spB0.z = 20.0f;
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &spB0, &sp8C);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s")
+ for (i = 0; i < 8; i++, phi_s1 += 0x1FFE) {
+ Math_Vec3f_Copy(&spB0, &D_801D15B0);
+ spB0.y = 1.0f;
+ spB0.z = Rand_ZeroOne() + 3.0f;
+ Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, phi_s1, &spB0, &sp98);
+ Math_Vec3f_Copy(&spB0, &D_801D15B0);
+ spB0.z = (Rand_ZeroOne() * 4.0f) + 12.0f;
+ Lib_Vec3f_TranslateAndRotateY(&sp8C, phi_s1, &spB0, &spA4);
+ func_80A85E2C(this->unk_394, &spA4, &D_801D15B0, &sp98, 0.4f, 0.06f, 12.0f, 4);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86384.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86460.s")
+s32 func_80A86674(EnTru* this) {
+ s32 pad;
+ Vec3f sp40;
+ Vec3f sp34;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86674.s")
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &D_80A8B3D8, &sp40);
+ Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, this->actor.world.rot.y, &D_80A8B3E4, &sp34);
+ if (this->unk_390 == 1) {
+ func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 3);
+ } else if (this->unk_390 == 2) {
+ func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 5);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86770.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A868F8.s")
+s32 func_80A86770(EnTru* this) {
+ s32 pad;
+ Vec3f sp98;
+ Vec3f sp8C;
+ s32 i;
+ s16 phi_s0 = Rand_ZeroOne() * 360.0f * 182.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86924.s")
+ for (i = 0; i < 4; i++, phi_s0 += 0x3FFC) {
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, phi_s0, &D_801D15B0, &sp98);
+ sp98.y = this->actor.floorHeight + 1.0f;
+ sp8C.x = Rand_ZeroOne() - 0.5f;
+ sp8C.z = Rand_ZeroOne() - 0.5f;
+ sp8C.y = Rand_ZeroOne() * 0.2f;
+ func_80A85E2C(this->unk_394, &sp98, &sp8C, &D_801D15B0, 1.0f, 0.04f, 28.0f, 4);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8697C.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A869DC.s")
+void func_80A868F8(EnTru* this) {
+ this->skelAnime.playSpeed = this->unk_358;
+ SkelAnime_Update(&this->skelAnime);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86B0C.s")
+s32 func_80A86924(EnTru* this, s32 arg1) {
+ s32 ret = false;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86BAC.s")
+ if (arg1 != this->unk_37C) {
+ this->unk_37C = arg1;
+ ret = func_8013BC6C(&this->skelAnime, D_80A8B2D8, arg1);
+ this->unk_358 = this->skelAnime.playSpeed;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86DB8.s")
+ return ret;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A871E0.s")
+void func_80A8697C(EnTru* this, GlobalContext* globalCtx) {
+ this->collider.dim.worldSphere.radius = this->collider.dim.modelSphere.radius * this->collider.dim.scale;
+ if (this->actor.draw != NULL) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A872AC.s")
+s32 func_80A869DC(EnTru* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f sp38;
+ Vec3f sp2C;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A873B8.s")
+ Math_ApproachS(&this->unk_368, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 4, 0x2AA8);
+ this->unk_368 = CLAMP(this->unk_368, -0x1FFE, 0x1FFE);
+ Math_Vec3f_Copy(&sp38, &player->actor.world.pos);
+ sp38.y = player->bodyPartsPos[7].y + 3.0f;
+ Math_Vec3f_Copy(&sp2C, &this->actor.focus.pos);
+ sp2C.y -= 30.0f;
+ Math_ApproachS(&this->unk_366, Math_Vec3f_Pitch(&sp2C, &sp38), 4, 0x2AA8);
+ this->unk_366 = CLAMP(this->unk_366, -0x1C70, 0x1C70);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87400.s")
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A875AC.s")
+s32 func_80A86B0C(EnTru* this, GlobalContext* globalCtx) {
+ if (this->unk_34E & 8) {
+ this->unk_34E &= ~0x10;
+ this->unk_34E |= 0x20;
+ func_80A869DC(this, globalCtx);
+ } else if (this->unk_34E & 0x20) {
+ this->unk_34E &= ~0x20;
+ this->unk_366 = 0;
+ this->unk_368 = 0;
+ this->unk_36A = 20;
+ } else if (DECR(this->unk_36A) == 0) {
+ this->unk_34E |= 0x10;
+ this->unk_36A = 20;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8777C.s")
+ return true;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87880.s")
+s32 func_80A86BAC(EnTru* this, GlobalContext* globalCtx) {
+ if (this->unk_34E & 0x400) {
+ Matrix_StatePush();
+ func_8012C28C(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87B48.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87DC0.s")
+ switch (this->unk_390) {
+ case 1:
+ gDPSetEnvColor(POLY_OPA_DISP++, 200, 0, 0, 0);
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87FD0.s")
+ case 2:
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 200, 0);
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A881E0.s")
+ default:
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 0);
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Init.s")
+ Matrix_InsertXRotation_s(-0x4000, MTXMODE_APPLY);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Destroy.s")
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, object_tru_DL_0020C8);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Update.s")
+ Matrix_StatePop();
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A885B8.s")
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A88698.s")
+ if (this->unk_34E & 0x800) {
+ Matrix_StatePush();
+ func_8012C2DC(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A886D4.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Draw.s")
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ Matrix_InsertXRotation_s(-0x4000, 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_tru_DL_001F90);
+
+ Matrix_StatePop();
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+
+ return false;
+}
+
+s32 func_80A86DB8(EnTru* this) {
+ if (this->unk_34E & 0x80) {
+ this->unk_36E = 2;
+ return false;
+ }
+
+ switch (this->unk_37C) {
+ case 0:
+ case 1:
+ if (DECR(this->unk_36C) == 0) {
+ s16 rand = Rand_S16Offset(40, 20);
+ if (this->unk_36E == 2) {
+ this->unk_36C = 8;
+ } else {
+ this->unk_36C = rand;
+ }
+
+ if (this->unk_36E == 2) {
+ this->unk_36E = 1;
+ } else {
+ this->unk_36E = 2;
+ }
+ }
+ return false;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, 10.0f)) {
+ this->unk_36E = 1;
+ } else if ((this->skelAnime.curFrame >= 11.0f) && (this->skelAnime.curFrame <= 32.0f)) {
+ this->unk_36E = 0;
+ } else {
+ this->unk_36E = 2;
+ }
+ return false;
+
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, 31.0f)) {
+ this->unk_36E = 1;
+ } else if (this->skelAnime.curFrame <= 32.0f) {
+ this->unk_36E = 2;
+ } else {
+ this->unk_36E = 0;
+ }
+ return false;
+
+ case 9:
+ if (Animation_OnFrame(&this->skelAnime, 57.0f)) {
+ this->unk_36C = 0;
+ this->unk_36E = 0;
+ }
+
+ if (this->skelAnime.curFrame < 57.0f) {
+ if (DECR(this->unk_36C) == 0) {
+ this = this;
+ this->unk_36C = Rand_S16Offset(8, 8);
+ this->unk_36E = 2;
+ } else {
+ this->unk_36E = 1;
+ }
+ } else if (DECR(this->unk_36C) == 0) {
+ this->unk_36E++;
+ if (this->unk_36E >= 4) {
+ this->unk_36C = Rand_S16Offset(20, 10);
+ this->unk_36E = 0;
+ }
+ }
+ return false;
+
+ case 10:
+ this->unk_36E = 0;
+ return false;
+
+ case 11:
+ if (Animation_OnFrame(&this->skelAnime, 19.0f) || Animation_OnFrame(&this->skelAnime, 45.0f)) {
+ this->unk_36E = 1;
+ } else if ((this->skelAnime.curFrame >= 19.0f) && (this->skelAnime.curFrame <= 45.0f)) {
+ this->unk_36E = 2;
+ } else {
+ this->unk_36E = 3;
+ }
+ return false;
+
+ case 13:
+ if (Animation_OnFrame(&this->skelAnime, 19.0f)) {
+ this->unk_36E = 1;
+ } else if (this->skelAnime.curFrame >= 19.0f) {
+ this->unk_36E = 2;
+ } else {
+ this->unk_36E = 0;
+ }
+ return false;
+
+ default:
+ if (DECR(this->unk_36C) == 0) {
+ if ((this->unk_36E != 2) || !(this->unk_34E & 0x80)) {
+ this->unk_36E++;
+ }
+
+ if (this->unk_36E >= 4) {
+ this->unk_36C = Rand_S16Offset(30, 30);
+ this->unk_36E = 0;
+ }
+ }
+ return false;
+ }
+
+ return false;
+}
+
+UNK_TYPE* func_80A871E0(EnTru* this, GlobalContext* globalCtx) {
+ if (this->unk_34E & 0x2000) {
+ if (this->unk_38C == 35) {
+ this->unk_390 = 1;
+ } else {
+ this->unk_390 = 2;
+ }
+ return D_80A88984;
+ }
+
+ if (this->unk_34E & 0x4000) {
+ return D_80A889A4;
+ }
+
+ if (this->unk_34E & 0x80) {
+ return D_80A88924;
+ }
+
+ if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) {
+ return D_80A88918;
+ }
+
+ if ((this->unk_34E & 0x1000) && !(gSaveContext.weekEventReg[16] & 0x10)) {
+ return D_80A88910;
+ }
+
+ return D_80A8892C;
+}
+
+s32 func_80A872AC(EnTru* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s32 ret = false;
+
+ if (this->unk_34E & 7) {
+ if (func_800B84D0(&this->actor, globalCtx)) {
+ if (player->transformation == PLAYER_FORM_HUMAN) {
+ this->unk_34E &= ~0x80;
+ }
+ this->unk_34E &= ~(0x4000 | 0x2000);
+
+ if ((player->unk_A87 == 35) || (player->unk_A87 == 36)) {
+ this->unk_34E |= 0x2000;
+ this->unk_38C = player->unk_A87;
+ } else if (player->unk_A87 != 0) {
+ this->unk_34E |= 0x4000;
+ }
+
+ this->unk_378 = func_80A875AC;
+ this->unk_390 = 0;
+ this->unk_364 = 0;
+ this->unk_354 = func_80A871E0(this, globalCtx);
+ func_8013AED4(&this->unk_34E, 0, 7);
+ this->actionFunc = func_80A881E0;
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+s32 func_80A873B8(EnTru* this) {
+ s16 yDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y;
+ s32 ret;
+
+ if ((u16)ABS_ALT(yDiff) < 0x1600) {
+ ret = true;
+ } else {
+ ret = false;
+ }
+ return ret;
+}
+
+s32 func_80A87400(EnTru* this, GlobalContext* globalCtx) {
+ Vec3s* sp4C;
+ Vec3f sp40;
+ Vec3f sp34;
+ s16 phi_a1;
+ s32 ret = false;
+
+ this->actor.velocity.y = Math_SinS(this->unk_360) * this->unk_35C;
+ this->unk_360 = CLAMP(this->unk_360 + 2000, 0, 0x4000);
+
+ Math_ApproachF(&this->unk_35C, 30.0f, 0.08f, 1000.0f);
+ Math_ApproachF(&this->actor.speedXZ, 30.0f, 0.2f, 1000.0f);
+
+ if (this->path != NULL) {
+ sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->path->points);
+ if (func_8013BD40(&this->actor, this->path, this->unk_384)) {
+ if (this->unk_384 > this->unk_384 + 1) {
+ this->unk_384 = this->path->count - 2;
+ ret = true;
+ }
+ this->unk_384++;
+ }
+ Math_Vec3s_ToVec3f(&sp34, &sp4C[this->unk_384]);
+ Math_Vec3f_Copy(&sp40, &this->actor.world.pos);
+ phi_a1 = Math_Vec3f_Yaw(&sp40, &sp34);
+ } else {
+ phi_a1 = this->actor.world.rot.y;
+ }
+
+ Math_ApproachS(&this->actor.world.rot.y, phi_a1, 4, 3640);
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
+ if ((s32)(this->actor.floorHeight + 80.0f) >= (s32)this->actor.world.pos.y) {
+ func_80A86770(this);
+ }
+
+ return ret;
+}
+
+s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+ s32 ret = false;
+
+ switch (this->unk_364) {
+ case 0:
+ if ((this->unk_34E & 0x40) || (gSaveContext.weekEventReg[16] & 0x10)) {
+ this->unk_374 = this->actor.cutscene;
+ this->unk_364++;
+ } else {
+ this->unk_364++;
+ this->unk_364++;
+ break;
+ }
+
+ case 1:
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor);
+ this->unk_364++;
+ } else {
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ }
+ break;
+
+ case 2:
+ if ((this->unk_37C != 5) && (this->unk_37C != 6)) {
+ func_80A86924(this, 3);
+ this->unk_364++;
+ } else {
+ func_80A86924(this, 4);
+ ret = true;
+ }
+ break;
+
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_364++;
+ func_80A86924(this, 4);
+ ret = true;
+ }
+ break;
+ }
+
+ if (ret == true) {
+ if (this->unk_390 != 0) {
+ this->unk_34E |= 8;
+ this->unk_378 = func_80A87880;
+ } else {
+ this->unk_378 = func_80A8777C;
+ }
+ this->unk_364 = 0;
+ }
+
+ return ret;
+}
+
+s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx) {
+ s32 temp_v0;
+ s32 ret = 0;
+
+ temp_v0 = func_80152498(&globalCtx->msgCtx);
+
+ switch (temp_v0) {
+ default:
+ if (temp_v0 != 0x10) {
+ break;
+ }
+ if (0) {
+
+ case 4:
+ case 5:
+ if (!func_80147624(globalCtx)) {
+ break;
+ }
+ }
+
+ temp_v0 = func_80123810(globalCtx);
+ if ((temp_v0 == 35) || (temp_v0 == 36)) {
+ ((EnTru*)thisx)->unk_34E |= 8;
+ if (temp_v0 == 35) {
+ ((EnTru*)thisx)->unk_390 = 1;
+ } else {
+ ((EnTru*)thisx)->unk_390 = 2;
+ }
+ ((EnTru*)thisx)->unk_378 = func_80A87880;
+ ((EnTru*)thisx)->unk_364 = 0;
+ ret = 1;
+ } else if (temp_v0 < 0) {
+ ret = 3;
+ } else if (temp_v0 != 0) {
+ ret = 2;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ EnTru* this = THIS;
+ s32 ret = false;
+
+ switch (this->unk_364) {
+ case 0:
+ ActorCutscene_Stop(this->unk_374);
+ this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374);
+ this->unk_364++;
+
+ case 1:
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor);
+ this->unk_364++;
+ } else {
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ }
+ break;
+
+ case 2:
+ this->unk_34E |= 0x10;
+ this->unk_34E &= ~0x8;
+ this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ func_80A86924(this, 7);
+ this->unk_364++;
+ break;
+
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_364++;
+ func_80A86924(this, 9);
+ this->actor.world.rot.y += 0x4000;
+ } else if (Animation_OnFrame(&this->skelAnime, 12.0f) && !(this->unk_34E & 0x800)) {
+ this->unk_34E |= 0x400;
+ this->unk_34E |= 0x800;
+ func_80123AA4(player, 3);
+ }
+ break;
+
+ case 4:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_364++;
+ func_80A86924(this, 10);
+ ret = true;
+ } else if (Animation_OnFrame(&this->skelAnime, 18.0f) || Animation_OnFrame(&this->skelAnime, 32.0f) ||
+ Animation_OnFrame(&this->skelAnime, 52.0f)) {
+ if (Animation_OnFrame(&this->skelAnime, 52.0f)) {
+ this->unk_34E &= ~0x400;
+ func_80123D50(globalCtx, player, 18, 21);
+ }
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_DRINK);
+ } else if (Animation_OnFrame(&this->skelAnime, 90.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_REGAIN);
+ }
+
+ if ((this->skelAnime.curFrame > 90.0f) && (this->skelAnime.curFrame < 95.0f)) {
+ func_80A86674(this);
+ }
+ break;
+ }
+
+ if (ret == true) {
+ this->unk_378 = func_80A87B48;
+ this->unk_364 = 0;
+ }
+
+ return ret;
+}
+
+s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3f sp4C;
+ Vec3f sp40;
+ s16 sp3E;
+ s32 pad2;
+ s32 ret = false;
+
+ switch (this->unk_364) {
+ case 0:
+ func_80A86924(this, 11);
+ this->unk_364++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ sp3E = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)));
+ Math_Vec3f_Copy(&sp4C, &D_801D15B0);
+ sp4C.z = 40.0f;
+ Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp3E, &sp4C, &sp40);
+ func_80A85620(this->unk_394, &sp40, 2.0f, 0.08f, 60.0f);
+ func_8016A268(globalCtx, 1, 160, 160, 160, 0);
+ this->unk_370 = 20;
+ this->unk_372 = 10;
+ this->unk_364++;
+ } else if (Animation_OnFrame(&this->skelAnime, 22.0f)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_MAGIC);
+ func_80A85AA4(this->unk_394, &this->unk_1F8, 1.0f, 0.1f, 40.0f);
+ }
+ break;
+
+ case 2:
+ if (DECR(this->unk_370) != 0) {
+ MREG(68) = 255.0f - ((fabsf(10.0f - this->unk_370) / 10) * 255.0f);
+ if (this->unk_370 == 9) {
+ this->actor.shape.shadowDraw = NULL;
+ this->unk_34E |= (0x200 | 0x8);
+ this->unk_34E &= ~0x800;
+ if (player->unk_A87 != 0) {
+ player->unk_A87 = 0;
+ }
+ func_80A86924(this, 12);
+ }
+ } else {
+ MREG(64) = 0;
+ ret = true;
+ }
+ break;
+ }
+
+ if (ret == true) {
+ this->unk_378 = func_80A87DC0;
+ this->unk_364 = 0;
+ }
+
+ return ret;
+}
+
+s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+ s32 ret = false;
+
+ switch (this->unk_364) {
+ case 0:
+ ActorCutscene_Stop(this->unk_374);
+ this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374);
+ this->unk_364++;
+
+ case 1:
+ if (ActorCutscene_GetCurrentIndex() == 0x7C) {
+ ActorCutscene_Stop(0x7C);
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor);
+ this->unk_364++;
+ } else {
+ ActorCutscene_SetIntentToPlay(this->unk_374);
+ }
+ break;
+
+ case 2:
+ func_801A75E8(NA_SE_EN_KOUME_MAGIC);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_AWAY);
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_LAUGH);
+ func_80A86924(this, 13);
+ this->skelAnime.baseTransl.y = 0;
+ this->skelAnime.moveFlags = 2;
+ this->unk_34E &= ~0x8;
+ this->unk_34E |= 0x10;
+ this->unk_364++;
+ break;
+
+ case 3:
+ if (!Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ AnimationContext_SetMoveActor(globalCtx, &this->actor, &this->skelAnime, 1.0f);
+ break;
+ } else {
+ func_80A86924(this, 14);
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->unk_362 = 20;
+ this->unk_364++;
+ }
+
+ case 4:
+ if (func_80A87400(this, globalCtx) || (DECR(this->unk_362) == 0)) {
+ ret = true;
+ gSaveContext.weekEventReg[12] |= 8;
+ }
+ break;
+ }
+
+ if (ret == true) {
+ this->actor.flags &= ~1;
+ this->actor.draw = NULL;
+ this->unk_378 = NULL;
+ this->unk_34E = 0;
+ this->unk_364 = 0;
+ }
+ return ret;
+}
+
+void func_80A87FD0(EnTru* this, GlobalContext* globalCtx) {
+ if (this->actor.draw != NULL) {
+ if ((this->unk_34E & 0x80) || (gSaveContext.weekEventReg[16] & 0x10)) {
+ if (func_80A873B8(this)) {
+ func_8013AED4(&this->unk_34E, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_34E, 0, 7);
+ }
+ } else if (this->unk_34E & 0x40) {
+ if (func_80A873B8(this)) {
+ func_8013AED4(&this->unk_34E, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_34E, 0, 7);
+ }
+
+ if ((this->unk_37C == 2) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_362 = Rand_S16Offset(40, 20);
+ func_80A86924(this, 1);
+ func_80A86460(this);
+ } else if (this->unk_37C != 2) {
+ if (DECR(this->unk_362) == 0) {
+ func_80A86924(this, 2);
+ }
+ }
+ } else if (!(gSaveContext.weekEventReg[16] & 0x10) && (fabsf(this->actor.playerHeightRel) < 10.0f) &&
+ (this->actor.xzDistToPlayer < 140.0f)) {
+ func_8013AED4(&this->unk_34E, 4, 7);
+ this->unk_34E |= 0x1040;
+ this->unk_362 = Rand_S16Offset(40, 20);
+ } else if (func_80A873B8(this)) {
+ func_8013AED4(&this->unk_34E, 3, 7);
+ } else {
+ func_8013AED4(&this->unk_34E, 0, 7);
+ }
+ }
+}
+
+void func_80A881E0(EnTru* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (func_8010BF58(&this->actor, globalCtx, this->unk_354, this->unk_378, &this->unk_1E8)) {
+ if (player->transformation != PLAYER_FORM_HUMAN) {
+ this->unk_34E |= 0x80;
+ }
+
+ if (ActorCutscene_GetCurrentIndex() != -1) {
+ ActorCutscene_Stop(ActorCutscene_GetCurrentIndex());
+ }
+
+ if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) {
+ func_80A86924(this, 0);
+ } else if (this->unk_34E & 0x80) {
+ func_80A86924(this, 0);
+ func_80A86460(this);
+ } else if (gSaveContext.weekEventReg[16] & 0x10) {
+ func_80A86924(this, 6);
+ }
+
+ func_8013AED4(&this->unk_34E, 0, 7);
+ this->unk_34E &= ~(0x1000 | 0x8);
+ this->unk_34E |= 0x10;
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->actor.flags &= ~0x100;
+ this->unk_1E8 = 0;
+ this->actionFunc = func_80A87FD0;
+ }
+}
+
+void EnTru_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+
+ if ((gSaveContext.entranceIndex != 0xC200) || (gSaveContext.weekEventReg[12] & 8)) {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+
+ ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f);
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tru_Skel_01AA60, NULL, this->jointTable, this->morphTable,
+ 27);
+ Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit);
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit);
+ this->unk_37C = -1;
+ func_80A86924(this, 0);
+ this->path = func_8013BEDC(globalCtx, this->actor.params & 0xFF, 255, &this->unk_384);
+ if (this->path != NULL) {
+ this->unk_384 = 1;
+ }
+
+ this->actor.targetMode = 0;
+ Actor_SetScale(&this->actor, 0.008f);
+ this->unk_34E = 0;
+
+ if (gSaveContext.weekEventReg[16] & 0x10) {
+ func_80A86924(this, 5);
+ } else {
+ this->unk_388 = 0;
+ }
+
+ this->actionFunc = func_80A87FD0;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
+}
+
+void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+
+ Collider_DestroySphere(globalCtx, &this->collider);
+}
+
+void EnTru_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnTru* this = THIS;
+ f32 radius;
+
+ func_80A872AC(this, globalCtx);
+
+ this->actionFunc(this, globalCtx);
+
+ func_80A868F8(this);
+ func_80A86B0C(this, globalCtx);
+ func_80A86DB8(this);
+
+ radius = this->collider.dim.worldSphere.radius + 30;
+ this->unk_388 = !(this->unk_34E & 0x80) ? 0 : 0;
+
+ func_8013C964(&this->actor, globalCtx, radius, 20.0f, this->unk_388, this->unk_34E & 7);
+ func_80A8697C(this, globalCtx);
+ func_80A86384(this->unk_394, &this->unk_1F8);
+}
+
+s32 EnTru_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ s32 pad;
+ EnTru* this = THIS;
+
+ if (limbIndex == 21) {
+ Matrix_GetStateTranslation(&this->actor.focus.pos);
+ Math_Vec3f_ToVec3s(&this->collider.dim.worldSphere.center, &this->actor.focus.pos);
+ this->actor.focus.pos.x = (this->actor.focus.pos.x / 10.0f) * 10.0f;
+ this->actor.focus.pos.y = ((this->actor.focus.pos.y + 10.0f) / 10.0f) * 10.0f;
+ this->actor.focus.pos.z = (this->actor.focus.pos.z / 10.0f) * 10.0f;
+ Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot);
+ Matrix_MultiplyVector3fByState(&D_80A8B3FC, &this->unk_1F8);
+ }
+
+ if (!(this->unk_34E & 0x200) && (limbIndex == 14)) {
+ *dList = NULL;
+ }
+
+ return false;
+}
+
+void EnTru_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ EnTru* this = THIS;
+
+ if (limbIndex == 19) {
+ func_80A86BAC(this, globalCtx);
+ }
+}
+
+void func_80A886D4(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) {
+ EnTru* this = THIS;
+ s32 pad[3];
+ s32 sp2C;
+ s32 phi_v1;
+
+ if (this->unk_34E & 0x10) {
+ phi_v1 = false;
+ } else {
+ phi_v1 = true;
+ }
+
+ if (this->unk_34E & 0x20) {
+ sp2C = true;
+ } else {
+ sp2C = false;
+ }
+
+ if (!phi_v1) {
+ sp2C = false;
+ }
+
+ if (limbIndex == 21) {
+ func_8013AD9C(this->unk_366, this->unk_368 + this->actor.shape.rot.y, &this->unk_1EC, &this->unk_204, phi_v1,
+ sp2C);
+ Matrix_StatePop();
+ Matrix_InsertTranslation(this->unk_1EC.x, this->unk_1EC.y, this->unk_1EC.z, MTXMODE_NEW);
+ Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
+ if (sp2C) {
+ s16 oldZ = this->unk_204.z;
+
+ this->unk_204.z = this->unk_204.x;
+ this->unk_204.x = oldZ;
+ }
+ Matrix_RotateY(this->unk_204.y, MTXMODE_APPLY);
+ Matrix_InsertXRotation_s(this->unk_204.x, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(this->unk_204.z, MTXMODE_APPLY);
+ Matrix_StatePush();
+ }
+}
+
+void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ static TexturePtr D_80A8B408[] = {
+ &object_tru_Tex_018FA0,
+ &object_tru_Tex_0197A0,
+ &object_tru_Tex_019FA0,
+ &object_tru_Tex_0197A0,
+ };
+ s32 pad;
+ EnTru* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E]));
+ gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E]));
+
+ func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, func_80A886D4, &this->actor);
+ func_80A85788(this->unk_394, globalCtx);
+ func_80A85BCC(this->unk_394, globalCtx);
+ func_80A85F84(this->unk_394, globalCtx);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.h b/src/overlays/actors/ovl_En_Tru/z_en_tru.h
index 7c21a43a33..4127fcdff8 100644
--- a/src/overlays/actors/ovl_En_Tru/z_en_tru.h
+++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.h
@@ -6,12 +6,55 @@
struct EnTru;
typedef void (*EnTruActionFunc)(struct EnTru*, GlobalContext*);
+typedef s32 (*EnTruUnkFunc)(Actor*, GlobalContext*);
+
+typedef struct {
+ /* 0x00 */ u8 unk_00;
+ /* 0x01 */ u8 unk_01;
+ /* 0x02 */ u8 unk_02;
+ /* 0x04 */ Vec3f unk_04;
+ /* 0x10 */ Vec3f unk_10;
+ /* 0x1C */ Vec3f unk_1C;
+ /* 0x28 */ f32 unk_28;
+ /* 0x2C */ f32 unk_2C;
+} EnTruUnkStruct; // size = 0x30
typedef struct EnTru {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x44];
+ /* 0x0144 */ SkelAnime skelAnime;
/* 0x0188 */ EnTruActionFunc actionFunc;
- /* 0x018C */ char unk_18C[0x7A8];
+ /* 0x018C */ ColliderSphere collider;
+ /* 0x01E4 */ Path* path;
+ /* 0x01E8 */ s32 unk_1E8;
+ /* 0x01EC */ Vec3f unk_1EC;
+ /* 0x01F8 */ Vec3f unk_1F8;
+ /* 0x0204 */ Vec3s unk_204;
+ /* 0x020A */ Vec3s jointTable[27];
+ /* 0x02AC */ Vec3s morphTable[27];
+ /* 0x034E */ u16 unk_34E;
+ /* 0x0350 */ UNK_TYPE1 unk350[0x4];
+ /* 0x0354 */ s32* unk_354;
+ /* 0x0358 */ f32 unk_358;
+ /* 0x035C */ f32 unk_35C;
+ /* 0x0360 */ s16 unk_360;
+ /* 0x0362 */ s16 unk_362;
+ /* 0x0364 */ s16 unk_364;
+ /* 0x0366 */ s16 unk_366;
+ /* 0x0368 */ s16 unk_368;
+ /* 0x036A */ s16 unk_36A;
+ /* 0x036C */ s16 unk_36C;
+ /* 0x036E */ s16 unk_36E;
+ /* 0x0370 */ s16 unk_370;
+ /* 0x0372 */ s16 unk_372;
+ /* 0x0374 */ s16 unk_374;
+ /* 0x0378 */ EnTruUnkFunc unk_378;
+ /* 0x037C */ s32 unk_37C;
+ /* 0x0380 */ UNK_TYPE1 unk380[0x4];
+ /* 0x0384 */ s32 unk_384;
+ /* 0x0388 */ s32 unk_388;
+ /* 0x038C */ s32 unk_38C;
+ /* 0x0390 */ s32 unk_390;
+ /* 0x0394 */ EnTruUnkStruct unk_394[30];
} EnTru; // size = 0x934
extern const ActorInit En_Tru_InitVars;
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 537d9b2ecf..60f5b896ac 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -11247,8 +11247,8 @@
0x80A88334:("EnTru_Init",),
0x80A884BC:("EnTru_Destroy",),
0x80A884E8:("EnTru_Update",),
- 0x80A885B8:("func_80A885B8",),
- 0x80A88698:("func_80A88698",),
+ 0x80A885B8:("EnTru_OverrideLimbDraw",),
+ 0x80A88698:("EnTru_PostLimbDraw",),
0x80A886D4:("func_80A886D4",),
0x80A887E4:("EnTru_Draw",),
0x80A8B770:("EnTrt_ChangeAnim",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index d5d2eb0e7f..8e75b9cbd4 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -12593,8 +12593,7 @@
0x80A8A188:("D_80A8A188","UNK_TYPE1","",0x1),
0x80A8B188:("D_80A8B188","UNK_TYPE1","",0x1),
0x80A8B250:("D_80A8B250","UNK_TYPE4","",0x4),
- 0x80A8B25C:("D_80A8B25C","UNK_TYPE1","",0x1),
- 0x80A8B268:("D_80A8B268","UNK_TYPE1","",0x1),
+ 0x80A8B25C:("D_80A8B25C","Color_RGBA8","[6]",0x18),
0x80A8B280:("D_80A8B280","UNK_TYPE1","",0x1),
0x80A8B2A0:("D_80A8B2A0","UNK_TYPE1","",0x1),
0x80A8B2CC:("D_80A8B2CC","UNK_TYPE1","",0x1),
diff --git a/undefined_syms.txt b/undefined_syms.txt
index ff66eaa8a4..ba74050c01 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -3872,9 +3872,25 @@ D_0600FEF0 = 0x0600FEF0;
D_06001F90 = 0x06001F90;
D_060020C8 = 0x060020C8;
+D_06002BD8 = 0x06002BD8;
+D_06003698 = 0x06003698;
+D_0600446C = 0x0600446C;
+D_06007FA0 = 0x06007FA0;
+D_06009348 = 0x06009348;
+D_0600EEDC = 0x0600EEDC;
+D_0600F9A0 = 0x0600F9A0;
+D_060108AC = 0x060108AC;
+D_06011F88 = 0x06011F88;
+D_06014728 = 0x06014728;
+D_06015CA0 = 0x06015CA0;
+D_06016B4C = 0x06016B4C;
+D_06018FA0 = 0x06018FA0;
+D_060197A0 = 0x060197A0;
+D_06019FA0 = 0x06019FA0;
D_0601A820 = 0x0601A820;
D_0601A830 = 0x0601A830;
D_0601AA60 = 0x0601AA60;
+D_0601B5C4 = 0x0601B5C4;
// ovl_En_Tru_Mt