From 98501be8df20fe273cc4eec3ffa1607584a6ace6 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Wed, 14 Sep 2022 16:32:22 +0100 Subject: [PATCH 1/8] Obj_Usiyane (#902) * Obj_Usiyane * PR * RP * PR --- spec | 3 +- .../actors/ovl_Obj_Usiyane/z_obj_usiyane.c | 243 ++++++++++++++++-- .../actors/ovl_Obj_Usiyane/z_obj_usiyane.h | 26 +- undefined_syms.txt | 6 - 4 files changed, 248 insertions(+), 30 deletions(-) diff --git a/spec b/spec index e17d3af91..9a0f31668 100644 --- a/spec +++ b/spec @@ -4850,8 +4850,7 @@ beginseg name "ovl_Obj_Usiyane" compress include "build/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.o" - include "build/data/ovl_Obj_Usiyane/ovl_Obj_Usiyane.data.o" - include "build/data/ovl_Obj_Usiyane/ovl_Obj_Usiyane.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Usiyane/ovl_Obj_Usiyane_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c index e895eeba9..33ebf1e50 100644 --- a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c +++ b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c @@ -5,6 +5,7 @@ */ #include "z_obj_usiyane.h" +#include "objects/object_obj_usiyane/object_obj_usiyane.h" #define FLAGS (ACTOR_FLAG_20) @@ -15,7 +16,6 @@ void ObjUsiyane_Destroy(Actor* thisx, PlayState* play); void ObjUsiyane_Update(Actor* thisx, PlayState* play); void ObjUsiyane_Draw(Actor* thisx, PlayState* play); -#if 0 const ActorInit Obj_Usiyane_InitVars = { ACTOR_OBJ_USIYANE, ACTORCAT_PROP, @@ -28,40 +28,245 @@ const ActorInit Obj_Usiyane_InitVars = { (ActorFunc)ObjUsiyane_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C086B0[] = { +PosRot D_80C08660[] = { + { { 800.0f, -940.0f, 2000.0f }, { 0, 0, 0x2AF8 } }, + { { 560.0f, -790.0f, -2000.0f }, { 0, 0, 0x2EE0 } }, + { { -480.0f, -780.0f, -1990.0f }, { 0, 0, -0x2710 } }, + { { -470.0f, -850.0f, 2000.0f }, { 0, 0, -0x2710 } }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 900, ICHAIN_STOP), }; -#endif +s32 func_80C07C80(s32 arg0) { + s32 var_v1; -extern InitChainEntry D_80C086B0[]; + if (!(arg0 & 1)) { + var_v1 = gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF; + } else { + var_v1 = (gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF0000) >> 0x10; + } + return var_v1 + CLOCK_TIME(2, 30); +} -extern UNK_TYPE D_06000838; -extern UNK_TYPE D_060022AC; +s32 func_80C07CD0(void) { + if (CURRENT_DAY <= 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C07C80.s") + if (CURRENT_DAY == 1) { + s32 time = gSaveContext.save.time; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C07CD0.s") + if ((time < CLOCK_TIME(2, 30)) || (time >= CLOCK_TIME(6, 0))) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C07DC4.s") + if (time < CLOCK_TIME(5, 15)) { + s32 var_s1 = CLOCK_TIME(5, 15); + s32 temp_v0_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C07DFC.s") + for (i = 0; i < 8; i++) { + temp_v0_2 = func_80C07C80(i); + var_s1 = CLAMP_MAX(var_s1, temp_v0_2); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C07F30.s") + if (time < (var_s1 + 0xE11)) { + return false; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C081C8.s") + if (gSaveContext.save.weekEventReg[22] & 1) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C082CC.s") +void func_80C07DC4(ObjUsiyane* this, PlayState* play) { + if (func_80C07CD0()) { + Actor_MarkForDeath(&this->dyna.actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/func_80C082E0.s") +void func_80C07DFC(Vec3f* arg0, Vec3s* arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 arg5, Vec3f* arg6, Vec3s* arg7) { + f32 temp_fv0 = (f32)arg4 / arg5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/ObjUsiyane_Init.s") + // VEC3F_LERPIMPDST + arg6->x = ((arg2->x - arg0->x) * temp_fv0) + arg0->x; + arg6->y = ((arg2->y - arg0->y) * temp_fv0) + arg0->y; + arg6->z = ((arg2->z - arg0->z) * temp_fv0) + arg0->z; + arg7->x = (((f32)arg3->x - (f32)arg1->x) * temp_fv0) + arg1->x; + arg7->y = (((f32)arg3->y - (f32)arg1->y) * temp_fv0) + arg1->y; + arg7->z = (((f32)arg3->z - (f32)arg1->z) * temp_fv0) + arg1->z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/ObjUsiyane_Destroy.s") +void func_80C07F30(ObjUsiyane* this, PlayState* play) { + s32 i; + s32 j; + Vec3f sp94; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/ObjUsiyane_Update.s") + for (i = 0; i < ARRAY_COUNT(this->unk_168[0]); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_168); j++) { + if (i != ARRAY_COUNT(this->unk_168[0]) - 1) { + func_80C07DFC(&this->unk_710[i], &D_80C08660[i].rot, &this->unk_710[i + 1], &D_80C08660[i + 1].rot, j, + 10, &this->unk_168[j][i].unk_00, &this->unk_168[j][i].unk_18); + } else { + func_80C07DFC(&this->unk_710[i], &D_80C08660[i].rot, &this->unk_710[0], &D_80C08660[0].rot, j, 10, + &this->unk_168[j][i].unk_00, &this->unk_168[j][i].unk_18); + } + func_800B12F0(play, &this->unk_168[j][i].unk_00, &gZeroVec3f, &gZeroVec3f, 100, 30, 7); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Usiyane/ObjUsiyane_Draw.s") + this->unk_168[j][i].unk_18.y = (s32)Rand_Next() >> 0x10; + + sp94.x = this->unk_168[j][i].unk_00.x - this->unk_708; + sp94.y = 0.0f; + sp94.z = this->unk_168[j][i].unk_00.z - this->unk_70C; + Math3D_Normalize(&sp94); + + sp94.x *= 5.0f; + sp94.y = 19.0f; + sp94.z *= 5.0f; + + this->unk_168[j][i].unk_0C = sp94; + + this->unk_168[j][i].unk_1E.x = Rand_Centered() * 4000.0f; + this->unk_168[j][i].unk_1E.y = Rand_Centered() * 4000.0f; + this->unk_168[j][i].unk_1E.z = Rand_Centered() * 4000.0f; + } + } + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_HOUSE_BROKEN); + this->unk_740 = 0; + this->unk_744 |= 4; +} + +void func_80C081C8(ObjUsiyane* this, PlayState* play) { + s32 i; + s32 j; + + this->unk_744 |= 1; + + if (this->unk_740 <= 70) { + for (i = 0; i < ARRAY_COUNT(this->unk_168[0]); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_168); j++) { + this->unk_168[j][i].unk_0C.y += -0.8f; + + this->unk_168[j][i].unk_00.x += this->unk_168[j][i].unk_0C.x; + this->unk_168[j][i].unk_00.y += this->unk_168[j][i].unk_0C.y; + this->unk_168[j][i].unk_00.z += this->unk_168[j][i].unk_0C.z; + + this->unk_168[j][i].unk_18.x += this->unk_168[j][i].unk_1E.x; + this->unk_168[j][i].unk_18.y += this->unk_168[j][i].unk_1E.y; + this->unk_168[j][i].unk_18.z += this->unk_168[j][i].unk_1E.z; + } + } + + } else if (this->unk_740 >= 70) { + Actor_MarkForDeath(&this->dyna.actor); + } + this->unk_740++; +} + +void func_80C082CC(ObjUsiyane* this, PlayState* play) { + this->unk_164 = -1; +} + +void func_80C082E0(ObjUsiyane* this, PlayState* play) { + CsCmdActorAction* csAction; + + if (Cutscene_CheckActorAction(play, 0x228)) { + this->unk_160 = Cutscene_GetActorActionIndex(play, 0x228); + csAction = play->csCtx.actorActions[this->unk_160]; + if (this->unk_164 != csAction->action) { + this->unk_164 = csAction->action; + if (this->unk_164 == 2) { + func_80C07F30(this, play); + this->actionFunc = func_80C081C8; + } + } + } +} + +void ObjUsiyane_Init(Actor* thisx, PlayState* play) { + ObjUsiyane* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, 0.1f); + + this->unk_744 = 0; + + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(play, &this->dyna, &object_obj_usiyane_Colheader_0022AC); + + switch (OBJUSIYANE_GET_F(&this->dyna.actor)) { + case OBJUSIYANE_F_0: + this->actionFunc = func_80C07DC4; + break; + + case OBJUSIYANE_F_1: + func_80C082CC(this, play); + this->actionFunc = func_80C082E0; + break; + + default: + Actor_MarkForDeath(&this->dyna.actor); + break; + } +} + +void ObjUsiyane_Destroy(Actor* thisx, PlayState* play) { + ObjUsiyane* this = THIS; + + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); +} + +void ObjUsiyane_Update(Actor* thisx, PlayState* play) { + ObjUsiyane* this = THIS; + + this->actionFunc(this, play); +} + +void ObjUsiyane_Draw(Actor* thisx, PlayState* play) { + ObjUsiyane* this = THIS; + MtxF mf; + + if (!(this->unk_744 & 1)) { + Gfx_DrawDListOpa(play, object_obj_usiyane_DL_000838); + } + + if (!(this->unk_744 & 2)) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_80C08660); i++) { + Vec3f sp74; + + Matrix_MultVec3f(&D_80C08660[i].pos, &this->unk_710[i]); + Matrix_MultVec3f(&gZeroVec3f, &sp74); + this->unk_708 = sp74.x; + this->unk_70C = sp74.z; + } + this->unk_744 |= 2; + } + + if ((this->unk_744 & 4) && !(this->unk_744 & 8)) { + s32 i; + s32 j; + + for (i = 0; i < ARRAY_COUNT(this->unk_168[0]); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_168); j++) { + Matrix_Push(); + SkinMatrix_SetScaleRotateRPYTranslate(&mf, 0.1f, 0.1f, 0.1f, this->unk_168[j][i].unk_18.x, + this->unk_168[j][i].unk_18.y, this->unk_168[j][i].unk_18.z, + this->unk_168[j][i].unk_00.x, this->unk_168[j][i].unk_00.y, + this->unk_168[j][i].unk_00.z); + Matrix_Put(&mf); + Gfx_DrawDListOpa(play, object_obj_usiyane_DL_000098); + Matrix_Pop(); + } + } + } +} diff --git a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.h b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.h index 7c4cdd8a5..c38a08ed9 100644 --- a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.h +++ b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.h @@ -7,11 +7,31 @@ struct ObjUsiyane; typedef void (*ObjUsiyaneActionFunc)(struct ObjUsiyane*, PlayState*); +#define OBJUSIYANE_GET_F(thisx) ((thisx)->params & 0xF) + +enum { + /* 0 */ OBJUSIYANE_F_0, + /* 1 */ OBJUSIYANE_F_1, +}; + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3s unk_18; + /* 0x1E */ Vec3s unk_1E; +} ObjUsiyaneStruct; // size = 0x24 + typedef struct ObjUsiyane { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ ObjUsiyaneActionFunc actionFunc; - /* 0x160 */ char unk_160[0x5E8]; + /* 0x160 */ s32 unk_160; + /* 0x164 */ s32 unk_164; + /* 0x168 */ ObjUsiyaneStruct unk_168[10][4]; + /* 0x708 */ f32 unk_708; + /* 0x70C */ f32 unk_70C; + /* 0x710 */ Vec3f unk_710[4]; + /* 0x740 */ s32 unk_740; + /* 0x744 */ s32 unk_744; } ObjUsiyane; // size = 0x748 extern const ActorInit Obj_Usiyane_InitVars; diff --git a/undefined_syms.txt b/undefined_syms.txt index faf0aba38..20a4cf5e2 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1450,12 +1450,6 @@ D_06001100 = 0x06001100; D_06001140 = 0x06001140; D_06001CB0 = 0x06001CB0; -// ovl_Obj_Usiyane - -D_06000098 = 0x06000098; -D_06000838 = 0x06000838; -D_060022AC = 0x060022AC; - // ovl_player_actor D_06008860 = 0x06008860; From 90ade1be9fe9f21357365f75362888e5fea72ef4 Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo <96613413+sonicdcer@users.noreply.github.com> Date: Wed, 14 Sep 2022 12:37:21 -0300 Subject: [PATCH 2/8] ovl_En_Js Decompiled (#991) * progress * progress * func_80968E38 (thanks @engineer124) * progress * remove comments * general cleanup * warnings * all functions matching * macros * final details * format * ovl_En_Js Decompiled * PLAYER_AO enums * fix * pr review * re preview * pr review * pr review * pr review * resolving after merge * conflict resolution * pr review * pr review * pr review --- assets/xml/objects/object_ob.xml | 177 ++-- spec | 3 +- src/overlays/actors/ovl_En_Js/z_en_js.c | 1035 ++++++++++++++++++++++- src/overlays/actors/ovl_En_Js/z_en_js.h | 18 +- tools/disasm/functions.txt | 4 +- 5 files changed, 1106 insertions(+), 131 deletions(-) diff --git a/assets/xml/objects/object_ob.xml b/assets/xml/objects/object_ob.xml index 75217e04e..d2390fc39 100644 --- a/assets/xml/objects/object_ob.xml +++ b/assets/xml/objects/object_ob.xml @@ -1,84 +1,101 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec b/spec index 9a0f31668..22a85ed0f 100644 --- a/spec +++ b/spec @@ -1644,8 +1644,7 @@ beginseg name "ovl_En_Js" compress include "build/src/overlays/actors/ovl_En_Js/z_en_js.o" - include "build/data/ovl_En_Js/ovl_En_Js.data.o" - include "build/data/ovl_En_Js/ovl_En_Js.reloc.o" + include "build/src/overlays/actors/ovl_En_Js/ovl_En_Js_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Js/z_en_js.c b/src/overlays/actors/ovl_En_Js/z_en_js.c index 57763a190..4e35a5158 100644 --- a/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -15,7 +15,18 @@ void EnJs_Destroy(Actor* thisx, PlayState* play); void EnJs_Update(Actor* thisx, PlayState* play); void EnJs_Draw(Actor* thisx, PlayState* play); -#if 0 +s32 func_80968B8C(EnJs* this, PlayState* play); +s32 func_809692A8(s32 arg0); +void func_80968A5C(EnJs* this); +void func_80969400(s32 arg0); +void func_8096971C(EnJs* this, PlayState* play); +void func_80969898(EnJs* this, PlayState* play); +void func_80969B5C(EnJs* this, PlayState* play); +void func_80969DA4(EnJs* this, PlayState* play); +void func_8096A104(EnJs* this, PlayState* play); +void func_8096A38C(EnJs* this, PlayState* play); +void func_8096A6F4(EnJs* this, PlayState* play); + const ActorInit En_Js_InitVars = { ACTOR_EN_JS, ACTORCAT_NPC, @@ -28,89 +39,1021 @@ const ActorInit En_Js_InitVars = { (ActorFunc)EnJs_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8096ABA0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, 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, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + 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, + OCELEM_ON, + }, { 20, 40, 0, { 0, 0, 0 } }, }; -#endif +static Gfx* D_8096ABCC[] = { + gMoonChildMajorasMaskDL, gMoonChildOdalwasMaskDL, gMoonChildGohtsMaskDL, + gMoonChildGyorgsMaskDL, gMoonChildTwinmoldsMaskDL, +}; -extern ColliderCylinderInit D_8096ABA0; +f32 D_8096ABE0[] = { 1.0f, 0.5f, 0.5f, 0.48f, 0.45f }; -extern UNK_TYPE D_06010880; -extern UNK_TYPE D_06016F58; -extern UNK_TYPE D_06017E98; +f32 D_8096ABF4[] = { 60.0f, 0.0f, 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/EnJs_Init.s") +f32 D_8096AC08[] = { -450.0f, 1400.0f, 1470.0f, 1670.0f, 1470.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/EnJs_Destroy.s") +f32 D_8096AC1C[] = { 0.0f, 700.0f, 900.0f, 900.0f, 900.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968A5C.s") +Vec3f D_8096AC30 = { 500.0f, -500.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968B18.s") +void EnJs_Init(Actor* thisx, PlayState* play) { + s32 pad; + s16 cs; + s32 i; + EnJs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968B8C.s") + Actor_SetScale(&this->actor, 0.01f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(play, &this->skelAnime, &gMoonChildSkel, &gMoonChildStandingAnim, this->jointTable, + this->morphTable, MOONCHILD_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gMoonChildStandingAnim); + Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968CB8.s") + this->actionFunc = func_8096971C; + this->maskType = 0; + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968DD0.s") + cs = this->actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968E38.s") + for (i = 0; i < ARRAY_COUNT(this->cutscenes); i++) { + this->cutscenes[i] = cs; + if (cs != -1) { + this->actor.cutscene = cs; + cs = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80968F48.s") + this->cutsceneIndex = -1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_809691B8.s") + switch (ENJS_GET_TYPE(&this->actor)) { + case 0: + this->maskType = 0; + this->actionFunc = func_8096A6F4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_809692A8.s") + Animation_PlayLoop(&this->skelAnime, &gMoonChildSittingAnim); + func_8016566C(0x3C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096933C.s") + if (gSaveContext.save.weekEventReg[84] & 0x20) { + Inventory_DeleteItem(ITEM_MASK_FIERCE_DEITY, SLOT(ITEM_MASK_FIERCE_DEITY)); + gSaveContext.save.weekEventReg[84] &= (u8)~0x20; + } + break; + case 1: + case 2: + case 3: + case 4: + this->maskType = ENJS_GET_TYPE(&this->actor); + func_80968B8C(this, play); + this->actionFunc = func_80969B5C; + func_80968A5C(this); + if (func_809692A8(ENJS_GET_TYPE(&this->actor) + 4)) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + case 5: + case 6: + case 7: + case 8: + this->maskType = ENJS_GET_TYPE(&this->actor) - 4; + this->actionFunc = func_8096A104; + break; + default: + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969400.s") +void EnJs_Destroy(Actor* thisx, PlayState* play) { + u32 paramsF; + EnJs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969494.s") + Collider_DestroyCylinder(play, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_809694E8.s") + paramsF = ENJS_GET_TYPE(&this->actor); + switch (paramsF) { + case 0: + func_80165690(); + break; + case 5: + case 6: + case 7: + case 8: + if (!func_809692A8(paramsF)) { + func_80969400(ENJS_GET_TYPE(&this->actor)); + } + break; + default: + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969530.s") +void func_80968A5C(EnJs* this) { + if (Rand_ZeroOne() < 0.5f) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildRunningAnim, -10.0f); + this->unk_2B4 = 5.0f; + } else { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildWalkingAnim, -10.0f); + this->unk_2B4 = 2.5f; + } + this->unk_2B8 &= ~4; + this->unk_2BC = Rand_ZeroFloat(40.0f) + 80.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_809695FC.s") +void func_80968B18(EnJs* this) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildStandingAnim, -10.0f); + this->unk_2B4 = 0.0f; + this->unk_2BC = Rand_ZeroFloat(20.0f) + 40.0f; + this->unk_2B8 |= 4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969688.s") +s32 func_80968B8C(EnJs* this, PlayState* play) { + Path* path; + f32 temp_f0; + f32 temp_f2; + s32 pathIndex = ENJS_GET_PATH_INDEX(&this->actor); + s32 i; + f32 sp18 = 0.0f; + Vec3s* points; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_809696EC.s") + if (pathIndex != 0x3F) { + this->path = &play->setupPathList[pathIndex]; + if (this->path != NULL) { + path = this->path; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096971C.s") + points = Lib_SegmentedToVirtual(path->points); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969748.s") + for (i = 0; i < path->count; i++, points++) { + temp_f0 = points->x - this->actor.world.pos.x; + temp_f2 = points->z - this->actor.world.pos.z; + temp_f0 = SQ(temp_f0) + SQ(temp_f2); + if (i == 0) { + sp18 = temp_f0; + this->unk_2B0 = 0; + } else if (temp_f0 < sp18) { + sp18 = temp_f0; + this->unk_2B0 = i; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969898.s") + this->unk_2B0++; + if (this->unk_2B0 >= path->count) { + this->unk_2B0 = 0; + } + } + } else { + this->path = NULL; + this->unk_2B0 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969AA0.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969B5C.s") +s32 func_80968CB8(EnJs* this) { + Path* path; + s32 pad; + f32 temp_fa0; + f32 temp_fa1; + Vec3s* temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969C54.s") + if (this->path == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_80969DA4.s") + path = this->path; + temp_v1 = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[this->unk_2B0]; + temp_fa0 = temp_v1->x - this->actor.world.pos.x; + temp_fa1 = temp_v1->z - this->actor.world.pos.z; + this->actor.world.rot.y = Math_Atan2S(temp_fa0, temp_fa1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A080.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 0x7D0, 0xC8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A104.s") + if ((SQ(temp_fa0) + SQ(temp_fa1)) < SQ(10.0f)) { + this->unk_2B0++; + if (this->unk_2B0 >= path->count) { + this->unk_2B0 = 0; + } + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A184.s") + Math_StepToF(&this->actor.speedXZ, this->unk_2B4, 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A1E8.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A2C0.s") +s32 func_80968DD0(EnJs* this, PlayState* play) { + if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, play) && + Actor_IsFacingPlayer(&this->actor, 0x3000)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A38C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A6F4.s") +s32 func_80968E38(s32 arg0) { + s32 i; + s32 count; + u8 mask; + u8* maskMaskBit = gSaveContext.maskMaskBit; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/EnJs_Update.s") + if (((arg0 < 0) || (arg0 >= 9))) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/func_8096A9F4.s") + count = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Js/EnJs_Draw.s") + arg0 *= 3; + for (mask = 1, i = 0; i < 8; i++, mask <<= 1) { + if (maskMaskBit[arg0] & mask) { + count++; + } + } + + arg0++; + for (mask = 1, i = 0; i < 8; i++, mask <<= 1) { + if (maskMaskBit[arg0] & mask) { + count++; + } + } + + arg0++; + for (mask = 1, i = 0; i < 5; i++, mask <<= 1) { + if (maskMaskBit[arg0] & mask) { + count++; + } + } + + return count; +} + +s32 EnJs_GetRemainingMasks(void) { + s32 count = 0; + + if (INV_CONTENT(ITEM_MASK_TRUTH) == ITEM_MASK_TRUTH) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KAFEIS_MASK) == ITEM_MASK_KAFEIS_MASK) { + count++; + } + if (INV_CONTENT(ITEM_MASK_ALL_NIGHT) == ITEM_MASK_ALL_NIGHT) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KEATON) == ITEM_MASK_KEATON) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GARO) == ITEM_MASK_GARO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) { + count++; + } + if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) { + count++; + } + if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GIBDO) == ITEM_MASK_GIBDO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_DON_GERO) == ITEM_MASK_DON_GERO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_CAPTAIN) == ITEM_MASK_CAPTAIN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_STONE) == ITEM_MASK_STONE) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) { + count++; + } + if (INV_CONTENT(ITEM_MASK_SCENTS) == ITEM_MASK_SCENTS) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GIANT) == ITEM_MASK_GIANT) { + count++; + } + + count -= func_80968E38(0); + return count; +} + +void EnJs_TakeMask(s32 actionParams, s32 childType) { + u8* maskMaskBit = gSaveContext.maskMaskBit; + s32 temp = 0; + + if ((childType >= 0) && (childType < 9)) { + actionParams -= PLAYER_AP_MASK_TRUTH; + childType *= 3; + if (actionParams < 8) { + maskMaskBit[childType] |= 1 << actionParams; + maskMaskBit[temp] |= 1 << actionParams; + return; + } + + actionParams -= 8; + childType++; + temp++; + if (actionParams < 8) { + maskMaskBit[childType] |= 1 << actionParams; + maskMaskBit[temp] |= 1 << actionParams; + return; + } + + actionParams -= 8; + childType++; + temp++; + if (actionParams < 6) { + maskMaskBit[childType] |= 1 << actionParams; + maskMaskBit[temp] |= 1 << actionParams; + } + } +} + +s32 func_809692A8(s32 arg0) { + switch (arg0) { + case 1: + case 2: + case 3: + case 4: + if (func_80968E38(arg0) < arg0) { + return false; + } + return true; + case 5: + case 6: + case 7: + case 8: + if (func_80968E38(arg0) < (arg0 - 4)) { + return false; + } + return true; + default: + return false; + } +} + +s32 func_8096933C(s32 arg0) { + s32 sp1C; + + switch (arg0) { + case 1: + case 2: + case 3: + case 4: + sp1C = EnJs_GetRemainingMasks(); + if ((func_80968E38(arg0) + sp1C) < arg0) { + return false; + } else { + return true; + } + case 5: + case 6: + case 7: + case 8: + sp1C = EnJs_GetRemainingMasks(); + if ((func_80968E38(arg0) + sp1C) < (arg0 - 4)) { + return false; + } else { + return true; + } + default: + return false; + } +} + +void func_80969400(s32 arg0) { + u8* maskMaskBit = gSaveContext.maskMaskBit; + u8* temp_v0 = &gSaveContext.maskMaskBit[arg0 * 3]; + + if ((arg0 >= 0) && (arg0 < 9)) { + maskMaskBit[0] &= ~temp_v0[0]; + maskMaskBit[1] &= ~temp_v0[1]; + + temp_v0[2] &= 0xF; + maskMaskBit[2] &= ~temp_v0[2]; + + temp_v0[0] = 0; + temp_v0[1] = 0; + temp_v0[2] = 0; + } +} + +void func_80969494(EnJs* this, PlayState* play) { + func_80968A5C(this); + func_801477B4(play); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_80969B5C; +} + +void func_809694E8(EnJs* this, PlayState* play) { + func_801477B4(play); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_8096A104; +} + +void func_80969530(EnJs* this, PlayState* play) { + func_801477B4(play); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_8096A6F4; + if ((this->actor.home.rot.y == this->actor.shape.rot.y) && (this->unk_2B8 & 0x10)) { + Animation_Change(&this->skelAnime, &gMoonChildGettingUpAnim, -1.0f, + Animation_GetLastFrame(&gMoonChildGettingUpAnim) - 1.0f, 0.0f, ANIMMODE_ONCE, -10.0f); + this->unk_2B8 &= ~0x10; + this->unk_2B8 |= 8; + } +} + +s32 func_809695FC(EnJs* this, PlayState* play) { + if (ENJS_GET_EXIT_INDEX(&this->actor) == 0x3F) { + return false; + } + play->transitionTrigger = TRANS_TRIGGER_START; + play->nextEntrance = play->setupExitList[ENJS_GET_EXIT_INDEX(&this->actor)]; + this->actionFunc = func_8096971C; + play->msgCtx.msgLength = 0; + gSaveContext.respawnFlag = -2; + return true; +} + +void func_80969688(EnJs* this) { + if (this->cutsceneIndex != -1) { + if (ActorCutscene_GetCurrentIndex() == this->cutscenes[this->cutsceneIndex]) { + ActorCutscene_Stop(this->cutscenes[this->cutsceneIndex]); + } + this->cutsceneIndex = -1; + } +} + +void func_809696EC(EnJs* this, s16 arg1) { + func_80969688(this); + this->cutsceneIndex = arg1; +} + +void func_8096971C(EnJs* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); +} + +void func_80969748(EnJs* this, PlayState* play) { + s32 itemActionParam; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (Message_GetState(&play->msgCtx) == TEXT_STATE_16) { + itemActionParam = func_80123810(play); + if (itemActionParam != PLAYER_AP_NONE) { + this->actionFunc = func_80969898; + } + if (itemActionParam > PLAYER_AP_NONE) { + func_801477B4(play); + if ((itemActionParam >= PLAYER_AP_MASK_TRUTH) && (itemActionParam <= PLAYER_AP_MASK_GIANT)) { + EnJs_TakeMask(itemActionParam, ENJS_GET_TYPE(&this->actor)); + Inventory_UnequipItem(itemActionParam - 4); + if (!func_809692A8(ENJS_GET_TYPE(&this->actor))) { + player->actor.textId = 0x2212; + } else { + player->actor.textId = 0x2213; + } + } else if ((itemActionParam >= PLAYER_AP_MASK_FIERCE_DEITY) && (itemActionParam <= PLAYER_AP_MASK_DEKU)) { + player->actor.textId = 0x2211; + } else { + player->actor.textId = 0x2210; + } + } + if (itemActionParam <= PLAYER_AP_MINUS1) { + func_80151938(play, 0x2216); + } + } +} + +void func_80969898(EnJs* this, PlayState* play) { + s32 pad; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + switch (Message_GetState(&play->msgCtx)) { + case TEXT_STATE_CHOICE: + if (Message_ShouldAdvance(play) && (play->msgCtx.currentTextId == 0x2215)) { + switch (play->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + func_80151938(play, 0x2217); + break; + case 1: + func_8019F230(); + func_80151938(play, 0x2216); + break; + } + } + break; + case TEXT_STATE_5: + if (Message_ShouldAdvance(play)) { + switch (play->msgCtx.currentTextId) { + case 0x220C: + this->unk_2B8 |= 1; + if (!func_8096933C(ENJS_GET_TYPE(&this->actor))) { + func_80151938(play, 0x220F); + break; + } + func_80151938(play, 0x220D); + break; + case 0x220D: + case 0x2213: + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + case 0x220E: + func_80151938(play, 0xFF); + this->actionFunc = func_80969748; + break; + case 0x2210: + case 0x2211: + case 0x2212: + player->exchangeItemId = PLAYER_AP_NONE; + func_80151938(play, 0xFF); + this->actionFunc = func_80969748; + break; + case 0x2214: + case 0x2217: + if (!func_809695FC(this, play)) { + func_80969494(this, play); + break; + } + break; + default: + func_80969494(this, play); + break; + } + } + break; + } +} + +void func_80969AA0(EnJs* this, PlayState* play) { + u16 textId; + + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + textId = 0x220B; + } else { + textId = 0x2215; + if (!func_809692A8(ENJS_GET_TYPE(&this->actor))) { + if (this->unk_2B8 & 1) { + if (!func_8096933C(ENJS_GET_TYPE(&this->actor))) { + textId = 0x220F; + } else { + textId = 0x220E; + } + } else { + textId = 0x220C; + } + } else { + textId = 0x2215; + } + } + Animation_MorphToLoop(&this->skelAnime, &gMoonChildStandingAnim, -10.0f); + Message_StartTextbox(play, textId, &this->actor); +} + +void func_80969B5C(EnJs* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + if (this->unk_2BC > 0) { + this->unk_2BC--; + if (this->unk_2BC == 0) { + if (this->unk_2B8 & 4) { + func_80968A5C(this); + } else { + func_80968B18(this); + } + } + } + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + this->actionFunc = func_80969898; + this->actor.speedXZ = 0.0f; + this->unk_2B4 = 0.0f; + func_80969AA0(this, play); + } else if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, play)) { + func_800B8614(&this->actor, play, 120.0f); + } + func_80968CB8(this); +} + +void func_80969C54(EnJs* this, PlayState* play) { + s32 itemActionParam; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (Message_GetState(&play->msgCtx) == TEXT_STATE_16) { + itemActionParam = func_80123810(play); + if (itemActionParam != PLAYER_AP_NONE) { + this->actionFunc = func_80969DA4; + } + if (itemActionParam > PLAYER_AP_NONE) { + func_801477B4(play); + if ((itemActionParam >= PLAYER_AP_MASK_TRUTH) && (itemActionParam <= PLAYER_AP_MASK_GIANT)) { + EnJs_TakeMask(itemActionParam, ENJS_GET_TYPE(&this->actor)); + Inventory_UnequipItem(itemActionParam - 4); + if (!func_809692A8(ENJS_GET_TYPE(&this->actor))) { + player->actor.textId = 0x2221; + } else { + player->actor.textId = 0x2222; + } + } else if ((itemActionParam >= PLAYER_AP_MASK_FIERCE_DEITY) && (itemActionParam <= PLAYER_AP_MASK_DEKU)) { + player->actor.textId = 0x2220; + } else { + player->actor.textId = 0x221D; + } + } + if (itemActionParam <= PLAYER_AP_MINUS1) { + func_80151938(play, 0x221E); + } + } +} + +void func_80969DA4(EnJs* this, PlayState* play) { + s32 pad; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + switch (Message_GetState(&play->msgCtx)) { + case TEXT_STATE_CHOICE: + if (Message_ShouldAdvance(play) && + ((play->msgCtx.currentTextId == 0x2219) || (play->msgCtx.currentTextId == 0x221E))) { + switch (play->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + if (!func_809695FC(this, play)) { + func_809694E8(this, play); + break; + } + break; + case 1: + func_8019F230(); + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + } + } + break; + case TEXT_STATE_5: + if (Message_ShouldAdvance(play)) { + switch (play->msgCtx.currentTextId) { + case 0x221B: + if (!func_8096933C(ENJS_GET_TYPE(&this->actor))) { + func_80151938(play, 0x2219); + break; + } + func_80151938(play, 0x221C); + break; + case 0x2224: + case 0x2226: + case 0x2228: + case 0x222A: + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + case 0x2225: + case 0x2227: + case 0x2229: + case 0x222B: + if (!func_809695FC(this, play)) { + func_809694E8(this, play); + break; + } + break; + case 0x2222: + player->exchangeItemId = PLAYER_AP_NONE; + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + case 0x2223: + switch (ENJS_GET_TYPE(&this->actor)) { + case 5: + func_80151938(play, 0x2224); + break; + case 6: + func_80151938(play, 0x2226); + break; + case 7: + func_80151938(play, 0x2228); + break; + case 8: + func_80151938(play, 0x222A); + break; + } + break; + case 0x221C: + func_80151938(play, 0xFF); + this->actionFunc = func_80969C54; + break; + case 0x221D: + case 0x2220: + case 0x2221: + player->exchangeItemId = PLAYER_AP_NONE; + func_80151938(play, 0xFF); + this->actionFunc = func_80969C54; + break; + default: + func_809694E8(this, play); + break; + } + } + break; + } +} + +void func_8096A080(EnJs* this, PlayState* play) { + u16 textId; + + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + textId = 0x2218; + } else { + textId = 0x221B; + if (this->unk_2B8 & 1) { + if (!func_8096933C(ENJS_GET_TYPE(&this->actor))) { + textId = 0x2219; + } else { + textId = 0x221C; + } + } else { + this->unk_2B8 |= 1; + } + } + Message_StartTextbox(play, textId, &this->actor); +} + +void func_8096A104(EnJs* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + this->actionFunc = func_80969DA4; + func_8096A080(this, play); + } else if (func_80968DD0(this, play)) { + func_800B8614(&this->actor, play, 120.0f); + } +} + +void func_8096A184(EnJs* this, PlayState* play) { + u16 textId; + + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + textId = 0x220B; + } else if (func_80968E38(0) >= 20) { + textId = 0x2202; + } else { + textId = 0x21FC; + } + Message_StartTextbox(play, textId, &this->actor); +} + +void func_8096A1E8(EnJs* this, PlayState* play) { + if (SkelAnime_Update(&this->skelAnime)) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildStandingAnim, 0.0f); + } + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + this->actionFunc = func_8096A38C; + Message_StartTextbox(play, 0x2208, &this->actor); + gSaveContext.save.weekEventReg[84] |= 0x20; + func_809696EC(this, 0); + } else { + func_800B8500(&this->actor, play, 1000.0f, 1000.0f, PLAYER_AP_MINUS1); + } +} + +void func_8096A2C0(EnJs* this, PlayState* play) { + if (SkelAnime_Update(&this->skelAnime)) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildStandingAnim, 0.0f); + } + if (Actor_HasParent(&this->actor, play)) { + this->actor.parent = NULL; + this->actor.flags |= ACTOR_FLAG_10000; + this->actionFunc = func_8096A1E8; + func_800B8500(&this->actor, play, 1000.0f, 1000.0f, PLAYER_AP_MINUS1); + } else { + Actor_PickUp(&this->actor, play, GI_MASK_FIERCE_DEITY, 10000.0f, 1000.0f); + } +} + +void func_8096A38C(EnJs* this, PlayState* play) { + if (SkelAnime_Update(&this->skelAnime)) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildStandingAnim, 0.0f); + this->unk_2B8 |= 2; + } + switch (Message_GetState(&play->msgCtx)) { + case TEXT_STATE_CHOICE: + if (Message_ShouldAdvance(play)) { + switch (play->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + break; + + case 1: + func_8019F230(); + break; + } + + switch (play->msgCtx.currentTextId) { + case 0x21FC: + switch (play->msgCtx.choiceIndex) { + case 0: + func_80151938(play, 0x21FE); + Animation_MorphToPlayOnce(&this->skelAnime, &gMoonChildGettingUpAnim, -5.0f); + this->unk_2B8 |= 0x10; + break; + case 1: + func_80151938(play, 0x21FD); + break; + } + break; + + case 0x21FE: + switch (play->msgCtx.choiceIndex) { + case 0: + func_80151938(play, 0x2200); + func_809696EC(this, 0); + break; + case 1: + func_80151938(play, 0x21FF); + break; + } + break; + + case 0x2203: + switch (play->msgCtx.choiceIndex) { + case 0: + func_80151938(play, 0x2205); + Animation_MorphToPlayOnce(&this->skelAnime, &gMoonChildGettingUpAnim, -5.0f); + this->unk_2B8 |= 0x10; + break; + case 1: + func_80151938(play, 0x2204); + break; + } + } + } + break; + case TEXT_STATE_5: + if (Message_ShouldAdvance(play)) { + switch (play->msgCtx.currentTextId) { + case 0x2202: + case 0x2205: + case 0x2206: + case 0x2209: + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + + case 0x2200: + case 0x2208: + func_809696EC(this, 1); + func_80151938(play, play->msgCtx.currentTextId + 1); + break; + + case 0x2207: + if (INV_CONTENT(ITEM_MASK_FIERCE_DEITY) == ITEM_MASK_FIERCE_DEITY) { + func_80151938(play, 0x2208); + func_809696EC(this, 0); + } else { + func_801477B4(play); + this->actionFunc = func_8096A2C0; + func_8096A2C0(this, play); + } + break; + + case 0x2201: + + case 0x220A: + if (!func_809695FC(this, play)) { + func_80969530(this, play); + } + break; + + default: + func_80969530(this, play); + break; + } + } + break; + } +} + +void func_8096A6F4(EnJs* this, PlayState* play) { + s32 pad; + + if (this->actor.home.rot.y != this->actor.shape.rot.y) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); + if ((this->actor.home.rot.y == this->actor.shape.rot.y) && (this->unk_2B8 & 0x10)) { + Animation_Change(&this->skelAnime, &gMoonChildGettingUpAnim, -1.0f, + Animation_GetLastFrame(&gMoonChildGettingUpAnim) - 1.0f, 0.0f, ANIMMODE_ONCE, -10.0f); + this->unk_2B8 &= ~0x10; + this->unk_2B8 |= 8; + } + this->actor.world.rot.y = this->actor.shape.rot.y; + } + if (SkelAnime_Update(&this->skelAnime)) { + Animation_MorphToLoop(&this->skelAnime, &gMoonChildSittingAnim, -10.0f); + this->unk_2B8 &= ~8; + } + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + this->actionFunc = func_8096A38C; + this->unk_2B8 &= ~2; + func_8096A184(this, play); + return; + } + if (!(this->unk_2B8 & 8) && (this->actor.xzDistToPlayer < 100.0f) && + Player_IsFacingActor(&this->actor, 0x3000, play) && Actor_IsFacingPlayer(&this->actor, 0x1000)) { + func_800B8614(&this->actor, play, 120.0f); + } +} + +void EnJs_Update(Actor* thisx, PlayState* play) { + s32 pad; + EnJs* this = THIS; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(play, &this->actor, 40.0f, 25.0f, 40.0f, 5); + + this->actionFunc(this, play); + + if ((this->cutsceneIndex != -1) && (ActorCutscene_GetCurrentIndex() != this->cutscenes[this->cutsceneIndex])) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->cutscenes[this->cutsceneIndex]); + } else if (ActorCutscene_GetCanPlayNext(this->cutscenes[this->cutsceneIndex])) { + ActorCutscene_Start(this->cutscenes[this->cutsceneIndex], &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->cutscenes[this->cutsceneIndex]); + } + } +} + +void func_8096A9F4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnJs* this = THIS; + + if (limbIndex == MOONCHILD_LIMB_HEAD) { + Matrix_MultVec3f(&D_8096AC30, &thisx->focus.pos); + if ((this->maskType >= 0) && (this->maskType < 5)) { + OPEN_DISPS(play->state.gfxCtx); + + if (this->maskType != 0) { + Matrix_Scale(D_8096ABE0[this->maskType], D_8096ABE0[this->maskType], D_8096ABE0[this->maskType], + MTXMODE_APPLY); + Matrix_RotateZYX(0, -0x4000, -0x36B0, MTXMODE_APPLY); + } + Matrix_Translate(D_8096ABF4[this->maskType], D_8096AC08[this->maskType], D_8096AC1C[this->maskType], + MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_8096ABCC[this->maskType]); + + CLOSE_DISPS(play->state.gfxCtx); + } + } +} + +void EnJs_Draw(Actor* thisx, PlayState* play) { + EnJs* this = THIS; + + func_8012C28C(play->state.gfxCtx); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + func_8096A9F4, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Js/z_en_js.h b/src/overlays/actors/ovl_En_Js/z_en_js.h index 96c1bbf49..534557e66 100644 --- a/src/overlays/actors/ovl_En_Js/z_en_js.h +++ b/src/overlays/actors/ovl_En_Js/z_en_js.h @@ -2,6 +2,11 @@ #define Z_EN_JS_H #include "global.h" +#include "objects/object_ob/object_ob.h" + +#define ENJS_GET_TYPE(thisx) ((thisx)->params & 0xF) +#define ENJS_GET_PATH_INDEX(thisx) (((thisx)->params & 0xFC00) >> 10) +#define ENJS_GET_EXIT_INDEX(thisx) (((thisx)->params & 0x3F0) >> 4) struct EnJs; @@ -9,7 +14,18 @@ typedef void (*EnJsActionFunc)(struct EnJs*, PlayState*); typedef struct EnJs { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x180]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ ColliderCylinder collider; + /* 0x1D4 */ Vec3s jointTable[MOONCHILD_LIMB_MAX]; + /* 0x240 */ Vec3s morphTable[MOONCHILD_LIMB_MAX]; + /* 0x2AC */ Path* path; + /* 0x2B0 */ s32 unk_2B0; + /* 0x2B4 */ f32 unk_2B4; + /* 0x2B8 */ u16 unk_2B8; + /* 0x2BA */ s16 maskType; + /* 0x2BC */ s16 unk_2BC; + /* 0x2BE */ s16 cutscenes[2]; + /* 0x2C2 */ s16 cutsceneIndex; /* 0x2C4 */ EnJsActionFunc actionFunc; } EnJs; // size = 0x2C8 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index bea647d45..cddc0dc43 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -7955,8 +7955,8 @@ 0x80968CB8:("func_80968CB8",), 0x80968DD0:("func_80968DD0",), 0x80968E38:("func_80968E38",), - 0x80968F48:("func_80968F48",), - 0x809691B8:("func_809691B8",), + 0x80968F48:("EnJs_GetRemainingMasks",), + 0x809691B8:("EnJs_TakeMask",), 0x809692A8:("func_809692A8",), 0x8096933C:("func_8096933C",), 0x80969400:("func_80969400",), From 3d430a57336442c608a33009ee685bd4c0dd5d5b Mon Sep 17 00:00:00 2001 From: Parker Burnett Date: Wed, 14 Sep 2022 08:46:16 -0700 Subject: [PATCH 3/8] En_bubble OK (#995) * bubble OK * fixing elfbulb * flag fix * PR comments * PR comments * missed a fix * PR fixes * don't know how this got in there * u to s * small fix --- assets/xml/objects/object_bubble.xml | 4 +- spec | 3 +- .../actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 2 +- .../actors/ovl_En_Bubble/z_en_bubble.c | 402 ++++++++++++++++-- .../actors/ovl_En_Bubble/z_en_bubble.h | 21 +- .../actors/ovl_En_Elfbub/z_en_elfbub.c | 2 +- tools/disasm/functions.txt | 22 +- 7 files changed, 398 insertions(+), 58 deletions(-) diff --git a/assets/xml/objects/object_bubble.xml b/assets/xml/objects/object_bubble.xml index 4397a017f..da2f01d47 100644 --- a/assets/xml/objects/object_bubble.xml +++ b/assets/xml/objects/object_bubble.xml @@ -1,6 +1,6 @@  - - + + diff --git a/spec b/spec index 22a85ed0f..a1ca83eb2 100644 --- a/spec +++ b/spec @@ -883,8 +883,7 @@ beginseg name "ovl_En_Bubble" compress include "build/src/overlays/actors/ovl_En_Bubble/z_en_bubble.o" - include "build/data/ovl_En_Bubble/ovl_En_Bubble.data.o" - include "build/data/ovl_En_Bubble/ovl_En_Bubble.reloc.o" + include "build/src/overlays/actors/ovl_En_Bubble/ovl_En_Bubble_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 64c42a1ce..12da39288 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -649,7 +649,7 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (this->actor.params == DEMO_KANKYO_TYPE_GIANTS) { - gSPDisplayList(POLY_XLU_DISP++, object_bubble_DL_001000); + gSPDisplayList(POLY_XLU_DISP++, gBubbleDL); } else { gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c index 3030041ca..06c5c33b1 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c @@ -15,11 +15,10 @@ void EnBubble_Destroy(Actor* thisx, PlayState* play); void EnBubble_Update(Actor* thisx, PlayState* play); void EnBubble_Draw(Actor* thisx, PlayState* play); -void func_808A029C(EnBubble* this, PlayState* play); -void func_808A0350(EnBubble* this, PlayState* play); -void func_808A03E8(EnBubble* this, PlayState* play); +void EnBubble_Wait(EnBubble* this, PlayState* play); +void EnBubble_Pop(EnBubble* this, PlayState* play); +void EnBubble_Regrow(EnBubble* this, PlayState* play); -#if 0 const ActorInit En_Bubble_InitVars = { ACTOR_EN_BUBBLE, ACTORCAT_ENEMY, @@ -32,73 +31,396 @@ const ActorInit En_Bubble_InitVars = { (ActorFunc)EnBubble_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_808A0700[2] = { +static ColliderJntSphElementInit sJntSphElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x04 }, { 0xF7CFD757, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x04 }, + { 0xF7CFD757, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 16 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00002820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_AT_INFO | BUMP_NO_DAMAGE | BUMP_NO_SWORD_SFX | BUMP_NO_HITMARK, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00002820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_AT_INFO | BUMP_NO_DAMAGE | BUMP_NO_SWORD_SFX | BUMP_NO_HITMARK, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 16 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808A0748 = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - ARRAY_COUNT(sJntSphElementsInit), D_808A0700, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT6, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_808A0758 = { 1, 2, 25, 25, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 2, 25, 25, MASS_IMMOVABLE }; -#endif +void EnBubble_SetDimensions(EnBubble* this, f32 dim) { + f32 x; + f32 y; + f32 z; + f32 norm; -extern ColliderJntSphElementInit D_808A0700[2]; -extern ColliderJntSphInit D_808A0748; -extern CollisionCheckInfoInit2 D_808A0758; + this->actor.flags |= ACTOR_FLAG_1; + Actor_SetScale(&this->actor, 1.0f); + this->actor.shape.yOffset = 16.0f; + this->modelRotSpeed = 16.0f; + this->modelEllipticity = 0.08f; + this->modelWidth = dim; + this->modelHeight = dim; + x = Rand_ZeroOne(); + y = Rand_ZeroOne(); + z = Rand_ZeroOne(); + this->unk_210 = 1.0f; + this->unk_214 = 1.0f; + norm = SQ(x) + SQ(y) + SQ(z); + this->unk1F8.x = x / norm; + this->unk1F8.y = y / norm; + this->unk1F8.z = z / norm; +} -extern UNK_TYPE D_06001000; +s32 func_8089F59C(EnBubble* this) { + ColliderInfo* info = &this->colliderSphere.elements[0].info; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F4E0.s") + info->toucher.dmgFlags = DMG_EXPLOSIVES; + info->toucher.effect = 0; + info->toucher.damage = 4; + info->toucherFlags = TOUCH_ON; + this->actor.velocity.y = 0.0f; + return 6; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F59C.s") +s32 func_8089F5D0(EnBubble* this) { + EnBubble_SetDimensions(this, -1.0f); + return 12; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F5D0.s") +void EnBubble_DamagePlayer(EnBubble* this, PlayState* play) { + play->damagePlayer(play, -this->colliderSphere.elements[0].info.toucher.damage); + func_800B8E1C(play, &this->actor, 6.0f, this->actor.yawTowardsPlayer, 6.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F5F4.s") +s32 EnBubble_Explosion(EnBubble* this, PlayState* play) { + static Color_RGBA8 sEffectPrimColor = { 255, 255, 255, 255 }; + static Color_RGBA8 sEffectEnvColor = { 150, 150, 150, 0 }; + s32 i; + Vec3f effectAccel = { 0.0f, -0.5f, 0.0f }; + Vec3f effectVel; + Vec3f effectPos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F660.s") + Math_SmoothStepToF(&this->modelWidth, 4.0f, 0.1f, 1000.0f, 0.0f); + Math_SmoothStepToF(&this->modelHeight, 4.0f, 0.1f, 1000.0f, 0.0f); + Math_SmoothStepToF(&this->modelRotSpeed, 54.0f, 0.1f, 1000.0f, 0.0f); + Math_SmoothStepToF(&this->modelEllipticity, 0.2f, 0.1f, 1000.0f, 0.0f); + this->actor.shape.yOffset = (this->modelHeight + 1.0f) * 16.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F8BC.s") + if (DECR(this->explosionCountdown) != 0) { + return -1; + } + effectPos.x = this->actor.world.pos.x; + effectPos.y = this->actor.world.pos.y + this->actor.shape.yOffset; + effectPos.z = this->actor.world.pos.z; + for (i = 0; i < 20; i++) { + effectVel.x = (Rand_ZeroOne() - 0.5f) * 7.0f; + effectVel.y = Rand_ZeroOne() * 7.0f; + effectVel.z = (Rand_ZeroOne() - 0.5f) * 7.0f; + EffectSsDtBubble_SpawnCustomColor(play, &effectPos, &effectVel, &effectAccel, &sEffectPrimColor, + &sEffectEnvColor, Rand_S16Offset(100, 50), 25, 0); + } + Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, 0x50); + this->actor.flags &= ~ACTOR_FLAG_1; + return Rand_S16Offset(90, 60); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F908.s") +s32 func_8089F8BC(EnBubble* this) { + if (DECR(this->explosionCountdown) != 0) { + return -1; + } else { + return func_8089F5D0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F95C.s") +s32 func_8089F908(EnBubble* this) { + this->modelWidth += 1.0f / 12.0f; + this->modelHeight += 1.0f / 12.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089F9E4.s") + if (DECR(this->explosionCountdown) != 0) { + return false; + } else { + return true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089FA54.s") +void EnBubble_Vec3fNormalizedReflect(Vec3f* vec1, Vec3f* vec2, Vec3f* dest) { + f32 norm; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089FF30.s") + func_80179F64(vec1, vec2, dest); + norm = sqrtf(SQ(dest->x) + SQ(dest->y) + SQ(dest->z)); + if (norm != 0.0f) { + dest->x /= norm; + dest->y /= norm; + dest->z /= norm; + } else { + dest->x = dest->y = dest->z = 0.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_8089FFCC.s") +void EnBubble_Vec3fNormalize(Vec3f* vec) { + f32 norm = sqrtf(SQ(vec->x) + SQ(vec->y) + SQ(vec->z)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_808A005C.s") + if (norm != 0.0f) { + vec->x /= norm; + vec->y /= norm; + vec->z /= norm; + } else { + vec->x = vec->y = vec->z = 0.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/EnBubble_Init.s") +void EnBubble_Fly(EnBubble* this, PlayState* play) { + CollisionPoly* poly; + Actor* bumpActor; + Vec3f sp84; + Vec3f sp78; + Vec3f sp6C; + Vec3f normal; + Vec3f bounceDirection; + f32 bounceSpeed; + s32 bgId; + u8 bounceCount; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/EnBubble_Destroy.s") + if (this->colliderSphere.elements[1].info.bumperFlags & BUMP_HIT) { + bumpActor = this->colliderSphere.base.ac; + this->normalizedBumpVelocity = bumpActor->velocity; + EnBubble_Vec3fNormalize(&this->normalizedBumpVelocity); + this->velocityFromBump.x += this->normalizedBumpVelocity.x * 3.0f; + this->velocityFromBump.y += this->normalizedBumpVelocity.y * 3.0f; + this->velocityFromBump.z += this->normalizedBumpVelocity.z * 3.0f; + } + this->yVelocity -= 0.1f; + if (this->yVelocity < this->actor.terminalVelocity) { + this->yVelocity = this->actor.terminalVelocity; + } + bounceDirection.x = this->velocityFromBounce.x + this->velocityFromBump.x; + bounceDirection.y = this->velocityFromBounce.y + this->velocityFromBump.y + this->yVelocity; + bounceDirection.z = this->velocityFromBounce.z + this->velocityFromBump.z; + EnBubble_Vec3fNormalize(&bounceDirection); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_808A029C.s") + sp78.x = this->actor.world.pos.x; + sp78.y = this->actor.world.pos.y + this->actor.shape.yOffset; + sp78.z = this->actor.world.pos.z; + sp6C = sp78; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_808A0350.s") + sp6C.x += (bounceDirection.x * 24.0f); + sp6C.y += (bounceDirection.y * 24.0f); + sp6C.z += (bounceDirection.z * 24.0f); + if (BgCheck_EntityLineTest1(&play->colCtx, &sp78, &sp6C, &sp84, &poly, true, true, true, false, &bgId)) { + normal.x = COLPOLY_GET_NORMAL(poly->normal.x); + normal.y = COLPOLY_GET_NORMAL(poly->normal.y); + normal.z = COLPOLY_GET_NORMAL(poly->normal.z); + EnBubble_Vec3fNormalizedReflect(&bounceDirection, &normal, &bounceDirection); + this->bounceDirection = bounceDirection; + bounceCount = this->bounceCount; + this->bounceCount = ++bounceCount; + if (bounceCount > (s16)(Rand_ZeroOne() * 10.0f)) { + this->bounceCount = 0; + } + bounceSpeed = (this->bounceCount == 0) ? 3.6000001f : 3.0f; + this->velocityFromBump.x = this->velocityFromBump.y = this->velocityFromBump.z = 0.0f; + this->velocityFromBounce.x = this->bounceDirection.x * bounceSpeed; + this->velocityFromBounce.y = this->bounceDirection.y * bounceSpeed; + this->velocityFromBounce.z = this->bounceDirection.z * bounceSpeed; + this->yVelocity = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AWA_BOUND); + this->modelRotSpeed = 128.0f; + this->modelEllipticity = 0.48f; + } else if ((this->actor.bgCheckFlags & 0x20) && (bounceDirection.y < 0.0f)) { + normal.x = normal.z = 0.0f; + normal.y = 1.0f; + EnBubble_Vec3fNormalizedReflect(&bounceDirection, &normal, &bounceDirection); + this->bounceDirection = bounceDirection; + bounceCount = this->bounceCount; + this->bounceCount = ++bounceCount; + if (bounceCount > (s16)(Rand_ZeroOne() * 10.0f)) { + this->bounceCount = 0; + } + bounceSpeed = (this->bounceCount == 0) ? 3.6000001f : 3.0f; + this->velocityFromBump.x = this->velocityFromBump.y = this->velocityFromBump.z = 0.0f; + this->velocityFromBounce.x = (this->bounceDirection.x * bounceSpeed); + this->velocityFromBounce.y = (this->bounceDirection.y * bounceSpeed); + this->velocityFromBounce.z = (this->bounceDirection.z * bounceSpeed); + this->yVelocity = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AWA_BOUND); + this->modelRotSpeed = 128.0f; + this->modelEllipticity = 0.48f; + } + this->actor.velocity.x = this->velocityFromBounce.x + this->velocityFromBump.x; + this->actor.velocity.y = this->velocityFromBounce.y + this->velocityFromBump.y + this->yVelocity; + this->actor.velocity.z = this->velocityFromBounce.z + this->velocityFromBump.z; + Math_ApproachF(&this->velocityFromBump.x, 0.0f, 0.3f, 0.1f); + Math_ApproachF(&this->velocityFromBump.y, 0.0f, 0.3f, 0.1f); + Math_ApproachF(&this->velocityFromBump.z, 0.0f, 0.3f, 0.1f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_808A03A0.s") +s32 func_8089FF30(EnBubble* this) { + if (((this->colliderSphere.base.acFlags & AC_HIT) != 0) == false) { + return false; + } + this->colliderSphere.base.acFlags &= ~AC_HIT; + if (this->colliderSphere.elements[1].info.bumperFlags & BUMP_HIT) { + this->unk1F4.x = this->colliderSphere.base.ac->velocity.x / 10.0f; + this->unk1F4.y = this->colliderSphere.base.ac->velocity.y / 10.0f; + this->unk1F4.z = this->colliderSphere.base.ac->velocity.z / 10.0f; + this->modelRotSpeed = 128.0f; + this->modelEllipticity = 0.48f; + return false; + } + this->timer = 8; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/func_808A03E8.s") +s32 EnBubble_IsPopped(EnBubble* this, PlayState* play) { + if ((DECR(this->timer) != 0) || (this->actionFunc == EnBubble_Pop)) { + return false; + } + if (this->colliderSphere.base.ocFlags2 & OC2_HIT_PLAYER) { + this->colliderSphere.base.ocFlags2 &= ~OC2_HIT_PLAYER; + EnBubble_DamagePlayer(this, play); + this->timer = 8; + return true; + } + return func_8089FF30(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/EnBubble_Update.s") +void func_808A005C(EnBubble* this) { + ColliderJntSphElementDim* dim = &this->colliderSphere.elements[0].dim; + Vec3f src; + Vec3f dest; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bubble/EnBubble_Draw.s") + src.x = dim->modelSphere.center.x; + src.y = dim->modelSphere.center.y; + src.z = dim->modelSphere.center.z; + + Matrix_MultVec3f(&src, &dest); + dim->worldSphere.center.x = dest.x; + dim->worldSphere.center.y = dest.y; + dim->worldSphere.center.z = dest.z; + dim->worldSphere.radius = dim->modelSphere.radius * (1.0f + this->modelWidth); + this->colliderSphere.elements[1].dim = *dim; +} + +void EnBubble_Init(Actor* thisx, PlayState* play) { + s32 pad; + EnBubble* this = THIS; + + ActorShape_Init(&this->actor.shape, 16.0f, ActorShadow_DrawCircle, 0.2f); + Collider_InitJntSph(play, &this->colliderSphere); + Collider_SetJntSph(play, &this->colliderSphere, &this->actor, &sJntSphInit, this->colliderElements); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(9), &sColChkInfoInit); + this->actor.hintId = 0x16; + this->bounceDirection.x = Rand_ZeroOne(); + this->bounceDirection.y = Rand_ZeroOne(); + this->bounceDirection.z = Rand_ZeroOne(); + EnBubble_Vec3fNormalize(&this->bounceDirection); + this->velocityFromBounce.x = this->bounceDirection.x * 3.0f; + this->velocityFromBounce.y = this->bounceDirection.y * 3.0f; + this->velocityFromBounce.z = this->bounceDirection.z * 3.0f; + EnBubble_SetDimensions(this, 0); + this->actionFunc = EnBubble_Wait; +} + +void EnBubble_Destroy(Actor* thisx, PlayState* play) { + EnBubble* this = (EnBubble*)thisx; + + Collider_DestroyJntSph(play, &this->colliderSphere); +} + +void EnBubble_Wait(EnBubble* this, PlayState* play) { + if (EnBubble_IsPopped(this, play)) { + this->explosionCountdown = func_8089F59C(this); + this->actionFunc = EnBubble_Pop; + } else { + EnBubble_Fly(this, play); + this->actor.shape.yOffset = (this->modelHeight + 1.0f) * 16.0f; + CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSphere.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSphere.base); + } +} + +void EnBubble_Pop(EnBubble* this, PlayState* play) { + if (EnBubble_Explosion(this, play) > -1) { + SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 60, NA_SE_EN_AWA_BREAK); + Actor_MarkForDeath(&this->actor); + } +} + +void EnBubble_Disappear(EnBubble* this, PlayState* play) { + s32 temp_v0 = func_8089F8BC(this); + + if (temp_v0 >= 0) { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->explosionCountdown = temp_v0; + this->actionFunc = EnBubble_Regrow; + } +} + +void EnBubble_Regrow(EnBubble* this, PlayState* play) { + if (func_8089F908(this)) { + this->actionFunc = EnBubble_Wait; + } + CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSphere.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSphere.base); +} + +void EnBubble_Update(Actor* thisx, PlayState* play) { + EnBubble* this = (EnBubble*)thisx; + + Actor_UpdatePos(&this->actor); + Actor_UpdateBgCheckInfo(play, &this->actor, 16.0f, 16.0f, 0.0f, 7); + this->actionFunc(this, play); + Actor_SetFocus(&this->actor, this->actor.shape.yOffset); +} + +void EnBubble_Draw(Actor* thisx, PlayState* play) { + s32 pad; + EnBubble* this = (EnBubble*)thisx; + + OPEN_DISPS(play->state.gfxCtx); + + if (this->actionFunc != EnBubble_Disappear) { + func_8012C2DC(play->state.gfxCtx); + Math_SmoothStepToF(&this->modelRotSpeed, 16.0f, 0.2f, 1000.0f, 0.0f); + Math_SmoothStepToF(&this->modelEllipticity, 0.08f, 0.2f, 1000.0f, 0.0f); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_Scale(this->modelWidth + 1.0f, this->modelHeight + 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(DEGF_TO_RADF((f32)play->state.frames) * this->modelRotSpeed, MTXMODE_APPLY); + Matrix_Scale(this->modelEllipticity + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(DEGF_TO_RADF(-(f32)play->state.frames) * this->modelRotSpeed, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gBubbleDL); + } + + CLOSE_DISPS(play->state.gfxCtx); + + if (this->actionFunc != EnBubble_Disappear) { + this->actor.shape.shadowScale = (this->modelWidth + 1.0f) * 0.2f; + func_808A005C(this); + } +} diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h index 2217b86b1..7affed807 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h @@ -2,6 +2,7 @@ #define Z_EN_BUBBLE_H #include "global.h" +#include "objects/object_bubble/object_bubble.h" struct EnBubble; @@ -10,7 +11,25 @@ typedef void (*EnBubbleActionFunc)(struct EnBubble*, PlayState*); typedef struct EnBubble { /* 0x000 */ Actor actor; /* 0x144 */ EnBubbleActionFunc actionFunc; - /* 0x148 */ char unk_148[0x110]; + /* 0x148 */ ColliderJntSph colliderSphere; + /* 0x168 */ ColliderJntSphElement colliderElements[2]; + /* 0x1F4 */ Vec3f unk1F4; // set but never used + /* 0x1F4 */ Vec3f unk1F8; // randomly generated, set but never used + /* 0x200 */ s16 timer; // set to 8 when about to pop + /* 0x202 */ s16 explosionCountdown; + /* 0x204 */ UNK_TYPE1 pad204[4]; // unused + /* 0x208 */ f32 modelRotSpeed; + /* 0x20C */ f32 modelEllipticity; + /* 0x210 */ f32 unk_210; // set to 1.0f, never used + /* 0x214 */ f32 unk_214; // set to 1.0f, never used + /* 0x218 */ f32 modelWidth; + /* 0x21C */ f32 modelHeight; + /* 0x220 */ u8 bounceCount; + /* 0x224 */ Vec3f bounceDirection; + /* 0x230 */ Vec3f velocityFromBounce; + /* 0x23C */ Vec3f normalizedBumpVelocity; + /* 0x248 */ Vec3f velocityFromBump; + /* 0x254 */ f32 yVelocity; } EnBubble; // size = 0x258 extern const ActorInit En_Bubble_InitVars; diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index d0bc05b8b..287ca85e1 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -161,7 +161,7 @@ void EnElfbub_Draw(Actor* thisx, PlayState* play2) { Matrix_RotateZS(this->zRot * -1, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, object_bubble_DL_001000); + gSPDisplayList(POLY_XLU_DISP++, gBubbleDL); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index cddc0dc43..20fb6c0c2 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -5621,25 +5621,25 @@ 0x8089F2C4:("func_8089F2C4",), 0x8089F380:("EnViewer_Update",), 0x8089F3C8:("EnViewer_Draw",), - 0x8089F4E0:("func_8089F4E0",), + 0x8089F4E0:("EnBubble_SetDimensions",), 0x8089F59C:("func_8089F59C",), 0x8089F5D0:("func_8089F5D0",), - 0x8089F5F4:("func_8089F5F4",), - 0x8089F660:("func_8089F660",), + 0x8089F5F4:("EnBubble_DamagePlayer",), + 0x8089F660:("EnBubble_Explosion",), 0x8089F8BC:("func_8089F8BC",), 0x8089F908:("func_8089F908",), - 0x8089F95C:("func_8089F95C",), - 0x8089F9E4:("func_8089F9E4",), - 0x8089FA54:("func_8089FA54",), + 0x8089F95C:("EnBubble_Vec3fNormalizedReflect",), + 0x8089F9E4:("EnBubble_Vec3fNormalize",), + 0x8089FA54:("EnBubble_Fly",), 0x8089FF30:("func_8089FF30",), - 0x8089FFCC:("func_8089FFCC",), + 0x8089FFCC:("EnBubble_IsPopped",), 0x808A005C:("func_808A005C",), 0x808A0170:("EnBubble_Init",), 0x808A0270:("EnBubble_Destroy",), - 0x808A029C:("func_808A029C",), - 0x808A0350:("func_808A0350",), - 0x808A03A0:("func_808A03A0",), - 0x808A03E8:("func_808A03E8",), + 0x808A029C:("EnBubble_Wait",), + 0x808A0350:("EnBubble_Pop",), + 0x808A03A0:("EnBubble_Disappear",), + 0x808A03E8:("EnBubble_Regrow",), 0x808A0458:("EnBubble_Update",), 0x808A04D4:("EnBubble_Draw",), 0x808A08F0:("DoorShutter_SetupAction",), From bf2606586732d1dc39e48fe1b09b98fd668760be Mon Sep 17 00:00:00 2001 From: petrie911 <69443847+petrie911@users.noreply.github.com> Date: Wed, 14 Sep 2022 10:51:10 -0500 Subject: [PATCH 4/8] EnAz and EnTwig (Beaver bros and the minigame rings) (#999) * leave it to beavers * match * merge * catchup part 2 * fix warnings * I accidentally the xml * hopefully that's all of them * lol merge * linked object * now with more enums * Update src/overlays/actors/ovl_En_Az/z_en_az.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * more fixes * limbs and maths * stuff * more macro management * last enum? * more fixes * fixed * entrances Co-authored-by: petrie911 Co-authored-by: petrie911 Co-authored-by: petrie911 Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> --- include/z64actor.h | 2 +- include/z64math.h | 3 + spec | 8 +- src/overlays/actors/ovl_En_Az/z_en_az.c | 1814 ++++++++++++++++++- src/overlays/actors/ovl_En_Az/z_en_az.h | 40 +- src/overlays/actors/ovl_En_Twig/z_en_twig.c | 214 ++- src/overlays/actors/ovl_En_Twig/z_en_twig.h | 17 +- 7 files changed, 2014 insertions(+), 84 deletions(-) diff --git a/include/z64actor.h b/include/z64actor.h index 175d9ef22..bbf0a5534 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -83,7 +83,7 @@ typedef struct { typedef struct { /* 0x0 */ s16 unk_0; // frame? - /* 0x2 */ Vec3s unk_2; // pos? + /* 0x2 */ Vec3s unk_2; // scale } struct_80124618; // size = 0x8 typedef struct { diff --git a/include/z64math.h b/include/z64math.h index 16ab72e8a..323042b15 100644 --- a/include/z64math.h +++ b/include/z64math.h @@ -101,6 +101,9 @@ typedef struct { #define BINANG_LERPIMP(v0, v1, t) ((v0) + (s16)(BINANG_SUB((v1), (v0)) * (t))) #define BINANG_LERPIMPINV(v0, v1, t) ((v0) + BINANG_SUB((v1), (v0)) / (t)) +#define LERPWEIGHT(val, prev, next) (((val) - (prev)) / ((next) - (prev))) +#define F32_LERPWEIGHT(val, prev, next) (((f32)(val) - (f32)(prev)) / ((f32)(next) - (f32)(prev))) + #define VEC3F_LERPIMPDST(dst, v0, v1, t){ \ (dst)->x = (v0)->x + (((v1)->x - (v0)->x) * t); \ (dst)->y = (v0)->y + (((v1)->y - (v0)->y) * t); \ diff --git a/spec b/spec index a1ca83eb2..cb56bb471 100644 --- a/spec +++ b/spec @@ -3038,9 +3038,7 @@ beginseg name "ovl_En_Az" compress include "build/src/overlays/actors/ovl_En_Az/z_en_az.o" - include "build/data/ovl_En_Az/ovl_En_Az.data.o" - include "build/data/ovl_En_Az/ovl_En_Az.bss.o" - include "build/data/ovl_En_Az/ovl_En_Az.reloc.o" + include "build/src/overlays/actors/ovl_En_Az/ovl_En_Az_reloc.o" endseg beginseg @@ -3206,9 +3204,7 @@ beginseg name "ovl_En_Twig" compress include "build/src/overlays/actors/ovl_En_Twig/z_en_twig.o" - include "build/data/ovl_En_Twig/ovl_En_Twig.data.o" - include "build/data/ovl_En_Twig/ovl_En_Twig.bss.o" - include "build/data/ovl_En_Twig/ovl_En_Twig.reloc.o" + include "build/src/overlays/actors/ovl_En_Twig/ovl_En_Twig_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.c b/src/overlays/actors/ovl_En_Az/z_en_az.c index c025a6f77..a3594bec4 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.c +++ b/src/overlays/actors/ovl_En_Az/z_en_az.c @@ -5,28 +5,69 @@ */ #include "z_en_az.h" +#include "objects/object_az/object_az.h" +#include "overlays/actors/ovl_En_Twig/z_en_twig.h" +#include "overlays/actors/ovl_En_Fish/z_en_fish.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnAz*)thisx) +typedef struct { + /* 0x0 */ s16 unk_0; + /* 0x4 */ f32 unk_4; +} struct_80A98F94; // size = 0x8 + void EnAz_Init(Actor* thisx, PlayState* play); void EnAz_Destroy(Actor* thisx, PlayState* play); void EnAz_Update(Actor* thisx, PlayState* play); void EnAz_Draw(Actor* thisx, PlayState* play); +void func_80A982E0(PlayState* play, ActorPathing* actorPathing); +void func_80A98414(EnAz* this, PlayState* play); +s32 func_80A98DA4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void func_80A98E48(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); +void func_80A98EFC(EnAz* this, PlayState* play, u16 textId, s32 arg3, s32 arg4); +void func_80A98F94(struct_80A98F94* yData, f32 frame, f32* yInterp); + +void func_80A95C5C(EnAz* this, PlayState* play); void func_80A95CEC(EnAz* this, PlayState* play); + +void func_80A95DA0(EnAz* this, PlayState* play); void func_80A95E88(EnAz* this, PlayState* play); + +void func_80A95F94(EnAz* this, PlayState* play); void func_80A95FE8(EnAz* this, PlayState* play); + +void func_80A979DC(EnAz* this, PlayState* play); void func_80A979F4(EnAz* this, PlayState* play); + +void func_80A97A28(EnAz* this, PlayState* play); void func_80A97A40(EnAz* this, PlayState* play); + +void func_80A97A9C(EnAz* this, PlayState* play); void func_80A97AB4(EnAz* this, PlayState* play); + +void func_80A97C0C(EnAz* this, PlayState* play); void func_80A97C24(EnAz* this, PlayState* play); void func_80A97C4C(EnAz* this, PlayState* play); + +void func_80A97D5C(EnAz* this, PlayState* play); void func_80A97E48(EnAz* this, PlayState* play); + +void func_80A97EAC(EnAz* this, PlayState* play); void func_80A97F9C(EnAz* this, PlayState* play); -#if 0 +static AnimationSpeedInfo sAnimationInfo[14] = { + { &object_az_Anim_00BCFC, 1.0f, ANIMMODE_LOOP, -10.0f }, { &object_az_Anim_00C94C, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_az_Anim_008960, 1.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_008BB4, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_az_Anim_00925C, 1.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_009B4C, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_az_Anim_0086AC, 1.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_007D3C, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_az_Anim_008EAC, 2.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_00A25C, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_az_Anim_00AAEC, 1.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_00B94C, 1.0f, ANIMMODE_ONCE, -5.0f }, + { &object_az_Anim_00C0A0, 1.0f, ANIMMODE_LOOP, -5.0f }, { &object_az_Anim_00C47C, 1.0f, ANIMMODE_LOOP, -5.0f }, +}; + const ActorInit En_Az_InitVars = { ACTOR_EN_AZ, ACTORCAT_NPC, @@ -39,108 +80,1771 @@ const ActorInit En_Az_InitVars = { (ActorFunc)EnAz_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A99110 = { - { COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 46, 0, { 0, 0, 0 } }, }; -#endif +static EnAz* D_80A9913C = NULL; -extern ColliderCylinderInit D_80A99110; +Vec3f D_80A99E80; // path point? +f32 D_80A99E8C; // player distance to path point? +f32 D_80A99E90[2]; // unused? -extern UNK_TYPE D_0600C94C; -extern UNK_TYPE D_0601ABF0; +void func_80A94A30(EnAz* this) { + this->actor.velocity.y += this->actor.gravity; + if (this->actor.velocity.y < this->actor.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94A30.s") +void func_80A94A64(EnAz* this) { + func_80A94A30(this); + Actor_UpdatePos(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94A64.s") +s32 func_80A94A90(PlayState* play, ActorPathing* actorPathing) { + func_80A94A64((EnAz*)actorPathing->actor); + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94A90.s") +void func_80A94AB8(EnAz* this, PlayState* play, s32 spawnIndex) { + play->nextEntrance = Entrance_CreateFromSpawn(spawnIndex); + gSaveContext.nextCutsceneIndex = 0; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_03; + gSaveContext.nextTransitionType = TRANS_TYPE_03; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94AB8.s") +void func_80A94B20(PlayState* play) { + Actor* ring = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94B20.s") + do { + ring = SubS_FindActor(play, ring, ACTORCAT_MISC, ACTOR_EN_TWIG); + if (ring != NULL) { + if (RACERING_GET_PARAM_F(ring) == 1) { + Actor_MarkForDeath(ring); + } + ring = ring->next; + } + } while (ring != NULL); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A94B98.s") +s32 func_80A94B98(EnAz* this, PlayState* play) { + EnTwig* ring; + s32 ret = false; + Actor* misc = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/EnAz_Init.s") + do { + if (1) {} + ring = (EnTwig*)SubS_FindActor(play, misc, ACTORCAT_MISC, ACTOR_EN_TWIG); + if ((ring != NULL) && (RACERING_GET_PARAM_F(&ring->dyna.actor) == 1) && !(ring->unk_16C & 1)) { + ret = true; + break; + } + misc = ring->dyna.actor.next; + } while (misc != NULL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/EnAz_Destroy.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A954AC.s") +static InitChainEntry sInitChain[3] = { + ICHAIN_F32(uncullZoneScale, 80, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 80, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95534.s") +void EnAz_Init(Actor* thisx, PlayState* play2) { + static s16 D_80A9914C[7] = { 1, 0, 3, 2, 5, 4, -1 }; + static s16 D_80A9915C[7] = { 0, 1, 0, 1, 0, 1, 1 }; + EnAz* this = THIS; + PlayState* play = play2; + s16 sp4E; + s32 phi_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A9565C.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_374 = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 1; + switch (BEAVER_GET_PARAM_F00(thisx)) { + case 0: + phi_v1 = (gSaveContext.save.entrance == ENTRANCE(WATERFALL_RAPIDS, 0)) && + (gSaveContext.save.weekEventReg[93] & 1); + phi_v1 = !phi_v1; + break; + case 2: + phi_v1 = (gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 1)) || + !(gSaveContext.save.weekEventReg[24] & 4); + break; + case 4: + phi_v1 = gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 2); + break; + case 1: + phi_v1 = (gSaveContext.save.entrance == ENTRANCE(WATERFALL_RAPIDS, 0)) && + (gSaveContext.save.weekEventReg[93] & 1); + phi_v1 = !phi_v1; + break; + case 3: + phi_v1 = (gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 1)) || + (gSaveContext.save.weekEventReg[24] & 4); + break; + case 5: + phi_v1 = gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 2); + break; + case 6: + phi_v1 = (gSaveContext.save.entrance == ENTRANCE(WATERFALL_RAPIDS, 0)) && + !(gSaveContext.save.weekEventReg[93] & 1); + phi_v1 = !phi_v1; + break; + default: + phi_v1 = true; + break; + } + if (phi_v1) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95730.s") + this->unk_2F8 = D_80A9915C[BEAVER_GET_PARAM_F00(thisx)]; + if (BEAVER_GET_PARAM_F00(thisx) >= 0) { + sp4E = D_80A9914C[BEAVER_GET_PARAM_F00(thisx)]; + } else { + sp4E = -1; + } + if (this->unk_2F8 == 0) { + this->unk_374 |= 2; + } + SubS_FillCutscenesList(&this->actor, this->unk_3D0, ARRAY_COUNT(this->unk_3D0)); + if (D_80A9913C == NULL) { + D_80A9913C = THIS; + this->unk_374 |= 1; + } + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + if (this->unk_374 & 2) { + SkelAnime_InitFlex(play, &this->skelAnime, &object_az_Skel_007438, &object_az_Anim_00C94C, this->jointTable, + this->morphTable, OBJECT_AZ_1_LIMB_MAX); + Actor_SetScale(&this->actor, 0.012f); + } else { + SkelAnime_InitFlex(play, &this->skelAnime, &object_az_Skel_017990, &object_az_Anim_00C94C, this->jointTable, + this->morphTable, OBJECT_AZ_2_LIMB_MAX); + } + Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); + if (this->unk_374 & 2) { + this->collider.dim.radius *= 1.2f; + this->collider.dim.height *= 1.2f; + this->collider.dim.yShift *= 1.2f; + } + Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 5); + if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 22.0f)) { + this->unk_374 |= 0x100; + this->unk_376 |= 0x100; + } + Animation_Change(&this->skelAnime, sAnimationInfo[0].animation, 1.0f, + Animation_GetLastFrame(sAnimationInfo[0].animation) * Rand_ZeroOne(), + Animation_GetLastFrame(sAnimationInfo[0].animation), sAnimationInfo[0].mode, + sAnimationInfo[0].morphFrames); + this->unk_37E = 0; + this->unk_380 = 0; + this->unk_384 = 0; + this->actor.gravity = -1.0f; + this->unk_376 = this->unk_374; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + this->skelAnime.curFrame = Rand_ZeroOne() * this->skelAnime.endFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A958B0.s") + switch (gSaveContext.save.entrance) { + case ENTRANCE(WATERFALL_RAPIDS, 0): + if (gSaveContext.save.weekEventReg[93] & 1) { + this->unk_2FA = 5; + if (this->unk_374 & 2) { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->unk_374 |= 0x20; + } + } else { + this->unk_2FA = 0; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->unk_374 |= 0x20; + } + func_80A94B20(play); + if (this->unk_2FA == 5) { + func_80A97C0C(this, play); + } else { + func_80A95DA0(this, play); + } + break; + case ENTRANCE(WATERFALL_RAPIDS, 3): + this->unk_2FA = 0; + if (!(this->unk_374 & 2)) { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10000); + } + if (gSaveContext.save.entrance == ENTRANCE(WATERFALL_RAPIDS, 3)) { + this->unk_2FA = 0xA; + } + func_80A97C0C(this, play); + break; + case ENTRANCE(WATERFALL_RAPIDS, 1): + if (gSaveContext.save.weekEventReg[93] & 1) { + if (gSaveContext.save.weekEventReg[24] & 4) { + this->unk_2FA = 8; + } else { + this->unk_2FA = 6; + } + } else { + if (gSaveContext.save.weekEventReg[24] & 4) { + this->unk_2FA = 3; + } else { + this->unk_2FA = 1; + } + } + if (this->unk_374 & 1) { + SubS_CopyPointFromPathList(play->setupPathList, BEAVER_GET_PARAM_FF(thisx), + play->setupPathList[BEAVER_GET_PARAM_FF(thisx)].count - 1, &D_80A99E80); + } + if (gSaveContext.save.weekEventReg[24] & 4) { + if (this->unk_374 & 2) { + func_80A97D5C(this, play); + } else { + func_80A979DC(this, play); + } + } else if (this->unk_374 & 2) { + func_80A979DC(this, play); + } else { + func_80A97D5C(this, play); + } + break; + case ENTRANCE(WATERFALL_RAPIDS, 2): + if (gSaveContext.save.weekEventReg[93] & 1) { + if (gSaveContext.save.weekEventReg[24] & 4) { + this->unk_2FA = 9; + } else { + this->unk_2FA = 7; + } + } else { + if (gSaveContext.save.weekEventReg[24] & 4) { + this->unk_2FA = 4; + } else { + this->unk_2FA = 2; + } + } + if (this->unk_2FA == 2) { + if (!(this->unk_374 & 2)) { + this->unk_374 |= 0x20; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10000); + this->actionFunc = func_80A97C24; + } else { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + func_80A95C5C(this, play); + } + } else { + if (this->unk_374 & 2) { + this->unk_374 |= 0x20; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10000); + } else { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + } + this->actionFunc = func_80A97C24; + } + break; + } + if (sp4E >= 0) { + this->brother = NULL; + do { + this->brother = (EnAz*)SubS_FindActor(play, &this->brother->actor, ACTORCAT_NPC, ACTOR_EN_AZ); + if (this->brother != NULL) { + if (sp4E == BEAVER_GET_PARAM_F00(&this->brother->actor)) { + break; + } + this->brother = (EnAz*)this->brother->actor.next; + } + } while (this->brother != NULL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95B34.s") +void EnAz_Destroy(Actor* thisx, PlayState* play2) { + EnAz* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95C5C.s") + if (gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 1)) { + gSaveContext.unk_3DD0[4] = 5; + } + Collider_DestroyCylinder(play2, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95CEC.s") +f32 func_80A954AC(EnAz* this) { + ActorPathing* pathing = &this->unk_300; + Vec3f sp28; + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95DA0.s") + sp28.x = pathing->curPoint.x - this->actor.world.pos.x; + sp28.y = pathing->curPoint.y - this->actor.world.pos.y; + sp28.z = pathing->curPoint.z - this->actor.world.pos.z; + sp1C.x = pathing->curPoint.x - pathing->prevPoint.x; + sp1C.y = pathing->curPoint.y - pathing->prevPoint.y; + sp1C.z = pathing->curPoint.z - pathing->prevPoint.z; + return Math3D_Parallel(&sp28, &sp1C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95E88.s") +s32 func_80A95534(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95F94.s") + this->actor.world.rot.x = 0; + Math_SmoothStepToS(&this->unk_39E, this->actor.world.rot.x, 2, 0x71C, 0); + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 2, 0x71C, 0); + Math_SmoothStepToS(&this->actor.world.rot.y, actorPathing->rotToCurPoint.y, 1, 0xE38, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 0x71C, 0); + this->actor.gravity = -1.0f; + this->unk_36C = 1.5f; + if (actorPathing->curPointIndex == actorPathing->endPointIndex) { + if (actorPathing->distSqToCurPointXZ < this->unk_36C) { + this->unk_36C = actorPathing->distSqToCurPointXZ; + } + } + Math_SmoothStepToF(&this->actor.speedXZ, this->unk_36C, 0.8f, 2.0f, 0.0f); + actorPathing->moveFunc = SubS_ActorPathing_MoveWithGravity; + if (actorPathing->distSqToCurPointXZ <= this->actor.speedXZ) { + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A95FE8.s") +s32 func_80A9565C(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + s32 ret = false; + f32 temp_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A9617C.s") + this->actor.gravity = -1.0f; + actorPathing->moveFunc = func_80A94A90; + this->unk_374 |= 0x2000; + temp_f0 = func_80A954AC(this); + if ((actorPathing->distSqToCurPointXZ < SQ(this->actor.speedXZ)) || (temp_f0 <= 0.0f)) { + ret = true; + } else { + this->unk_39E = this->actor.world.rot.x = + Math_Atan2S(-this->actor.velocity.y, Math_CosS(-this->actor.world.rot.x) * this->actor.speedXZ); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97114.s") +s32 func_80A95730(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + s32 ret = false; + f32 temp_f0; + f32 sp40; + s32 sp3C; + s32 sp38; + s32 sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97274.s") + this->actor.gravity = 0.0f; + temp_f0 = func_80A954AC(this); + if ((actorPathing->distSqToCurPointXZ < SQ(this->actor.speedXZ)) || (temp_f0 <= 0.0f)) { + ret = true; + } else { + sp40 = SQ(this->actor.speedXZ) / actorPathing->distSqToCurPoint; + sp34 = ABS(actorPathing->rotToCurPoint.x - this->actor.world.rot.x); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A973B4.s") + sp3C = (s32)(sp34 * sp40) + 0xAAA; + sp34 = ABS(actorPathing->rotToCurPoint.y - this->actor.world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97410.s") + Math_SmoothStepToS(&this->actor.world.rot.x, actorPathing->rotToCurPoint.x, 1, sp3C, 0); + sp38 = (s32)(sp34 * sp40) + 0xAAA; + Math_SmoothStepToS(&this->actor.world.rot.y, actorPathing->rotToCurPoint.y, 1, sp38, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A979DC.s") + Math_SmoothStepToS(&this->unk_39E, this->actor.world.rot.x, 2, sp3C, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, sp38, 0); + } + actorPathing->moveFunc = SubS_ActorPathing_MoveWithoutGravityReverse; + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A979F4.s") +s32 func_80A958B0(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + s32 ret = false; + f32 temp; + f32 phi_f0; + f32 temp1; + f32 temp2; + f32 sp3C; + s32 sp2C; + s32 sp28; + s32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97A28.s") + this->actor.gravity = 0.0f; + temp2 = D_80A99E8C; + temp = D_80A99E90[this->unk_2F8]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97A40.s") + if (temp <= temp2) { + phi_f0 = (this->unk_374 & 2) ? 480.0f : 240.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97A9C.s") + if (this->actor.xzDistToPlayer < phi_f0) { + Math_SmoothStepToF(&this->unk_36C, 12.0f, 0.8f, 0.5f, 0.01f); + } else { + Math_SmoothStepToF(&this->unk_36C, 6.0f, 0.8f, 0.5f, 0.01f); + } + } else { + Math_SmoothStepToF(&this->unk_36C, 26.0f, 0.5f, 1.0f, 0.01f); + } + Math_SmoothStepToF(&this->actor.speedXZ, this->unk_36C, 0.8f, 2.0f, 0.0f); + temp1 = func_80A954AC(this); + if ((actorPathing->distSqToCurPointXZ < SQ(this->actor.speedXZ)) || (temp1 <= 0.0f)) { + ret = true; + } else { + sp3C = SQ(this->actor.speedXZ) / actorPathing->distSqToCurPoint; + sp30 = ABS(actorPathing->rotToCurPoint.x - this->actor.world.rot.x); + sp2C = (s32)(sp30 * sp3C) + 0xAAA; + sp30 = ABS(actorPathing->rotToCurPoint.y - this->actor.world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97AB4.s") + Math_SmoothStepToS(&this->actor.world.rot.x, actorPathing->rotToCurPoint.x, 1, sp2C, 0); + sp28 = (s32)(sp30 * sp3C) + 0xAAA; + Math_SmoothStepToS(&this->actor.world.rot.y, actorPathing->rotToCurPoint.y, 1, sp28, 0); + Math_SmoothStepToS(&this->unk_39E, this->actor.world.rot.x, 2, sp2C, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, sp28, 0); + } + actorPathing->moveFunc = SubS_ActorPathing_MoveWithoutGravityReverse; + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97C0C.s") +s32 func_80A95B34(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + s32 ret; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97C24.s") + if (this->unk_374 & 0x100) { + if (!(this->unk_374 & 8)) { + if (this->unk_374 & 2) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 8, &this->animIndex); + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 2, &this->animIndex); + } + this->unk_374 |= 8; + } + if (this->unk_2FA == 0) { + ret = func_80A95730(play, actorPathing); + } else { + ret = func_80A958B0(play, actorPathing); + } + } else if (this->actor.bgCheckFlags & 1) { + if (this->unk_374 & 8) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 1, &this->animIndex); + this->unk_374 &= ~8; + } + ret = func_80A95534(play, actorPathing); + } else { + ret = func_80A9565C(play, actorPathing); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97C4C.s") +void func_80A95C5C(EnAz* this, PlayState* play) { + this->actor.draw = NULL; + this->actor.world.pos.y = this->actor.home.pos.y + 120.0f; + this->actor.gravity = -1.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.bgCheckFlags &= ~0x21; + this->unk_3C0 = 0; + this->actionFunc = func_80A95CEC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97D5C.s") +void func_80A95CEC(EnAz* this, PlayState* play) { + if (this->unk_374 & 0x8000) { + if (!(this->actor.bgCheckFlags & 1)) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.draw = EnAz_Draw; + Actor_MoveWithGravity(&this->actor); + func_800B9010(&this->actor, NA_SE_EV_HONEYCOMB_FALL - SFX_FLAG); + } else { + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + } + if (SubS_StartActorCutscene(&this->actor, 0x7C, this->unk_3D0[0], SUBS_CUTSCENE_NORMAL)) { + func_80A97C0C(this, play); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97E48.s") +void func_80A95DA0(EnAz* this, PlayState* play) { + ActorPathing* sp40 = &this->unk_300; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97EAC.s") + SubS_ActorPathing_Init(play, &this->actor.world.pos, &this->actor, sp40, play->setupPathList, + BEAVER_GET_PARAM_FF(&this->actor), 0, 0, 1, 1); + this->unk_36C = 4.0f; + this->actor.speedXZ = 4.0f; + this->actor.gravity = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 2, &this->animIndex); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.bgCheckFlags &= ~0x21; + this->unk_374 |= 0x1000; + Math_Vec3f_Copy(&this->actor.world.pos, &sp40->curPoint); + this->actionFunc = func_80A95E88; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A97F9C.s") +void func_80A95E88(EnAz* this, PlayState* play) { + SubS_ActorPathing_Update(play, &this->unk_300, func_80A982E0, func_80A95B34, SubS_ActorPathing_MoveWithGravity, + SubS_ActorPathing_SetNextPoint); + if (this->actor.depthInWater > 8.0f) { + if (this->unk_374 & 2) { + if ((this->skelAnime.curFrame < this->skelAnime.playSpeed) && (this->skelAnime.curFrame >= 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BEAVER_SWIM_HAND); + } + } else { + func_800B9010(&this->actor, NA_SE_EV_BEAVER_SWIM_MOTOR - SFX_FLAG); + } + } + if (!(this->unk_374 & 0x2000)) { + SkelAnime_Update(&this->skelAnime); + } + this->unk_374 &= ~0x2000; + if (this->actor.isTargeted) { + func_80A95F94(this, play); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A982E0.s") +void func_80A95F94(EnAz* this, PlayState* play) { + func_800BE33C(&this->actor.world.pos, &this->actor.home.pos, &this->actor.world.rot, 0); + this->unk_39E = 0; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = func_80A95FE8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A98414.s") +void func_80A95FE8(EnAz* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + if (ActorCutscene_GetCanPlayNext(this->unk_3D0[0])) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_3D0[0], &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->unk_3D0[0]); + } + if (Actor_DistanceToPoint(&this->actor, &this->actor.home.pos) > 20.0f) { + func_800B9010(&this->actor, NA_SE_EV_BEAVER_SWIM_MOTOR - SFX_FLAG); + func_800BE33C(&this->actor.world.pos, &this->actor.home.pos, &this->actor.world.rot, 0); + Math_SmoothStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x, 3, 0xE38, 0x38E); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0xE38, 0x38E); + this->actor.shape.rot.z = 0; + Actor_MoveWithoutGravityReverse(&this->actor); + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + this->unk_374 &= ~0x1000; + this->actor.gravity = -1.0f; + this->actor.speedXZ = 0.0f; + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 3, 0x1000, 0x100); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x1038, 0x100); + if (this->actor.bgCheckFlags & 1) { + this->actor.shape.rot.x = 0; + this->actor.gravity = 0.0f; + func_80A97C0C(this, play); + ActorCutscene_Stop(this->unk_3D0[0]); + } + Actor_MoveWithGravity(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/EnAz_Update.s") +s32 func_80A9617C(EnAz* this, PlayState* play) { + s32 pad[2]; + s32 ret = 2; + EnAz* brother = this->brother; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/EnAz_Draw.s") + switch (Message_GetState(&play->msgCtx)) { + case TEXT_STATE_CHOICE: + case TEXT_STATE_5: + case TEXT_STATE_DONE: + if ((play->msgCtx.currentTextId == 0x10DD) && (this->unk_374 & 0x8000)) { + if (SubS_StartActorCutscene(&brother->actor, brother->unk_3D0[0], 0x7C, SUBS_CUTSCENE_NORMAL)) { + brother->unk_374 |= 0x8000; + play->msgCtx.msgMode = 0x44; + ret = 0; + } + } else if (Message_ShouldAdvance(play)) { + ret = 3; + switch (play->msgCtx.currentTextId) { + case 0x70: + case 0xCD: + gSaveContext.save.weekEventReg[24] &= (u8)~1; + this->actor.textId = 0x10F2; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 11, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 11, &brother->animIndex); + break; + case 0x10CE: + this->actor.textId = 0x10CF; + gSaveContext.save.weekEventReg[16] |= 0x40; + break; + case 0x10CF: + this->actor.textId = 0x10D0; + break; + case 0x10D0: + this->actor.textId = 0x10D1; + ret = 3; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 5, &this->animIndex); + break; + case 0x10D1: + this->actor.textId = 0x10D2; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10D2: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + this->actor.textId = 0x10D6; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 5, &this->animIndex); + } else { + func_8019F230(); + this->actor.textId = 0x10D3; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 11, &this->animIndex); + } + break; + case 0x10D3: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + this->unk_374 |= 0x20; + ret = 0; + break; + case 0x10D4: + this->actor.textId = 0x10D2; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10D6: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + func_80A979DC(this, play); + this->unk_2FA = 1; + ret = 0; + break; + case 0x10D7: + this->actor.textId = 0x10D8; + break; + case 0x10D8: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + switch (this->unk_2FA) { + case 2: + this->unk_2FA = 1; + break; + case 4: + this->unk_2FA = 3; + break; + case 7: + this->unk_2FA = 6; + break; + case 9: + this->unk_2FA = 8; + break; + } + ret = 0; + } else { + func_8019F230(); + this->actor.textId = 0x10D9; + } + break; + case 0x10D9: + if ((this->unk_2FA == 3) || (this->unk_2FA == 8)) { + gSaveContext.save.weekEventReg[24] &= (u8)~4; + } + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + ret = 0; + break; + case 0x10DA: + this->actor.textId = 0x10DB; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10DB: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + play->msgCtx.msgMode = 0x44; + this->unk_2FA = 1; + ret = 0; + } else { + func_8019F230(); + this->actor.textId = 0x10DC; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 11, &this->animIndex); + } + break; + case 0x10DC: + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + this->unk_374 |= 0x20; + ret = 0; + break; + case 0x10DD: + func_80A98EFC(this, play, 0x10DE, 13, 9); + this->unk_374 |= 0x8000; + ret = 2; + break; + case 0x10DE: + func_80A98EFC(this, play, 0x10DF, 12, 10); + ret = 0; + break; + case 0x10DF: + func_80A98EFC(this, play, 0x10E0, 13, 9); + ret = 0; + break; + case 0x10E0: + func_80A98EFC(this, play, 0x10E1, 12, 10); + ret = 0; + break; + case 0x10E1: + func_80A98EFC(this, play, 0x10E2, 13, 9); + ret = 0; + break; + case 0x10E2: + this->actor.textId = 0x10E3; + ret = 3; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10E3: + func_80A98EFC(this, play, 0x10E4, 0, 4); + ret = 0; + break; + case 0x10E4: + func_80A98EFC(this, play, 0x10E5, 0, 4); + ret = 0; + break; + case 0x10E5: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + this->actor.textId = 0x10E8; + } else { + func_8019F230(); + this->actor.textId = 0x10E6; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 9, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 13, + &brother->animIndex); + } + break; + case 0x10E6: + this->actor.textId = 0x10E7; + func_80A98EFC(this, play, 0x10E7, 0, 10); + ret = 0; + break; + case 0x10E7: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + func_80A94AB8(this, play, 0); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + func_80A979DC(this, play); + ret = 0; + break; + case 0x10E8: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + this->unk_2FA = 3; + ret = 0; + break; + case 0x10E9: + func_80A98EFC(this, play, 0x10EA, 12, 4); + ret = 0; + break; + case 0x10EA: + func_80A98EFC(this, play, 0x10EB, 0, 4); + ret = 0; + break; + case 0x10EB: + if (play->msgCtx.choiceIndex == 0) { + play->msgCtx.msgMode = 0x44; + func_8019F208(); + switch (this->unk_2FA) { + case 4: + this->unk_2FA = 3; + break; + case 7: + this->unk_2FA = 6; + break; + case 9: + default: + this->unk_2FA = 8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A98DA4.s") + break; + } + ret = 0; + } else { + func_8019F230(); + this->actor.textId = 0x10EC; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 7, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 13, + &brother->animIndex); + } + break; + case 0x10EC: + func_80A98EFC(this, play, 0x10ED, -1, 6); + ret = 0; + break; + case 0x10ED: + if ((this->unk_2FA == 4) || (this->unk_2FA == 9)) { + gSaveContext.save.weekEventReg[24] &= (u8)~4; + } + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + ret = 0; + break; + case 0x10EE: + func_80A98EFC(this, play, 0x10EF, 12, 10); + ret = 0; + break; + case 0x10EF: + func_80A98EFC(this, play, 0x10F0, 13, 9); + ret = 0; + break; + case 0x10F0: + func_80A98EFC(this, play, 0x10F1, 12, 10); + ret = 0; + break; + case 0x10F1: + gSaveContext.save.weekEventReg[93] |= 1; + if (gSaveContext.save.weekEventReg[23] & 0x80) { + this->getItemId = GI_RUPEE_RED; + } else { + this->getItemId = GI_BOTTLE; + gSaveContext.save.weekEventReg[23] |= 0x80; + } + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + ret = 7; + break; + case 0x10F2: + case 0x1109: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + ret = 0; + break; + case 0x10F3: + func_80A98EFC(this, play, 0x10F4, 12, 10); + ret = 0; + break; + case 0x10F4: + func_80A98EFC(this, play, 0x10F5, 13, 9); + ret = 0; + break; + case 0x10F5: + func_80A98EFC(this, play, 0x10F6, 12, 10); + ret = 0; + break; + case 0x10F6: + func_80A98EFC(this, play, 0x10F7, 13, 5); + ret = 0; + break; + case 0x10F7: + this->actor.textId = 0x10F8; + ret = 3; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10F8: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + if (gSaveContext.save.weekEventReg[25] & 1) { + this->actor.textId = 0x1107; + } else { + this->actor.textId = 0x10FA; + } + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 5, &this->animIndex); + } else { + func_8019F230(); + this->actor.textId = 0x10F9; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 11, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 11, + &brother->animIndex); + } + break; + case 0x10F9: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + this->unk_374 |= 0x20; + ret = 0; + break; + case 0x10FA: + case 0x1107: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + this->unk_2FA = 6; + ret = 0; + break; + case 0x10FB: + func_80A98EFC(this, play, 0x10FC, 12, 10); + ret = 0; + break; + case 0x10FC: + func_80A98EFC(this, play, 0x10FD, 13, 4); + ret = 0; + break; + case 0x10FD: + this->actor.textId = 0x10FE; + ret = 3; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + break; + case 0x10FE: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + if (gSaveContext.save.weekEventReg[25] & 1) { + this->actor.textId = 0x1108; + } else { + this->actor.textId = 0x1101; + } + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + } else { + func_8019F230(); + this->actor.textId = 0x10FF; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 9, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 13, + &brother->animIndex); + } + break; + case 0x10FF: + func_80A98EFC(this, play, 0x1100, 12, 10); + ret = 0; + break; + case 0x1100: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + ret = 0; + break; + case 0x1101: + case 0x1108: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + this->unk_2FA = 8; + ret = 0; + break; + case 0x1102: + func_80A98EFC(this, play, 0x1103, 12, 10); + ret = 0; + break; + case 0x1103: + func_80A98EFC(this, play, 0x1104, 13, 9); + ret = 0; + break; + case 0x1104: + func_80A98EFC(this, play, 0x1105, 12, 10); + ret = 0; + break; + case 0x1105: + if (gSaveContext.save.weekEventReg[25] & 1) { + this->getItemId = GI_RUPEE_PURPLE; + } else { + this->getItemId = GI_HEART_PIECE; + gSaveContext.save.weekEventReg[25] |= 1; + } + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + ret = 7; + break; + case 0x1106: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 0, &brother->animIndex); + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + ret = 0; + break; + case 0x10D5: + default: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + this->unk_374 |= 0x20; + ret = 0; + break; + } + } + break; + case TEXT_STATE_NONE: + case TEXT_STATE_1: + case TEXT_STATE_CLOSING: + case TEXT_STATE_3: + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A98E48.s") +void func_80A97114(EnAz* this, PlayState* play) { + EnAz* brother = this->brother; + s32 sp20 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A98EFC.s") + this->actor.flags &= ~ACTOR_FLAG_10000; + switch (this->actor.textId) { + case 0x10DA: + case 0x10DD: + case 0x10E9: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10EE: + case 0x10F3: + case 0x10FB: + case 0x1102: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 9, &this->animIndex); + sp20 = true; + break; + case 0x10F2: + case 0x1106: + case 0x1109: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 11, &this->animIndex); + if (brother != NULL) { + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 11, &brother->animIndex); + } + break; + } + if ((brother != NULL) && sp20) { + if (this->unk_374 & 2) { + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 13, &brother->animIndex); + } else { + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, 12, &brother->animIndex); + } + } + this->unk_374 &= ~0x20; + this->unk_378 = 2; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Az/func_80A98F94.s") +s32 func_80A97274(EnAz* this, PlayState* play) { + s32 textId; + + if (this->unk_374 & 0x4000) { + return 0x10D7; + } + switch (this->unk_2FA) { + case 0: + default: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + if (!(gSaveContext.save.weekEventReg[16] & 0x40)) { + textId = 0x10CE; + } else { + textId = 0x10D4; + } + break; + case 2: + if (gSaveContext.save.weekEventReg[24] & 1) { + gSaveContext.save.weekEventReg[24] |= 4; + this->unk_3C0 = 0; + textId = 0x10DD; + } else { + textId = 0x10DA; + } + break; + case 4: + if (gSaveContext.save.weekEventReg[24] & 1) { + textId = 0x10EE; + } else { + textId = 0x10E9; + } + break; + case 5: + gSaveContext.save.weekEventReg[24] &= (u8)~4; + textId = 0x10F3; + break; + case 7: + if (gSaveContext.save.weekEventReg[24] & 1) { + gSaveContext.save.weekEventReg[24] |= 4; + textId = 0x10FB; + } else { + textId = 0x10E9; + } + break; + case 9: + if (gSaveContext.save.weekEventReg[24] & 1) { + textId = 0x1102; + } else { + textId = 0x10E9; + } + break; + } + return textId; +} + +s32 func_80A973B4(EnAz* this, PlayState* play) { + s32 ret = 0; + + if (this->getItemId != GI_RUPEE_RED) { + if ((this->getItemId != GI_RUPEE_PURPLE) && (this->getItemId != GI_HEART_PIECE)) { + if (this->getItemId == GI_BOTTLE) { + ret = 0x10F2; + } + } else { + ret = 0x1106; + } + } else { + ret = 0x1109; + } + this->unk_374 |= 0x20; + + return ret; +} + +void func_80A97410(EnAz* this, PlayState* play) { + s16 sp56; + s16 sp54; + s32 temp_a0; + + if (this->unk_378 != 0) { + Vec3f* thisPos = &this->actor.world.pos; + + if ((this->unk_2FA == 0) && !(this->unk_374 & 2)) { + Math_SmoothStepToS(&this->unk_3D4, 0, 2, 0x71C, 0xA); + Math_SmoothStepToS(&this->unk_3D6, 0, 3, 0x71C, 0xA); + } + if (this->brother != NULL) { + Vec3f* broPos = &this->brother->actor.world.pos; + + if (this->unk_374 & 0x40) { + this->actor.focus.pos.x = (thisPos->x * 0.5f) + (broPos->x * 0.5f); + this->actor.focus.pos.y = (thisPos->y * 0.5f) + (broPos->y * 0.5f) + 45.0f; + this->actor.focus.pos.z = (thisPos->z * 0.5f) + (broPos->z * 0.5f); + } else { + this->actor.focus.pos.x = (thisPos->x * 0.7f) + (broPos->x * 0.3f); + this->actor.focus.pos.y = (thisPos->y * 0.7f) + (broPos->y * 0.3f) + 45.0f; + this->actor.focus.pos.z = (thisPos->z * 0.7f) + (broPos->z * 0.3f); + } + } else { + this->actor.focus.pos.x = thisPos->x; + this->actor.focus.pos.y = thisPos->y; + this->actor.focus.pos.z = thisPos->z; + } + 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; + } + if (this->unk_378 == 2) { + this->unk_378 = func_80A9617C(this, play); + if (this->unk_378 == 0) { + this->actor.flags &= ~ACTOR_FLAG_10000; + } + } + if (this->unk_378 == 3) { + func_80151938(play, this->actor.textId); + this->unk_378 = 2; + } else if (this->unk_378 == 5) { + Message_StartTextbox(play, this->actor.textId, &this->actor); + this->unk_378 = 2; + } else { + if ((this->unk_378 == 6) || (this->unk_378 == 7)) { + if (Actor_HasParent(&this->actor, play)) { + this->actor.parent = NULL; + if (this->unk_378 == 7) { + this->unk_378 = 1; + this->unk_374 |= 0x20; + } else { + this->unk_378 = 0; + } + } else { + Actor_PickUp(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer, + this->actor.playerHeightRel); + } + } + if (this->unk_378 == 9) { + temp_a0 = Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38, 0x222); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (temp_a0 == 0) { + switch (this->unk_3D2) { + case 0x10CE: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 4, &this->animIndex); + break; + case 0x10D4: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 5, &this->animIndex); + break; + } + Message_StartTextbox(play, this->unk_3D2, &this->actor); + this->actor.textId = this->unk_3D2; + this->unk_378 = 2; + } + } else if (((this->unk_378 == 0) || (this->unk_378 == 1)) && (this->unk_374 & 0x20)) { + if (this->unk_378 == 1) { + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + func_80A97114(this, play); + this->unk_378 = 2; + } else if (func_800B8500(&this->actor, play, this->actor.xzDistToPlayer, this->actor.playerHeightRel, + PLAYER_AP_MINUS1)) { + this->actor.textId = func_80A973B4(this, play); + } + } else { + if ((this->unk_2FA == 0) && !(this->unk_374 & 2)) { + Player* player = GET_PLAYER(play); + Vec3f sp38; + s16 temp_a1_2 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + s16 temp_v0_7; + + if (ABS(temp_a1_2) < 0x1800) { + Math_SmoothStepToS(&this->unk_3D4, temp_a1_2, 2, 0x71C, 0); + } else { + Math_SmoothStepToS(&this->unk_3D4, 0, 2, 0x71C, 0); + } + Math_Vec3f_Copy(&sp38, &player->actor.world.pos); + sp38.y = player->bodyPartsPos[7].y + 3.0f; + temp_v0_7 = Math_Vec3f_Pitch(&this->actor.focus.pos, &sp38); + if (ABS(temp_v0_7) < 0x800) { + Math_SmoothStepToS(&this->unk_3D6, temp_v0_7, 3, 0x71C, 0); + } else { + Math_SmoothStepToS(&this->unk_3D6, 0, 3, 0x71C, 0); + } + } + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + func_80A97114(this, play); + this->unk_378 = 2; + if ((this->unk_3D2 == 0x10CE) || (this->unk_3D2 == 0x10D4)) { + this->unk_378 = 9; + } + } else { + Actor_GetScreenPos(play, &this->actor, &sp56, &sp54); + if ((sp56 >= 0) && (sp56 <= SCREEN_WIDTH) && (sp54 >= 0) && (sp54 <= SCREEN_HEIGHT) && + func_800B8500(&this->actor, play, 120.0f, 120.0f, 0)) { + this->unk_3D2 = func_80A97274(this, play); + if ((this->unk_3D2 == 0x10CE) || (this->unk_3D2 == 0x10D4)) { + this->actor.textId = 0; + } else { + this->actor.textId = this->unk_3D2; + } + } + } + } + } + } +} + +void func_80A979DC(EnAz* this, PlayState* play) { + this->actionFunc = func_80A979F4; +} + +void func_80A979F4(EnAz* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + Actor_MoveWithGravity(&this->actor); +} + +void func_80A97A28(EnAz* this, PlayState* play) { + this->actionFunc = func_80A97A40; +} + +void func_80A97A40(EnAz* this, PlayState* play) { + if (SubS_StartActorCutscene(&this->actor, 0, -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + play->msgCtx.msgMode = 0; + play->msgCtx.msgLength = 0; + func_80A97A9C(this, play); + } +} + +void func_80A97A9C(EnAz* this, PlayState* play) { + this->actionFunc = func_80A97AB4; +} + +void func_80A97AB4(EnAz* this, PlayState* play) { + switch (Message_GetState(&play->msgCtx)) { + case TEXT_STATE_NONE: + Message_StartTextbox(play, 0x10D7, NULL); + break; + case TEXT_STATE_CHOICE: + case TEXT_STATE_5: + case TEXT_STATE_DONE: + if (Message_ShouldAdvance(play)) { + switch (play->msgCtx.currentTextId) { + case 0x10D7: + func_80151938(play, 0x10D8); + break; + case 0x10D8: + if (play->msgCtx.choiceIndex == 0) { + func_8019F208(); + play->msgCtx.msgMode = 0x44; + func_800FD750(NA_BGM_MINI_GAME_2); + func_80A94AB8(this, play, 1); + func_80A979DC(this, play); + } else { + func_8019F230(); + if (gSaveContext.save.weekEventReg[24] & 4) { + gSaveContext.save.weekEventReg[24] &= (u8)~4; + } + func_80151938(play, 0x10D9); + } + break; + case 0x10D9: + func_80A94AB8(this, play, 0); + func_80A979DC(this, play); + break; + } + } + case TEXT_STATE_1: + case TEXT_STATE_CLOSING: + break; + } +} + +void func_80A97C0C(EnAz* this, PlayState* play) { + this->actionFunc = func_80A97C4C; +} + +void func_80A97C24(EnAz* this, PlayState* play) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = func_80A97C4C; +} + +void func_80A97C4C(EnAz* this, PlayState* play) { + if (SkelAnime_Update(&this->skelAnime) && (this->animIndex == 0xB)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 0, &this->animIndex); + } + func_80A97410(this, play); + if ((this->unk_2FA == 1) || (this->unk_2FA == 3) || (this->unk_2FA == 6) || (this->unk_2FA == 8)) { + gSaveContext.save.weekEventReg[24] &= (u8)~1; + func_800FD750(NA_BGM_MINI_GAME_2); + play->nextEntrance = Entrance_CreateFromSpawn(1); + gSaveContext.nextCutsceneIndex = 0; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_80; + gSaveContext.nextTransitionType = TRANS_TYPE_03; + func_80A979DC(this, play); + } else { + Actor_MoveWithGravity(&this->actor); + } +} + +void func_80A97D5C(EnAz* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + player->stateFlags1 |= PLAYER_STATE1_20; + func_80112AFC(play); + gSaveContext.minigameScore = (this->unk_374 & 2) ? 25 : 20; + play->interfaceCtx.unk_280 = 1; + if ((this->unk_2FA == 1) || (this->unk_2FA == 3)) { + func_8010E9F0(4, 120); + } else if (gSaveContext.save.weekEventReg[25] & 1) { + func_8010E9F0(4, 100); + } else { + func_8010E9F0(4, 110); + } + this->actionFunc = func_80A97E48; +} + +void func_80A97E48(EnAz* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (play->interfaceCtx.unk_280 >= 8) { + player->stateFlags1 &= ~PLAYER_STATE1_20; + func_80A97EAC(this, play); + } + Actor_MoveWithGravity(&this->actor); + SkelAnime_Update(&this->skelAnime); +} + +void func_80A97EAC(EnAz* this, PlayState* play) { + SubS_ActorPathing_Init(play, &this->actor.world.pos, &this->actor, &this->unk_300, play->setupPathList, + BEAVER_GET_PARAM_FF(&this->actor), 0, 0, 1, 0); + this->unk_36C = 8.0f; + this->actor.speedXZ = 8.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 6.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, 2, &this->animIndex); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.bgCheckFlags &= ~0x21; + this->unk_374 |= 0x1000; + this->unk_3C2 = 0; + this->unk_3C4 = 0; + this->actionFunc = func_80A97F9C; +} + +void func_80A97F9C(EnAz* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + D_80A99E8C = + Math3D_XZDistanceSquared(player->actor.world.pos.x, player->actor.world.pos.z, D_80A99E80.x, D_80A99E80.z); + if (Math3D_XZDistanceSquared(this->actor.world.pos.x, this->actor.world.pos.z, D_80A99E80.x, D_80A99E80.z) >= + SQ(1000.0f)) { + this->unk_374 |= 0x1000; + } + if (!(this->unk_300.flags & ACTOR_PATHING_REACHED_END_PERMANENT)) { + SubS_ActorPathing_Update(play, &this->unk_300, func_80A982E0, func_80A95B34, SubS_ActorPathing_MoveWithGravity, + SubS_ActorPathing_SetNextPoint); + } + if (!(this->unk_374 & 0x10) && + SurfaceType_IsHorseBlocked(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId)) { + this->unk_374 |= 0x10; + } + if (SurfaceType_IsHorseBlocked(&play->colCtx, player->actor.floorPoly, player->actor.floorBgId)) { + if (func_80A94B98(this, play)) { + gSaveContext.save.weekEventReg[24] &= (u8)~1; + } else { + gSaveContext.save.weekEventReg[24] |= 1; + } + gSaveContext.unk_3DD0[4] = 5; + this->unk_374 &= ~0x10; + play->nextEntrance = Entrance_CreateFromSpawn(2); + gSaveContext.nextCutsceneIndex = 0; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_03; + gSaveContext.nextTransitionType = TRANS_TYPE_03; + this->actor.speedXZ = 0.0f; + func_80A979DC(this, play); + } else { + if (gSaveContext.unk_3DE0[4] == 0) { + gSaveContext.unk_3DD0[4] = 5; + this->unk_374 |= 0x4000; + func_80A97A28(this, play); + } + if (this->unk_374 & 0x100) { + if (this->actor.flags & ACTOR_FLAG_40) { + func_80A98414(this, play); + } + if ((DECR(this->unk_37A) == 0) && (this->actor.flags & ACTOR_FLAG_40)) { + EffectSsBubble_Spawn(play, &this->actor.world.pos, 0.0f, 20.0f, 20.0f, 0.35f); + this->unk_37A = (Rand_ZeroOne() * 70.0f) + 10.0f; + } + } + if (this->actor.depthInWater > 8.0f) { + if (this->unk_374 & 2) { + if ((this->skelAnime.curFrame < this->skelAnime.playSpeed) && (this->skelAnime.curFrame >= 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BEAVER_SWIM_HAND); + } + } else { + func_800B9010(&this->actor, NA_SE_EV_BEAVER_SWIM_MOTOR - SFX_FLAG); + } + } + SkelAnime_Update(&this->skelAnime); + } +} + +void func_80A982E0(PlayState* play, ActorPathing* actorPathing) { + EnAz* this = (EnAz*)actorPathing->actor; + Vec3f sp28; + + actorPathing->curPoint.x = actorPathing->points[actorPathing->curPointIndex].x; + if (this->actor.bgCheckFlags & 1) { + actorPathing->curPoint.y = actorPathing->points[actorPathing->curPointIndex].y; + } else { + actorPathing->curPoint.y = actorPathing->points[actorPathing->curPointIndex].y - this->unk_3A4; + } + actorPathing->curPoint.z = actorPathing->points[actorPathing->curPointIndex].z; + sp28.x = actorPathing->curPoint.x - actorPathing->worldPos->x; + sp28.y = actorPathing->curPoint.y - actorPathing->worldPos->y; + sp28.z = actorPathing->curPoint.z - actorPathing->worldPos->z; + actorPathing->distSqToCurPointXZ = Math3D_XZLengthSquared(sp28.x, sp28.z); + actorPathing->distSqToCurPoint = Math3D_LengthSquared(&sp28); + actorPathing->rotToCurPoint.y = Math_FAtan2F(sp28.z, sp28.x); + actorPathing->rotToCurPoint.x = Math_FAtan2F(sqrtf(actorPathing->distSqToCurPointXZ), -sp28.y); + actorPathing->rotToCurPoint.z = 0; +} + +void func_80A98414(EnAz* this, PlayState* play) { + Actor* itemAction = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + + while (itemAction != NULL) { + if (itemAction->id == ACTOR_EN_FISH) { + EnFish* fish = (EnFish*)itemAction; + + if ((fish->actor.params < 0) && (fish->actor.room == this->actor.room) && + (Math3D_Vec3fDistSq(&this->actor.world.pos, &fish->actor.world.pos) < SQ(200.0f))) { + fish->unk_276 = 0x14; + fish->unk_274 = Actor_YawBetweenActors(&fish->actor, &this->actor); + } + } + itemAction = itemAction->next; + } +} + +void EnAz_Update(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnAz* this = THIS; + + this->unk_374 &= ~0x100; + if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 22.0f)) { + if (!(this->unk_376 & 0x100)) { + this->unk_374 |= 0x200; + } + this->unk_374 |= 0x100; + } else if (this->unk_376 & 0x100) { + this->unk_374 |= 0x400; + } + this->actionFunc(this, play); + Actor_SetFocus(&this->actor, 40.0f); + if (this->unk_374 & 0x200) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_INTO_WATER); + } + if (this->unk_374 & 0x400) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_JUMP_OUT_WATER); + } + this->unk_37E++; + if (this->unk_37E >= 4) { + this->unk_37E = 0; + } + this->unk_380++; + if (this->unk_380 >= 3) { + this->unk_380 = 0; + } + this->unk_384--; + if (this->unk_384 < 0) { + this->unk_384 = 2; + } + this->unk_39C++; + if (this->unk_39C >= 16) { + this->unk_39C = 0; + } + if (!(this->unk_374 & 0x1000)) { + Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 5); + } else { + Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 0x400); + this->unk_374 &= ~0x1000; + } + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + + this->unk_376 = this->unk_374; + this->unk_374 &= ~0x600; + + if (GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER) { + this->unk_374 |= 0x800; + } else { + this->unk_374 &= ~0x800; + } +} + +static Gfx* D_80A9916C[5] = { + object_az_DL_01A600, object_az_DL_01A730, object_az_DL_01A860, object_az_DL_01A990, object_az_DL_01AAC0, +}; +static AnimatedMaterial* D_80A99180[5] = { + object_az_Matanimheader_01A6E8, object_az_Matanimheader_01A818, object_az_Matanimheader_01A948, + object_az_Matanimheader_01AA78, object_az_Matanimheader_01ABA8, +}; +static u8 D_80A99194[5] = { + 95, 135, 175, 215, 255, +}; +static u8 D_80A9919C[5] = { + 31, 45, 58, 73, 85, +}; +static struct_80124618 D_80A991A4[5][9] = { + { + { 0, { 200, 160, 160 } }, + { 2, { 250, 210, 210 } }, + { 4, { 200, 160, 160 } }, + { 6, { 250, 210, 210 } }, + { 8, { 200, 160, 160 } }, + { 10, { 250, 210, 210 } }, + { 12, { 200, 160, 160 } }, + { 14, { 250, 210, 210 } }, + { 16, { 200, 160, 160 } }, + }, + { + { 0, { 330, 200, 200 } }, + { 2, { 280, 150, 150 } }, + { 4, { 330, 200, 200 } }, + { 6, { 280, 150, 150 } }, + { 8, { 330, 200, 200 } }, + { 10, { 280, 150, 150 } }, + { 12, { 330, 200, 200 } }, + { 14, { 280, 150, 150 } }, + { 16, { 330, 200, 200 } }, + }, + { + { 0, { 350, 170, 120 } }, + { 2, { 400, 220, 170 } }, + { 4, { 350, 170, 120 } }, + { 6, { 400, 220, 170 } }, + { 8, { 350, 170, 120 } }, + { 10, { 400, 220, 170 } }, + { 12, { 350, 170, 120 } }, + { 14, { 400, 220, 170 } }, + { 16, { 350, 170, 120 } }, + }, + { + { 0, { 480, 216, 156 } }, + { 2, { 540, 216, 156 } }, + { 4, { 450, 300, 216 } }, + { 6, { 540, 216, 156 } }, + { 8, { 450, 300, 216 } }, + { 10, { 540, 216, 156 } }, + { 12, { 450, 300, 216 } }, + { 14, { 540, 300, 156 } }, + { 16, { 450, 250, 216 } }, + }, + { + { 0, { 600, 375, 160 } }, + { 2, { 640, 510, 200 } }, + { 4, { 600, 375, 160 } }, + { 6, { 640, 510, 200 } }, + { 8, { 600, 375, 160 } }, + { 10, { 640, 510, 200 } }, + { 12, { 600, 375, 160 } }, + { 14, { 640, 510, 200 } }, + { 16, { 600, 375, 160 } }, + }, +}; +static struct_80A98F94 D_80A9930C[5][4] = { + { { 0, 2100.0f }, { 7, 1500.0f }, { 16, 2100.0f }, { 0, 0.0f } }, + { { 0, 1900.0f }, { 7, 2200.0f }, { 10, 1600.0f }, { 16, 1900.0f } }, + { { 0, 1700.0f }, { 7, 2200.0f }, { 16, 1700.0f }, { 0, 0.0f } }, + { { 0, 1900.0f }, { 4, 1600.0f }, { 10, 2200.0f }, { 16, 1900.0f } }, + { { 0, 1900.0f }, { 7, 1400.0f }, { 16, 1900.0f }, { 0, 0.0f } }, +}; +static Vec3f D_80A993AC[3] = { + { 1.0f, 1.0f, 0.0f }, + { 0.9f, 0.9f, 120.0f }, + { 0.95f, 0.95f, 240.0f }, +}; +static Vec3f D_80A993D0[3] = { + { 1.5f, 1.5f, 0.0f }, + { 1.2f, 1.2f, 120.0f }, + { 1.35f, 1.35f, 240.0f }, +}; +static TexturePtr D_80A993F4[4] = { + object_az_Tex_00F918, + object_az_Tex_010118, + object_az_Tex_010918, + object_az_Tex_011118, +}; +static TexturePtr D_80A99404[3] = { + object_az_Tex_016018, + object_az_Tex_016818, + object_az_Tex_017018, +}; + +void EnAz_Draw(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnAz* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x19); + CLOSE_DISPS(play->state.gfxCtx); + + if (this->unk_374 & 2) { + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80A98DA4, func_80A98E48, &this->actor); + } else { + OPEN_DISPS(play->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A993F4[this->unk_37E])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80A99404[this->unk_380])); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80A98DA4, func_80A98E48, &this->actor); + CLOSE_DISPS(play->state.gfxCtx); + } + OPEN_DISPS(play->state.gfxCtx); + if ((this->actor.depthInWater >= 28.0f) && (this->actor.speedXZ > 0.5f)) { + Matrix_Translate(this->unk_3B4.x, this->unk_3B4.y, this->unk_3B4.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_39E, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + func_8012C2DC(play->state.gfxCtx); + if (this->unk_374 & 2) { + s32 i; + Vec3f sp98; + f32 sp94; + + Matrix_Translate(0.0f, 0.0f, -2000.0f, MTXMODE_APPLY); + for (i = 0; i < ARRAY_COUNT(D_80A99180); i++) { + Matrix_Push(); + func_80A98F94(D_80A9930C[i], this->unk_39C, &sp94); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(D_80A99180[i])); + Matrix_Translate(0.0f, sp94 * 100.0f, i * -930.0f, MTXMODE_APPLY); + Matrix_Scale(1.1f, 0.95f, 1.0f, MTXMODE_APPLY); + func_80124618(D_80A991A4[i], this->unk_39C, &sp98); + Matrix_Scale(sp98.x, sp98.y, sp98.z, MTXMODE_APPLY); + if (this->unk_374 & 0x800) { + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_PrimColor(play->state.gfxCtx, 0x80, 255, 255, 255, D_80A99194[i])); + } else { + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_PrimColor(play->state.gfxCtx, 0x80, 255, 255, 255, D_80A9919C[i])); + } + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80A9916C[i]); + Matrix_Pop(); + } + } else { + Matrix_Push(); + Matrix_Translate(0.0f, 2000.0f, -2000.0f, MTXMODE_APPLY); + Matrix_RotateZS(D_80A993D0[this->unk_384].z * (0x10000 / 360.0f), MTXMODE_APPLY); + Matrix_Scale(D_80A993AC[this->unk_384].x, D_80A993AC[this->unk_384].y, 0.0f, MTXMODE_APPLY); + if (this->unk_374 & 0x800) { + gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_PrimColor(play->state.gfxCtx, 0x80, 255, 255, 255, 255)); + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_PrimColor(play->state.gfxCtx, 0x80, 255, 255, 255, 85)); + } + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_az_DL_01ABF0); + Matrix_Pop(); + Matrix_Translate(0.0f, 2000.0f, -2100.0f, MTXMODE_APPLY); + Matrix_RotateZS(D_80A993D0[this->unk_384].z * (0x10000 / 360.0f), MTXMODE_APPLY); + Matrix_Scale(D_80A993D0[this->unk_384].x, D_80A993D0[this->unk_384].y, 0.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_az_DL_01AD00); + } + } + CLOSE_DISPS(play->state.gfxCtx); +} + +s32 func_80A98DA4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnAz* this = THIS; + + if ((limbIndex == OBJECT_AZ_1_LIMB_NONE) && ((play->gameplayFrames % 2) != 0)) { + *dList = NULL; + } + if (limbIndex == OBJECT_AZ_1_LIMB_NONE) { + rot->x = rot->x; + rot->y = rot->y; + rot->z = rot->z; + } + if (limbIndex == OBJECT_AZ_1_LIMB_03) { + rot->y -= this->unk_39E; + } else { + // this space intentionally left blank + } + if (limbIndex == OBJECT_AZ_1_LIMB_05) { + rot->x += this->unk_3D4; + rot->y -= this->unk_3D6; + } + return false; +} + +void func_80A98E48(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80A99410 = { 700.0f, 0.0f, 0.0f }; + static Vec3f D_80A9941C = { -500.0f, 0.0f, 0.0f }; + static Vec3f D_80A99428 = { -1200.0f, 0.0f, 1000.0f }; + EnAz* this = THIS; + + if (limbIndex == OBJECT_AZ_1_LIMB_03) { + Matrix_MultVec3f(&D_80A99410, &this->unk_3A8); + Math_SmoothStepToF(&this->unk_3A4, this->unk_3A8.y - this->actor.world.pos.y, 0.8f, 10.0f, 0.01f); + if (this->unk_374 & 2) { + Matrix_MultVec3f(&D_80A9941C, &this->unk_3B4); + } else { + Matrix_MultVec3f(&D_80A99428, &this->unk_3B4); + } + } +} + +void func_80A98EFC(EnAz* this, PlayState* play, u16 textId, s32 arg3, s32 arg4) { + EnAz* brother = this->brother; + + Actor_ChangeFocus(&this->actor, play, &brother->actor); + if (arg3 >= 0) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimationInfo, arg3, &this->animIndex); + } + this->actor.textId = 0; + brother->actor.textId = textId; + brother->unk_378 = 5; + if ((arg4 >= 0) && (arg4 != brother->animIndex)) { + SubS_ChangeAnimationBySpeedInfo(&brother->skelAnime, sAnimationInfo, arg4, &brother->animIndex); + } + this->unk_378 = 0; +} + +void func_80A98F94(struct_80A98F94* yData, f32 frame, f32* yInterp) { + f32 nextFrame; + f32 prevFrame; + f32 weight; + + do { + yData++; + nextFrame = yData[0].unk_0; + } while (nextFrame < frame); + prevFrame = yData[-1].unk_0; + weight = LERPWEIGHT(frame, prevFrame, nextFrame); + *yInterp = LERPIMP(yData[-1].unk_4, yData[0].unk_4, weight) * 0.01f; +} diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.h b/src/overlays/actors/ovl_En_Az/z_en_az.h index 5c302c6f3..ffe094a93 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.h +++ b/src/overlays/actors/ovl_En_Az/z_en_az.h @@ -7,10 +7,48 @@ struct EnAz; typedef void (*EnAzActionFunc)(struct EnAz*, PlayState*); +#define BEAVER_GET_PARAM_F00(thisx) (((thisx)->params >> 8) & 0xF) +#define BEAVER_GET_PARAM_FF(thisx) ((thisx)->params & 0xFF) + typedef struct EnAz { /* 0x000 */ Actor actor; /* 0x144 */ EnAzActionFunc actionFunc; - /* 0x148 */ char unk_148[0x290]; + /* 0x148 */ SkelAnime skelAnime; + /* 0x18C */ ColliderCylinder collider; + /* 0x1D8 */ Vec3s jointTable[24]; + /* 0x268 */ Vec3s morphTable[24]; + /* 0x2F8 */ s16 unk_2F8; + /* 0x2FA */ s16 unk_2FA; // cutscene state? + /* 0x2FC */ s32 animIndex; + /* 0x300 */ ActorPathing unk_300; + /* 0x36C */ f32 unk_36C; + /* 0x370 */ UNK_TYPE1 unk370[4]; + /* 0x374 */ u16 unk_374; // flags of some sort + /* 0x376 */ u16 unk_376; // flags of some sort + /* 0x378 */ u8 unk_378; // cutscene state? + /* 0x37A */ s16 unk_37A; + /* 0x37C */ s16 unk_37C; + /* 0x37E */ s16 unk_37E; + /* 0x380 */ s16 unk_380; + /* 0x382 */ s16 unk_382; + /* 0x384 */ s16 unk_384; + /* 0x388 */ struct EnAz* brother; + /* 0x38C */ UNK_TYPE1 unk38C[0x10]; + /* 0x39C */ s16 unk_39C; + /* 0x39E */ s16 unk_39E; // some sort of rotation + /* 0x3A0 */ UNK_TYPE1 unk3A0[4]; + /* 0x3A4 */ f32 unk_3A4; + /* 0x3A8 */ Vec3f unk_3A8; + /* 0x3B4 */ Vec3f unk_3B4; // translation + /* 0x3C0 */ s16 unk_3C0; // seems to do nothing + /* 0x3C2 */ s16 unk_3C2; + /* 0x3C4 */ s16 unk_3C4; + /* 0x3C6 */ UNK_TYPE1 unk3C6[6]; + /* 0x3CC */ s32 getItemId; + /* 0x3D0 */ s16 unk_3D0[1]; + /* 0x3D2 */ u16 unk_3D2; + /* 0x3D4 */ s16 unk_3D4; + /* 0x3D6 */ s16 unk_3D6; } EnAz; // size = 0x3D8 extern const ActorInit En_Az_InitVars; diff --git a/src/overlays/actors/ovl_En_Twig/z_en_twig.c b/src/overlays/actors/ovl_En_Twig/z_en_twig.c index 182db5659..5df9cee3c 100644 --- a/src/overlays/actors/ovl_En_Twig/z_en_twig.c +++ b/src/overlays/actors/ovl_En_Twig/z_en_twig.c @@ -5,6 +5,7 @@ */ #include "z_en_twig.h" +#include "objects/object_twig/object_twig.h" #define FLAGS (ACTOR_FLAG_10) @@ -12,10 +13,18 @@ void EnTwig_Init(Actor* thisx, PlayState* play); void EnTwig_Destroy(Actor* thisx, PlayState* play); -void EnTwig_Update(Actor* thisx, PlayState* play); -void EnTwig_Draw(Actor* thisx, PlayState* play); +void EnTwig_Update(Actor* this, PlayState* play); +void EnTwig_Draw(EnTwig* this, PlayState* play); + +void func_80AC0A54(EnTwig* this, PlayState* play); +void func_80AC0A6C(EnTwig* this, PlayState* play); + +void func_80AC0A7C(EnTwig* this, PlayState* play); +void func_80AC0AC8(EnTwig* this, PlayState* play); + +void func_80AC0CC4(EnTwig* this, PlayState* play); +void func_80AC0D2C(EnTwig* this, PlayState* play); -#if 0 const ActorInit En_Twig_InitVars = { ACTOR_EN_TWIG, ACTORCAT_MISC, @@ -28,36 +37,205 @@ const ActorInit En_Twig_InitVars = { (ActorFunc)EnTwig_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AC10C0[] = { +static s32 sCurrentRing; +static s16 sRingCount; +static s16 sRingNotCollected[25]; + +static CollisionHeader* sColHeaders[] = { + NULL, + &object_twig_Colheader_0020A0, + &object_twig_Colheader_0016C0, +}; + +static s16 sRingsHaveSpawned = false; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 40, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 40, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -#endif +void EnTwig_Init(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnTwig* this = THIS; + s32 i; -extern InitChainEntry D_80AC10C0[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_160 = RACERING_GET_PARAM_F(&this->dyna.actor); + DynaPolyActor_Init(&this->dyna, 1); + if (sColHeaders[this->unk_160] != NULL) { + DynaPolyActor_LoadMesh(play, &this->dyna, sColHeaders[this->unk_160]); + } + this->dyna.actor.bgCheckFlags |= 0x400; + switch (this->unk_160) { + case 0: + Actor_MarkForDeath(&this->dyna.actor); + break; + case 1: + if (!sRingsHaveSpawned) { + sRingCount = (gSaveContext.save.weekEventReg[24] & 4) ? 25 : 20; + for (i = 0; i < sRingCount; i++) { + sRingNotCollected[i] = false; + } + sRingsHaveSpawned = true; + } + if (RACERING_GET_PARAM_1F0(&this->dyna.actor) != 0) { + if (!(gSaveContext.save.weekEventReg[24] & 4)) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + } else if (gSaveContext.save.weekEventReg[24] & 4) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + Actor_SetScale(&this->dyna.actor, 4.2f); + this->dyna.actor.uncullZoneScale = this->dyna.actor.uncullZoneDownward = this->dyna.actor.scale.x * 60.0f; + func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId); + func_80AC0A7C(this, play); + break; + case 2: + Actor_SetScale(&this->dyna.actor, 1.0f); + this->dyna.actor.uncullZoneScale = this->dyna.actor.uncullZoneDownward = this->dyna.actor.scale.x * 880.0f; + func_80AC0A54(this, play); + break; + } +} -extern UNK_TYPE D_06001C38; +void EnTwig_Destroy(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnTwig* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/EnTwig_Init.s") + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/EnTwig_Destroy.s") +void func_80AC0A54(EnTwig* this, PlayState* play) { + this->actionFunc = func_80AC0A6C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0A54.s") +void func_80AC0A6C(EnTwig* this, PlayState* play) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0A6C.s") +void func_80AC0A7C(EnTwig* this, PlayState* play) { + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0A7C.s") + Math_Vec3f_Copy(&this->unk_180, &player->bodyPartsPos[0]); + this->unk_178 = 0; + this->unk_17A = 0; + this->actionFunc = func_80AC0AC8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0AC8.s") +void func_80AC0AC8(EnTwig* this, PlayState* play) { + static Vec3f D_80AC10D0 = { 0.0f, 0.0f, 1.0f }; + Player* player = GET_PLAYER(play); + Plane sp4C; + Vec3f sp40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0CC4.s") + if (sCurrentRing == RACERING_GET_PARAM_FE0(&this->dyna.actor)) { + if (this->unk_17A == 3) { + this->unk_17A = 0; + this->dyna.actor.shape.rot.z += 0x2000; + } else { + this->unk_17A++; + } + } + SubS_ConstructPlane(&this->dyna.actor.world.pos, &D_80AC10D0, &this->dyna.actor.shape.rot, &sp4C); + if ((sCurrentRing == RACERING_GET_PARAM_FE0(&this->dyna.actor)) && + Math3D_LineSegVsPlane(sp4C.normal.x, sp4C.normal.y, sp4C.normal.z, sp4C.originDist, &this->unk_180, + &player->bodyPartsPos[0], &sp40, 0)) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &sp40) <= SQ(this->dyna.actor.scale.x * 0.345f * 40.0f)) { + func_80AC0CC4(this, play); + return; + } + } else { + if (this->dyna.actor.xyzDistToPlayerSq <= SQ((this->dyna.actor.scale.x * 40.0f) + 40)) { + func_800C6314(play, &play->colCtx.dyna, this->dyna.bgId); + } else { + func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId); + } + if (this->dyna.actor.xyzDistToPlayerSq >= (this->dyna.actor.scale.x * 10.0f * 40.0f * 40.0f)) { + this->dyna.actor.shape.rot.y = this->dyna.actor.yawTowardsPlayer; + this->dyna.actor.world.rot.y = this->dyna.actor.yawTowardsPlayer; + } + } + Math_Vec3f_Copy(&this->unk_180, &player->bodyPartsPos[0]); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/func_80AC0D2C.s") +void func_80AC0CC4(EnTwig* this, PlayState* play) { + this->unk_170 = 3458.0f; + this->unk_174 = 0.2f; + this->unk_16C |= 1; + func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId); + this->actionFunc = func_80AC0D2C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/EnTwig_Update.s") +void func_80AC0D2C(EnTwig* this, PlayState* play) { + static Vec3f sKiraVel = { 0.0f, -0.05f, 0.0f }; + static Vec3f sKiraAccel = { 0.0f, -0.025f, 0.0f }; + static Color_RGBA8 sColorWhite = { 255, 255, 255, 130 }; + static Color_RGBA8 sColorYellow = { 255, 255, 0, 0 }; + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Twig/EnTwig_Draw.s") + Math_SmoothStepToF(&this->dyna.actor.world.pos.x, player->bodyPartsPos[0].x, 0.5f, 100.0f, 0.01f); + Math_SmoothStepToF(&this->dyna.actor.world.pos.y, player->bodyPartsPos[0].y, 0.5f, 100.0f, 0.01f); + Math_SmoothStepToF(&this->dyna.actor.world.pos.z, player->bodyPartsPos[0].z, 0.5f, 100.0f, 0.01f); + this->dyna.actor.shape.rot.z += (s16)this->unk_170; + this->dyna.actor.scale.x -= this->unk_174; + if (this->dyna.actor.scale.x < 0.0f) { + Actor_SetScale(&this->dyna.actor, 0.0f); + } else { + Actor_SetScale(&this->dyna.actor, this->dyna.actor.scale.x); + } + if (this->dyna.actor.scale.x <= 0.0f) { + s32 j; + Vec3f sp6C; + + for (j = 0; j < 7; j++) { + sp6C.x = (Rand_Centered() * 10.0f) + this->dyna.actor.world.pos.x; + sp6C.y = (Rand_Centered() * 10.0f) + this->dyna.actor.world.pos.y; + sp6C.z = (Rand_Centered() * 10.0f) + this->dyna.actor.world.pos.z; + EffectSsKirakira_SpawnDispersed(play, &sp6C, &sKiraVel, &sKiraAccel, &sColorWhite, &sColorYellow, 1000, + (s32)(Rand_ZeroOne() * 10.0f) + 20); + } + play_sound(NA_SE_SY_GET_ITEM); + play->interfaceCtx.unk_25C--; + sRingNotCollected[RACERING_GET_PARAM_FE0(&this->dyna.actor)] = true; + if (sCurrentRing == RACERING_GET_PARAM_FE0(&this->dyna.actor)) { + s32 i; + + for (i = 0; i < sRingCount; i++) { + if (!sRingNotCollected[i]) { + sCurrentRing = i; + break; + } + } + if (i == sRingCount) { + sCurrentRing = -1; + } + } + Actor_MarkForDeath(&this->dyna.actor); + return; + } + this->unk_170 += 180.0f / 0x10000; + this->unk_174 += 0.15f; +} + +void EnTwig_Update(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnTwig* this = THIS; + + this->actionFunc(this, play); +} + +void EnTwig_Draw(EnTwig* thisx, PlayState* play) { + EnTwig* this = THIS; + + switch (this->unk_160) { + case 1: + Gfx_DrawDListOpa(play, object_twig_DL_001C38); + break; + case 2: + Gfx_DrawDListOpa(play, object_twig_DL_0014C8); + break; + } +} diff --git a/src/overlays/actors/ovl_En_Twig/z_en_twig.h b/src/overlays/actors/ovl_En_Twig/z_en_twig.h index 2caebeb82..3de7f8f4b 100644 --- a/src/overlays/actors/ovl_En_Twig/z_en_twig.h +++ b/src/overlays/actors/ovl_En_Twig/z_en_twig.h @@ -7,11 +7,22 @@ struct EnTwig; typedef void (*EnTwigActionFunc)(struct EnTwig*, PlayState*); +#define RACERING_GET_PARAM_F(thisx) ((thisx)->params & 0xF) +#define RACERING_GET_PARAM_1F0(thisx) (((thisx)->params >> 4) & 0x1F) +#define RACERING_GET_PARAM_FE0(thisx) (((thisx)->params >> 9) & 0x7F) + typedef struct EnTwig { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ EnTwigActionFunc actionFunc; - /* 0x160 */ char unk_160[0x2C]; + /* 0x160 */ s32 unk_160; + /* 0x160 */ UNK_TYPE1 unk164[8]; + /* 0x16C */ s32 unk_16C; + /* 0x170 */ f32 unk_170; + /* 0x174 */ f32 unk_174; + /* 0x178 */ s16 unk_178; + /* 0x17A */ u16 unk_17A; + /* 0x17C */ UNK_TYPE1 unk17C[4]; + /* 0x180 */ Vec3f unk_180; } EnTwig; // size = 0x18C extern const ActorInit En_Twig_InitVars; From e47dc7da25ee45b4e2805d78766e27ac8c0f6970 Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo <96613413+sonicdcer@users.noreply.github.com> Date: Wed, 14 Sep 2022 12:57:47 -0300 Subject: [PATCH 5/8] ovl_Oceff_Wipe3 OK (#1001) * all functions matching * ovl_Oceff_Wipe3 decompiled * bss * pr review * pr review * renamings * pr review --- assets/xml/overlays/ovl_Oceff_Wipe3.xml | 10 +++ spec | 4 +- .../actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c | 81 +++++++++++++++++-- .../actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h | 2 +- 4 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 assets/xml/overlays/ovl_Oceff_Wipe3.xml diff --git a/assets/xml/overlays/ovl_Oceff_Wipe3.xml b/assets/xml/overlays/ovl_Oceff_Wipe3.xml new file mode 100644 index 000000000..d8be72985 --- /dev/null +++ b/assets/xml/overlays/ovl_Oceff_Wipe3.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/spec b/spec index cb56bb471..5f0500cf3 100644 --- a/spec +++ b/spec @@ -1988,9 +1988,7 @@ beginseg name "ovl_Oceff_Wipe3" compress include "build/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.o" - include "build/data/ovl_Oceff_Wipe3/ovl_Oceff_Wipe3.data.o" - include "build/data/ovl_Oceff_Wipe3/ovl_Oceff_Wipe3.bss.o" - include "build/data/ovl_Oceff_Wipe3/ovl_Oceff_Wipe3.reloc.o" + include "build/src/overlays/actors/ovl_Oceff_Wipe3/ovl_Oceff_Wipe3_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c index fb1f2a45d..1b1347e8f 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c +++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c @@ -16,7 +16,6 @@ void OceffWipe3_Destroy(Actor* thisx, PlayState* play); void OceffWipe3_Update(Actor* thisx, PlayState* play); void OceffWipe3_Draw(Actor* thisx, PlayState* play); -#if 0 const ActorInit Oceff_Wipe3_InitVars = { ACTOR_OCEFF_WIPE3, ACTORCAT_ITEMACTION, @@ -29,12 +28,82 @@ const ActorInit Oceff_Wipe3_InitVars = { (ActorFunc)OceffWipe3_Draw, }; -#endif +#include "assets/overlays/ovl_Oceff_Wipe3/ovl_Oceff_Wipe3.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe3/OceffWipe3_Init.s") +s32 D_80989130; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe3/OceffWipe3_Destroy.s") +void OceffWipe3_Init(Actor* thisx, PlayState* play) { + OceffWipe3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe3/OceffWipe3_Update.s") + Actor_SetScale(&this->actor, 0.1f); + this->counter = 0; + this->actor.world.pos = GET_ACTIVE_CAM(play)->eye; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe3/OceffWipe3_Draw.s") +void OceffWipe3_Destroy(Actor* thisx, PlayState* play) { + OceffWipe3* this = THIS; + + func_80115D5C(&play->state); + play->msgCtx.unk120B0 = 0; +} + +void OceffWipe3_Update(Actor* thisx, PlayState* play) { + OceffWipe3* this = THIS; + + this->actor.world.pos = GET_ACTIVE_CAM(play)->eye; + if (this->counter < 100) { + this->counter++; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void OceffWipe3_Draw(Actor* thisx, PlayState* play) { + u32 scroll = play->state.frames & 0xFFF; + OceffWipe3* this = THIS; + f32 z; + u8 alpha; + s32 pad[2]; + Vec3f eye = GET_ACTIVE_CAM(play)->eye; + Vtx* vtxPtr; + Vec3f quakeOffset; + + Camera_GetQuakeOffset(&quakeOffset, GET_ACTIVE_CAM(play)); + + vtxPtr = sSariaSongFrustumVtx; + + if (this->counter < 32) { + z = Math_SinS(this->counter * 512) * 1220.0f; + } else { + z = 1220.0f; + } + + if (this->counter >= 80) { + alpha = 12 * (100 - this->counter); + } else { + alpha = 255; + } + + vtxPtr[1].v.cn[3] = vtxPtr[3].v.cn[3] = vtxPtr[5].v.cn[3] = vtxPtr[7].v.cn[3] = vtxPtr[9].v.cn[3] = + vtxPtr[11].v.cn[3] = vtxPtr[13].v.cn[3] = vtxPtr[15].v.cn[3] = vtxPtr[17].v.cn[3] = vtxPtr[19].v.cn[3] = + vtxPtr[21].v.cn[3] = alpha; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C2DC(play->state.gfxCtx); + Matrix_Translate(eye.x + quakeOffset.x, eye.y + quakeOffset.y, eye.z + quakeOffset.z, MTXMODE_NEW); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_RotateXS(0x708, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 170, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 100, 200, 0, 128); + gSPDisplayList(POLY_XLU_DISP++, &sSariaSongFrustrumMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, 0, scroll * 12, scroll * -12, 64, 64, 1, + scroll * 8, scroll * -8, 64, 64)); + gSPDisplayList(POLY_XLU_DISP++, &sSariaSongFrustumModelDL); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h index b9f41bb09..f29ca9278 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h +++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h @@ -7,7 +7,7 @@ struct OceffWipe3; typedef struct OceffWipe3 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ s16 counter; } OceffWipe3; // size = 0x148 extern const ActorInit Oceff_Wipe3_InitVars; From 33f7ede84f01eaae9d9e7560416e2f925a70e8a4 Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo <96613413+sonicdcer@users.noreply.github.com> Date: Wed, 14 Sep 2022 13:07:46 -0300 Subject: [PATCH 6/8] ovl_Oceff_Spot OK (#1004) * ovl_Oceff_Spot decompiled * format * renamings and pr review * pr review * pr review --- assets/xml/overlays/ovl_Oceff_Spot.xml | 7 + spec | 3 +- .../actors/ovl_Oceff_Spot/z_oceff_spot.c | 146 ++++++++++++++++-- .../actors/ovl_Oceff_Spot/z_oceff_spot.h | 7 +- tools/disasm/functions.txt | 6 +- 5 files changed, 146 insertions(+), 23 deletions(-) create mode 100644 assets/xml/overlays/ovl_Oceff_Spot.xml diff --git a/assets/xml/overlays/ovl_Oceff_Spot.xml b/assets/xml/overlays/ovl_Oceff_Spot.xml new file mode 100644 index 000000000..f4e9beea7 --- /dev/null +++ b/assets/xml/overlays/ovl_Oceff_Spot.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spec b/spec index 5f0500cf3..1135ac921 100644 --- a/spec +++ b/spec @@ -1694,8 +1694,7 @@ beginseg name "ovl_Oceff_Spot" compress include "build/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.o" - include "build/data/ovl_Oceff_Spot/ovl_Oceff_Spot.data.o" - include "build/data/ovl_Oceff_Spot/ovl_Oceff_Spot.reloc.o" + include "build/src/overlays/actors/ovl_Oceff_Spot/ovl_Oceff_Spot_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c index 91a5d3e66..504a2815a 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c @@ -10,17 +10,17 @@ #define THIS ((OceffSpot*)thisx) -void OceffSpot_Init(Actor* thisx, PlayState* play); -void OceffSpot_Destroy(Actor* thisx, PlayState* play); +void OceffSpot_Init(Actor* thisx, PlayState* play2); +void OceffSpot_Destroy(Actor* thisx, PlayState* play2); void OceffSpot_Update(Actor* thisx, PlayState* play); void OceffSpot_Draw(Actor* thisx, PlayState* play); -void func_809728F8(OceffSpot* this, PlayState* play); -void func_80972934(OceffSpot* this, PlayState* play); +void OceffSpot_Wait(OceffSpot* this, PlayState* play); +void OceffSpot_GrowCylinder(OceffSpot* this, PlayState* play); +void OceffSpot_End(OceffSpot* this, PlayState* play); void OceffSpot_SetupAction(OceffSpot* this, OceffSpotActionFunc actionFunc); -#if 0 const ActorInit Oceff_Spot_InitVars = { ACTOR_OCEFF_SPOT, ACTORCAT_ITEMACTION, @@ -33,28 +33,140 @@ const ActorInit Oceff_Spot_InitVars = { (ActorFunc)OceffSpot_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80973478[] = { +#include "assets/overlays/ovl_Oceff_Spot/ovl_Oceff_Spot.c" + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_STOP), }; -#endif +void OceffSpot_SetupAction(OceffSpot* this, OceffSpotActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern InitChainEntry D_80973478[]; +void OceffSpot_Init(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + OceffSpot* this = THIS; + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_SetupAction.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + OceffSpot_SetupAction(this, OceffSpot_GrowCylinder); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Init.s") + Lights_PointNoGlowSetInfo(&this->lightInfo1, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, 0); + this->lightNode1 = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Destroy.s") + Lights_PointNoGlowSetInfo(&this->lightInfo2, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, 0); + this->lightNode2 = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo2); + this->actor.scale.y = 0.3f; + this->unk16C = 0.0f; + this->actor.world.pos.y = player->actor.world.pos.y; + this->actor.world.pos.x = player->bodyPartsPos[0].x; + this->actor.world.pos.z = player->bodyPartsPos[0].z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_80972844.s") +void OceffSpot_Destroy(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + OceffSpot* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_809728F8.s") + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode1); + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode2); + func_80115D5C(&play->state); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_80972934.s") +void OceffSpot_End(OceffSpot* this, PlayState* play) { + if (this->unk16C > 0.0f) { + this->unk16C -= 0.05f; + } else { + Actor_MarkForDeath(&this->actor); + if ((REG(15) != 0x190) && (play->msgCtx.unk12046 == 0)) { + if ((play->msgCtx.ocarinaAction != 0x39) || (play->msgCtx.ocarinaMode != 0xA)) { + gSaveContext.sunsSongState = SUNSSONG_START; + } + } else { + play->msgCtx.ocarinaMode = 4; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Update.s") +void OceffSpot_Wait(OceffSpot* this, PlayState* play) { + if (this->timer > 0) { + this->timer--; + } else { + OceffSpot_SetupAction(this, OceffSpot_End); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Draw.s") +void OceffSpot_GrowCylinder(OceffSpot* this, PlayState* play) { + if (this->unk16C < 1.0f) { + this->unk16C += 0.05f; + } else { + OceffSpot_SetupAction(this, OceffSpot_Wait); + this->timer = 60; + } +} + +void OceffSpot_Update(Actor* thisx, PlayState* play) { + f32 scale; + s32 pad; + Player* player = GET_PLAYER(play); + f32 temp; + OceffSpot* this = THIS; + + temp = (1.0f - cosf(this->unk16C * M_PI)) * 0.5f; + this->actionFunc(this, play); + + switch (gSaveContext.save.playerForm) { + default: + scale = 1.0f; + break; + + case PLAYER_FORM_DEKU: + scale = 1.3f; + break; + + case PLAYER_FORM_ZORA: + scale = 1.2f; + break; + + case PLAYER_FORM_GORON: + scale = 2.0f; + break; + } + + this->actor.scale.z = (scale * 0.42f) * temp; + this->actor.scale.x = (scale * 0.42f) * temp; + + this->actor.world.pos = player->actor.world.pos; + this->actor.world.pos.y = this->actor.world.pos.y + 5.0f; + + temp = (2.0f - this->unk16C) * this->unk16C; + + func_800FD2B4(play, temp * 0.5f, 880.0f, 0.2f, 0.9f); + + Lights_PointNoGlowSetInfo(&this->lightInfo1, this->actor.world.pos.x, this->actor.world.pos.y + 55.0f, + this->actor.world.pos.z, (s32)(255.0f * temp), (s32)(255.0f * temp), (s32)(200.0f * temp), + 100.0f * temp); + Lights_PointNoGlowSetInfo( + &this->lightInfo2, this->actor.world.pos.x + (Math_SinS(player->actor.shape.rot.y) * 20.0f), + this->actor.world.pos.y + 20.0f, this->actor.world.pos.z + (Math_CosS(player->actor.shape.rot.y) * 20.0f), + (s32)(255.0f * temp), (s32)(255.0f * temp), (s32)(200.0f * temp), 100.0f * temp); +} + +void OceffSpot_Draw(Actor* thisx, PlayState* play) { + OceffSpot* this = THIS; + u32 scroll = play->state.frames & 0xFFFF; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C2DC(play->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &sSunSongEffectCylinderMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, 0, scroll * 2, scroll * -2, 0x20, 0x20, 1, 0, + scroll * -8, 0x20, 0x20)); + gSPDisplayList(POLY_XLU_DISP++, &sSunSongEffectCylinderModelDL); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h index 922b1f89b..0a770ee9d 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h @@ -9,7 +9,12 @@ typedef void (*OceffSpotActionFunc)(struct OceffSpot*, PlayState*); typedef struct OceffSpot { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x30]; + /* 0x144 */ LightNode* lightNode1; + /* 0x148 */ LightInfo lightInfo1; + /* 0x158 */ LightNode* lightNode2; + /* 0x15C */ LightInfo lightInfo2; + /* 0x16C */ f32 unk16C; + /* 0x170 */ u16 timer; /* 0x174 */ OceffSpotActionFunc actionFunc; } OceffSpot; // size = 0x178 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 20fb6c0c2..dc205b344 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8057,9 +8057,9 @@ 0x80972680:("OceffSpot_SetupAction",), 0x8097268C:("OceffSpot_Init",), 0x809727EC:("OceffSpot_Destroy",), - 0x80972844:("func_80972844",), - 0x809728F8:("func_809728F8",), - 0x80972934:("func_80972934",), + 0x80972844:("OceffSpot_End",), + 0x809728F8:("OceffSpot_Wait",), + 0x80972934:("OceffSpot_GrowCylinder",), 0x80972998:("OceffSpot_Update",), 0x80972C54:("OceffSpot_Draw",), 0x80973550:("EnTorch_Init",), From 420403a09ae34516a63987685537700cde3cefe4 Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo <96613413+sonicdcer@users.noreply.github.com> Date: Wed, 14 Sep 2022 13:12:31 -0300 Subject: [PATCH 7/8] ovl_En_Encount1 OK (#1005) * 1 Non matching * all functions matching * new reloc problems * Documenting * ovl_En_Encount1 decompiled * Co-authored-by: Synray synray@users.noreply.github.com * Co-authored-by: petrie911 petrie911@users.noreply.github.com * Co-authored-by: Fig02 fig02srl@gmail.com * Co-authored-by: Maide eeeedddccc@hotmail.co.uk * Co-authored-by: EllipticEllipsis EllipticEllipsis@users.noreply.github.com * uncomment old reloc * pr review --- spec | 3 +- .../actors/ovl_En_Encount1/z_en_encount1.c | 128 +++++++++++++++++- .../actors/ovl_En_Encount1/z_en_encount1.h | 23 +++- 3 files changed, 144 insertions(+), 10 deletions(-) diff --git a/spec b/spec index 1135ac921..95d8074c9 100644 --- a/spec +++ b/spec @@ -1162,8 +1162,7 @@ beginseg name "ovl_En_Encount1" compress include "build/src/overlays/actors/ovl_En_Encount1/z_en_encount1.o" - include "build/data/ovl_En_Encount1/ovl_En_Encount1.data.o" - include "build/data/ovl_En_Encount1/ovl_En_Encount1.reloc.o" + include "build/src/overlays/actors/ovl_En_Encount1/ovl_En_Encount1_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index 8e68f9205..0305af8ef 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -15,7 +15,6 @@ void EnEncount1_Update(Actor* thisx, PlayState* play); void func_808E0954(EnEncount1* this, PlayState* play); -#if 0 const ActorInit En_Encount1_InitVars = { ACTOR_EN_ENCOUNT1, ACTORCAT_PROP, @@ -28,10 +27,129 @@ const ActorInit En_Encount1_InitVars = { (ActorFunc)NULL, }; -#endif +static s16 sActorList[] = { + ACTOR_EN_GRASSHOPPER, + ACTOR_EN_WALLMAS, + ACTOR_EN_PR2, + ACTOR_EN_PR2, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Encount1/EnEncount1_Init.s") +static s16 sActorParams[] = { 1, 0, 1, 3 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Encount1/func_808E0954.s") +void EnEncount1_Init(Actor* thisx, PlayState* play) { + EnEncount1* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Encount1/EnEncount1_Update.s") + if (this->actor.params <= 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actorType = ENENCOUNT1_GET_TYPE(&this->actor); + this->unk_14C = ENENCOUNT1_GET_7C0(&this->actor); + this->unk_154 = ENENCOUNT1_GET_PATH(&this->actor); + this->unk_158 = this->actor.world.rot.x; + this->unk_15C = this->actor.world.rot.y; + this->unk_160 = (this->actor.world.rot.z * 40.0f) + 120.0f; + + if (this->unk_154 >= 0x3F) { + this->unk_154 = -1; + } + if (this->actor.world.rot.z < 0) { + this->unk_160 = -1.0f; + } + if (this->actorType == EN_ENCOUNT1_SKULLFISH_2) { + this->unk_15A = ENENCOUNT1_GET_PATH(&this->actor); + this->path = SubS_GetPathByIndex(play, this->unk_15A, 0x3F); + this->unk_154 = -1; + this->unk_160 = -1.0f; + } + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = func_808E0954; +} + +void func_808E0954(EnEncount1* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Vec3f spawnPos; + f32 sp64; + f32 temp_fv0_2; + s16 sp5E; + s16 actorList; + s32 actorParams; + CollisionPoly* sp54; + s32 sp50; + + if (((this->unk_14E >= this->unk_14C) || ((this->unk_160 > 0.0f) && (this->unk_160 < this->actor.xzDistToPlayer)) || + ((this->unk_154 > 0) && (this->unk_154 <= this->unk_152)))) { + return; + } else if (this->unk_156 != 0) { + this->unk_156++; + if (this->unk_156 < this->unk_158) { + return; + } + } + + this->unk_156 = 0; + switch (this->actorType) { + case EN_ENCOUNT1_GRASSHOPPER: + sp64 = randPlusMinusPoint5Scaled(40.0f) + 200.0f; + sp5E = player->actor.shape.rot.y; + if (this->unk_14E & 1) { + sp5E = -sp5E; + sp64 = randPlusMinusPoint5Scaled(20.0f) + 100.0f; + } + spawnPos.x = player->actor.world.pos.x + (Math_SinS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); + spawnPos.y = player->actor.floorHeight + 120.0f; + spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); + temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos); + if ((temp_fv0_2 <= BGCHECK_Y_MIN) || + ((player->actor.depthInWater != BGCHECK_Y_MIN) && + (temp_fv0_2 < (player->actor.world.pos.y - player->actor.depthInWater)))) { + return; + } + spawnPos.y = temp_fv0_2; + break; + + case EN_ENCOUNT1_WALLMASTER: + Math_Vec3f_Copy(&spawnPos, &player->actor.world.pos); + break; + + case EN_ENCOUNT1_SKULLFISH: + sp64 = randPlusMinusPoint5Scaled(250.0f) + 500.0f; + sp5E = player->actor.shape.rot.y; + spawnPos.x = player->actor.world.pos.x + Math_SinS(sp5E) * sp64 + randPlusMinusPoint5Scaled(40.0f); + spawnPos.y = player->actor.world.pos.y - Rand_ZeroFloat(20.0f); + spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); + temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos); + if ((!(player->stateFlags1 & 0x8000000) || (temp_fv0_2 <= (BGCHECK_Y_MIN)) || + (player->actor.depthInWater < temp_fv0_2))) { + return; + } + break; + + case EN_ENCOUNT1_SKULLFISH_2: + if ((this->path != NULL) && (!SubS_CopyPointFromPath(this->path, 0, &spawnPos))) { + Actor_MarkForDeath(&this->actor); + } + break; + } + + actorList = sActorList[this->actorType]; + actorParams = sActorParams[this->actorType]; + if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorList, spawnPos.x, spawnPos.y, spawnPos.z, 0, 0, 0, + actorParams) != NULL) { + this->unk_14E++; + if (this->unk_154 > 0) { + this->unk_152++; + } + + if ((this->unk_14E >= this->unk_14C) && (this->unk_158 != 0)) { + this->unk_156 = 1; + } + } +} + +void EnEncount1_Update(Actor* thisx, PlayState* play) { + EnEncount1* this = THIS; + + this->actionFunc(this, play); +} diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h index d625f2151..8906d523e 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h @@ -3,6 +3,17 @@ #include "global.h" +#define ENENCOUNT1_GET_TYPE(thisx) (((thisx)->params >> 11) & 0x1F) +#define ENENCOUNT1_GET_7C0(thisx) (((thisx)->params >> 6) & 0x1F) +#define ENENCOUNT1_GET_PATH(thisx) ((thisx)->params & 0x3F) + +typedef enum EnEncount1Enemy { + /* 0x0 */ EN_ENCOUNT1_GRASSHOPPER, + /* 0x1 */ EN_ENCOUNT1_WALLMASTER, + /* 0x2 */ EN_ENCOUNT1_SKULLFISH, + /* 0x3 */ EN_ENCOUNT1_SKULLFISH_2, +} EnEncount1Enemy; + struct EnEncount1; typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, PlayState*); @@ -10,11 +21,17 @@ typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, PlayState*); typedef struct EnEncount1 { /* 0x000 */ Actor actor; /* 0x144 */ EnEncount1ActionFunc actionFunc; - /* 0x148 */ char unk_148[0x6]; + /* 0x148 */ Path* path; + /* 0x14C */ s16 unk_14C; /* 0x14E */ s16 unk_14E; - /* 0x150 */ char unk_150[0xA]; + /* 0x150 */ s16 actorType; + /* 0x152 */ s16 unk_152; + /* 0x154 */ s16 unk_154; + /* 0x156 */ s16 unk_156; + /* 0x158 */ s16 unk_158; /* 0x15A */ s16 unk_15A; - /* 0x15C */ char unk_15C[0x8]; + /* 0x15C */ s32 unk_15C; + /* 0x160 */ f32 unk_160; } EnEncount1; // size = 0x164 extern const ActorInit En_Encount1_InitVars; From aa6841a33b0ec0fe185c4cea0a4f2463868b89ca Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo <96613413+sonicdcer@users.noreply.github.com> Date: Wed, 14 Sep 2022 13:21:02 -0300 Subject: [PATCH 8/8] ovl_Oceff_Wipe2 OK (#1006) * ovl_Oceff_Wipe2 Decompiled * pr review * renamings * renamings --- assets/xml/overlays/ovl_Oceff_Wipe2.xml | 11 +++ spec | 4 +- .../actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c | 82 +++++++++++++++++-- .../actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h | 2 +- 4 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 assets/xml/overlays/ovl_Oceff_Wipe2.xml diff --git a/assets/xml/overlays/ovl_Oceff_Wipe2.xml b/assets/xml/overlays/ovl_Oceff_Wipe2.xml new file mode 100644 index 000000000..c43ced3c0 --- /dev/null +++ b/assets/xml/overlays/ovl_Oceff_Wipe2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/spec b/spec index 95d8074c9..cc7babd85 100644 --- a/spec +++ b/spec @@ -1977,9 +1977,7 @@ beginseg name "ovl_Oceff_Wipe2" compress include "build/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.o" - include "build/data/ovl_Oceff_Wipe2/ovl_Oceff_Wipe2.data.o" - include "build/data/ovl_Oceff_Wipe2/ovl_Oceff_Wipe2.bss.o" - include "build/data/ovl_Oceff_Wipe2/ovl_Oceff_Wipe2.reloc.o" + include "build/src/overlays/actors/ovl_Oceff_Wipe2/ovl_Oceff_Wipe2_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c index ca7ff8de2..a26636e15 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c +++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c @@ -15,7 +15,6 @@ void OceffWipe2_Destroy(Actor* thisx, PlayState* play); void OceffWipe2_Update(Actor* thisx, PlayState* play); void OceffWipe2_Draw(Actor* thisx, PlayState* play); -#if 0 const ActorInit Oceff_Wipe2_InitVars = { ACTOR_OCEFF_WIPE2, ACTORCAT_ITEMACTION, @@ -28,12 +27,83 @@ const ActorInit Oceff_Wipe2_InitVars = { (ActorFunc)OceffWipe2_Draw, }; -#endif +#include "assets/overlays/ovl_Oceff_Wipe2/ovl_Oceff_Wipe2.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe2/OceffWipe2_Init.s") +s32 D_809879D0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe2/OceffWipe2_Destroy.s") +void OceffWipe2_Init(Actor* thisx, PlayState* play) { + OceffWipe2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe2/OceffWipe2_Update.s") + Actor_SetScale(&this->actor, 0.1f); + this->timer = 0; + this->actor.world.pos = GET_ACTIVE_CAM(play)->eye; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe2/OceffWipe2_Draw.s") +void OceffWipe2_Destroy(Actor* thisx, PlayState* play) { + OceffWipe2* this = THIS; + + func_80115D5C(&play->state); + play->msgCtx.unk120B0 = 0; +} + +void OceffWipe2_Update(Actor* thisx, PlayState* play) { + OceffWipe2* this = THIS; + + this->actor.world.pos = GET_ACTIVE_CAM(play)->eye; + if (this->timer < 100) { + this->timer++; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void OceffWipe2_Draw(Actor* thisx, PlayState* play) { + u32 scroll = play->state.frames & 0xFF; + OceffWipe2* this = THIS; + f32 z; + u8 alpha; + s32 pad[2]; + Vec3f eye = GET_ACTIVE_CAM(play)->eye; + Vtx* vtxPtr; + Vec3f quakeOffset; + + Camera_GetQuakeOffset(&quakeOffset, GET_ACTIVE_CAM(play)); + + vtxPtr = sEponaSongFrustumVtx; + + if (this->timer < 32) { + z = Math_SinS(this->timer << 9) * 1220.0f; + } else { + z = 1220.0f; + } + + if (this->timer >= 80) { + alpha = 12 * (100 - this->timer); + } else { + alpha = 255; + } + + vtxPtr[1].v.cn[3] = vtxPtr[3].v.cn[3] = vtxPtr[5].v.cn[3] = vtxPtr[7].v.cn[3] = vtxPtr[9].v.cn[3] = + vtxPtr[11].v.cn[3] = vtxPtr[13].v.cn[3] = vtxPtr[15].v.cn[3] = vtxPtr[16].v.cn[3] = vtxPtr[18].v.cn[3] = + vtxPtr[20].v.cn[3] = alpha; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C2DC(play->state.gfxCtx); + + Matrix_Translate(eye.x + quakeOffset.x, eye.y + quakeOffset.y, eye.z + quakeOffset.z, MTXMODE_NEW); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_RotateXS(0x708, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 170, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 100, 0, 128); + gSPDisplayList(POLY_XLU_DISP++, sEponaSongFrustumMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, scroll * 6, scroll * -6, 64, + 64, 1, scroll * -6, 0, 64, 64)); + gSPDisplayList(POLY_XLU_DISP++, sEponaSongFrustumModelDL); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h index 79d366525..c213dfe38 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h +++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h @@ -7,7 +7,7 @@ struct OceffWipe2; typedef struct OceffWipe2 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ s16 timer; } OceffWipe2; // size = 0x148 extern const ActorInit Oceff_Wipe2_InitVars;