From 2e344b8d15e37dd0fa95309b0c7a3d7a5c70b45c Mon Sep 17 00:00:00 2001 From: CodeOverFLow Date: Fri, 13 Oct 2023 09:59:49 +0200 Subject: [PATCH 1/9] Boyo (#1341) * updated variables.txt * continue investigation * format to style * matching more asm * still more asm matching * finally matching * matching even more * add rodata * match more asm for Update * matching 99.58% of ObjBoyo_Update * matched ObjBoyo_Update * some cleanup * formatted * review: remove ACTOR_COLLISION_HANDLING_CASES define * review: fix main functions parameters * review: fix collision function signatures * review: fix ObjBoyo_FindCollidedActor parameters * review: better formatting for InitVars * review: fix ObjBoyoCollisionHandler typedef * review: fix segmented AnimatedMaterial * review: fix static ColliderCylinderInit * review: disassembled initchain * review: fix collision functions * review: fix functions.txt * review: fix variables.txt * review: clean z_obj_boyo.h * review: fix ObjBoyo_Destroy * remove fake variable from ObjBoyo_Init * review: rematch FindCollidedActor * review: make asm match again * review: update spec file * review: fix spec file * review: remove static D_*** * review: fix bad logic to find collided actor * review: fix ObjBoyo size (local make is now OK) * review: rename collision handlers array * review: use constant * review: clean PushPlayer function * review: fix LSP bad renaming * review: use GET_PLAYER macro * review: remove ugly pointer deref * review: replace += 1 with ++ * review: return NULL to emphasize it is a pointer * review: check against NULL instead of 0 * review: remove unnecessary casts * review: use constants * review: remove unnecessary include * review: rename variables + fix assembly matching * review: change ++i to i++ * review: fix inline comments * review: replace != with < in for loop --- spec | 3 +- src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c | 191 +++++++++++++++++- src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h | 16 +- tools/disasm/functions.txt | 8 +- tools/disasm/variables.txt | 7 +- 5 files changed, 201 insertions(+), 24 deletions(-) diff --git a/spec b/spec index 7aab83ed8..dd160ae09 100644 --- a/spec +++ b/spec @@ -2108,8 +2108,7 @@ beginseg name "ovl_Obj_Boyo" compress include "build/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.o" - include "build/data/ovl_Obj_Boyo/ovl_Obj_Boyo.data.o" - include "build/data/ovl_Obj_Boyo/ovl_Obj_Boyo.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Boyo/ovl_Obj_Boyo_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c index e5e53000a..9e791f7ae 100644 --- a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c +++ b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c @@ -1,4 +1,7 @@ #include "z_obj_boyo.h" +#include "overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_boyo/object_boyo.h" #define FLAGS (ACTOR_FLAG_10) @@ -9,7 +12,11 @@ void ObjBoyo_Destroy(Actor* thisx, PlayState* play2); void ObjBoyo_Update(Actor* thisx, PlayState* play2); void ObjBoyo_Draw(Actor* thisx, PlayState* play); -/* +void ObjBoyo_PushPlayer(ObjBoyo* this, Actor* actor); +void ObjBoyo_PushPirate(ObjBoyo* this, Actor* actor); +void ObjBoyo_ExplodeBomb(ObjBoyo* this, Actor* actor); +Actor* ObjBoyo_FindCollidedActor(ObjBoyo* this, PlayState* play, s32* index); + const ActorInit Obj_Boyo_InitVars = { ACTOR_OBJ_BOYO, ACTORCAT_PROP, @@ -19,22 +26,184 @@ const ActorInit Obj_Boyo_InitVars = { (ActorFunc)ObjBoyo_Init, (ActorFunc)ObjBoyo_Destroy, (ActorFunc)ObjBoyo_Update, - (ActorFunc)ObjBoyo_Draw + (ActorFunc)ObjBoyo_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Init.s") +typedef void (*ObjBoyoCollisionHandler)(ObjBoyo* this, Actor* actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Destroy.s") +typedef struct ObjBoyoUnkStruct { + /* 0x0 */ s16 id; + /* 0x4 */ ObjBoyoCollisionHandler colHandler; +} ObjBoyoUnkStruct; // size = 0x8 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5DC0.s") +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_TYPE_PLAYER | AC_HARD | AC_ON, + OC1_TYPE_2 | OC1_TYPE_1 | OC1_TYPE_PLAYER | OC1_ON, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x01CBFFBE, 0x00, 0x00 }, + TOUCH_NONE, + BUMP_ON, + OCELEM_ON, + }, + { + 60, + 140, + 0, + { 0, 0, 0 }, + }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5DE0.s") +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 300, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5E14.s") +static ObjBoyoUnkStruct sCollisionHandlers[] = { + { ACTOR_PLAYER, ObjBoyo_PushPlayer }, + { ACTOR_EN_KAIZOKU, ObjBoyo_PushPirate }, + { ACTOR_EN_BOM, ObjBoyo_ExplodeBomb }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5E24.s") +void ObjBoyo_Init(Actor* thisx, PlayState* play) { + ObjBoyo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Update.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitCylinder(play, &this->collider); + Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->animatedMaterial = Lib_SegmentedToVirtual(&object_boyo_Matanimheader_000E88); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Draw.s") +void ObjBoyo_Destroy(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + ObjBoyo* this = THIS; + + Collider_DestroyCylinder(play, &this->collider); +} + +void ObjBoyo_PushPlayer(ObjBoyo* this, Actor* actor) { + Player* player = (Player*)actor; + + player->pushedSpeed = 30.0f; + player->pushedYaw = this->actor.yawTowardsPlayer; +} + +void ObjBoyo_PushPirate(ObjBoyo* this, Actor* actor) { + EnKaizoku* kaizoku = (EnKaizoku*)actor; + + kaizoku->unk_2F0 = 30.0f; + kaizoku->unk_2F4 = Actor_WorldYawTowardActor(&this->actor, &kaizoku->picto.actor); +} + +void ObjBoyo_ExplodeBomb(ObjBoyo* this, Actor* actor) { + EnBom* bom = (EnBom*)actor; + + bom->timer = 0; +} + +/* + * Find the Actor we collided with. + */ +Actor* ObjBoyo_FindCollidedActor(ObjBoyo* this, PlayState* play, s32* index) { + Actor* collidedActor; + ObjBoyoUnkStruct* iter; + s32 i; + + if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { + *index = 0; + return &GET_PLAYER(play)->actor; + } + iter = sCollisionHandlers + 1; + if (this->collider.base.ocFlags1 & OC1_HIT) { + collidedActor = this->collider.base.oc; + for (i = 1; i < 3; i++) { + if (iter->id == collidedActor->id) { + *index = i; + return collidedActor; + } + iter++; + } + } + return NULL; +} + +void ObjBoyo_Update(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + ObjBoyo* this = THIS; + Actor* collidedActor; + s32 index; + + collidedActor = ObjBoyo_FindCollidedActor(this, play, &index); + + if (collidedActor != NULL) { + sCollisionHandlers[index].colHandler(this, collidedActor); + // TODO: find out what all of these are. + + this->unk194 = 0x64; + this->unk196 = 3; + this->unk198 = 0.01f; + this->unk19C = 0.03f; + this->unk1A4 = 0x3F40; + this->unk1A6 = 0x7D0; + this->unk1A8 = 0; + this->unk1A0 = 0.03f; + this->unk1AA = 0x2DF7; + this->unk1AC = 0x258; + } + + if (this->unk194 > 0) { + // compute new scaling + // this computation might help finding what those values are. + + this->unk194 -= this->unk196; + this->unk1AA += this->unk1AC; + this->unk1A8 += this->unk1AA; + + this->actor.scale.x = this->actor.scale.z = + (Math_CosS(this->unk1A8 + this->unk1A4) * (f32)this->unk194 * this->unk19C * this->unk198) + 0.1f; + + this->actor.scale.y = + (Math_CosS(this->unk1A8 + this->unk1A6) * (f32)this->unk194 * this->unk1A0 * this->unk198) + 0.1f; + } else { + Actor_SetScale(&this->actor, 0.1f); + if (this->collider.base.acFlags & AC_HIT) { + // TODO: find out what all of these are. + + this->unk194 = 0x1E; + this->unk196 = 2; + this->unk198 = 0.033333335f; + this->unk19C = 0.012f; + this->unk1A0 = 0.006f; + this->unk1A4 = 0x3F40; + this->unk1A6 = 0x7D0; + this->unk1A8 = 0; + this->unk1AA = 0x3A98; + this->unk1AC = 0x640; + } + } + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.ocFlags1 &= ~OC1_HIT; + this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + if (this->actor.xzDistToPlayer < 2000.0f) { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); + } +} + +void ObjBoyo_Draw(Actor* thisx, PlayState* play) { + ObjBoyo* this = THIS; + + AnimatedMat_Draw(play, this->animatedMaterial); + Gfx_DrawDListOpa(play, object_boyo_DL_000300); +} diff --git a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h index feb95dcd1..eb1184a40 100644 --- a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h +++ b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h @@ -3,11 +3,21 @@ #include "global.h" -struct ObjBoyo; - typedef struct ObjBoyo { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x6C]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ AnimatedMaterial* animatedMaterial; + /* 0x194 */ s16 unk194; + /* 0x196 */ s16 unk196; + /* 0x198 */ f32 unk198; + /* 0x19C */ f32 unk19C; + /* 0x1A0 */ f32 unk1A0; + /* 0x1A4 */ s16 unk1A4; + /* 0x1A6 */ s16 unk1A6; + /* 0x1A8 */ s16 unk1A8; + /* 0x1AA */ s16 unk1AA; + /* 0x1AC */ s16 unk1AC; + /* 0x1AE */ s16 unk1AE; } ObjBoyo; // size = 0x1B0 #endif // Z_OBJ_BOYO_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 85b13487c..9ad15cf7d 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8743,10 +8743,10 @@ 0x809A5B50:("ObjArmos_Draw",), 0x809A5D10:("ObjBoyo_Init",), 0x809A5D94:("ObjBoyo_Destroy",), - 0x809A5DC0:("func_809A5DC0",), - 0x809A5DE0:("func_809A5DE0",), - 0x809A5E14:("func_809A5E14",), - 0x809A5E24:("func_809A5E24",), + 0x809A5DC0:("ObjBoyo_PushPlayer",), + 0x809A5DE0:("ObjBoyo_PushPirate",), + 0x809A5E14:("ObjBoyo_ExplodeBomb",), + 0x809A5E24:("ObjBoyo_FindCollidedActor",), 0x809A5E98:("ObjBoyo_Update",), 0x809A610C:("ObjBoyo_Draw",), 0x809A6280:("EnGrasshopper_Init",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index b427905c9..7fd394acc 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -9366,10 +9366,9 @@ 0x809A5BF0:("D_809A5BF0","f32","",0x4), 0x809A5BF4:("D_809A5BF4","f32","",0x4), 0x809A6150:("Obj_Boyo_InitVars","UNK_TYPE1","",0x1), - 0x809A6170:("D_809A6170","UNK_TYPE1","",0x1), - 0x809A619C:("D_809A619C","UNK_TYPE1","",0x1), - 0x809A61B0:("D_809A61B0","UNK_TYPE1","",0x1), - 0x809A61B4:("D_809A61B4","UNK_TYPE2","",0x2), + 0x809A6170:("sCylinderInit","ColliderCylinderInit","",0x1), + 0x809A619C:("sInitChain","InitChainEntry","[]",0x4), + 0x809A61AC:("gCollisionHandling","ObjBoyoUnkStruct","[]",0x20), 0x809A61D0:("D_809A61D0","f32","",0x4), 0x809A61D4:("D_809A61D4","f32","",0x4), 0x809A61D8:("D_809A61D8","f32","",0x4), From 01d581641786b25fc88762bb679abada38191326 Mon Sep 17 00:00:00 2001 From: Wimmer <71473855+Wimmerrad@users.noreply.github.com> Date: Fri, 13 Oct 2023 13:50:00 +0200 Subject: [PATCH 2/9] obj_big_fwall (#1435) * Big Fire Wall Big fire wall.xml / Z en encount3.c update * RingOfFire update --- assets/xml/objects/object_big_fwall.xml | 5 +++-- src/overlays/actors/ovl_En_Encount3/z_en_encount3.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/assets/xml/objects/object_big_fwall.xml b/assets/xml/objects/object_big_fwall.xml index bb8b838be..f1becbe8e 100644 --- a/assets/xml/objects/object_big_fwall.xml +++ b/assets/xml/objects/object_big_fwall.xml @@ -1,6 +1,7 @@  + - - + + diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c index 931e8c6d4..fa37bcb38 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c @@ -199,7 +199,7 @@ void EnEncount3_Draw(Actor* thisx, PlayState* play) { Matrix_Scale(this->unk168, this->unk174, this->unk168, 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_big_fwall_DL_0009A0); + gSPDisplayList(POLY_XLU_DISP++, gRingOfFireDL); Matrix_Pop(); CLOSE_DISPS(play->state.gfxCtx); From a03335d325bae37b72beb90f2ad4aab957541e1f Mon Sep 17 00:00:00 2001 From: Nuss <67802335+hack-nuss@users.noreply.github.com> Date: Fri, 13 Oct 2023 19:04:36 +0200 Subject: [PATCH 3/9] ovl_Door_Spiral decompiled (#1432) * data * some matching * all funcs * improvements * improvements * improvements * small clean up --- spec | 3 +- .../actors/ovl_Door_Spiral/z_door_spiral.c | 234 ++++++++++++++++-- .../actors/ovl_Door_Spiral/z_door_spiral.h | 14 +- 3 files changed, 232 insertions(+), 19 deletions(-) diff --git a/spec b/spec index dd160ae09..9b7dcc1fb 100644 --- a/spec +++ b/spec @@ -2079,8 +2079,7 @@ beginseg name "ovl_Door_Spiral" compress include "build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.o" - include "build/data/ovl_Door_Spiral/ovl_Door_Spiral.data.o" - include "build/data/ovl_Door_Spiral/ovl_Door_Spiral.reloc.o" + include "build/src/overlays/actors/ovl_Door_Spiral/ovl_Door_Spiral_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c index 6c7d32152..0370023a8 100644 --- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c +++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c @@ -21,8 +21,17 @@ void DoorSpiral_Destroy(Actor* thisx, PlayState* play); void DoorSpiral_Update(Actor* thisx, PlayState* play); void DoorSpiral_Draw(Actor* thisx, PlayState* play); -/* -const ActorInit Door_Spiral_InitVars = { +void DoorSpiral_SetupAction(DoorSpiral* this, DoorSpiralActionFunc actionFunc); +s32 func_809A2B70(DoorSpiral* this, PlayState* play); +u8 func_809A2BF8(PlayState* play); +f32 func_809A2E08(PlayState* play, DoorSpiral* this, f32 arg2, f32 arg3, f32 arg4); +void func_809A2DB0(DoorSpiral* this, PlayState* play); +void func_809A2FF8(DoorSpiral* this, PlayState* play); +void func_809A2DB0(DoorSpiral* this, PlayState* play); +void func_809A3098(DoorSpiral* this, PlayState* play); +s32 func_809A2EA0(DoorSpiral* this, PlayState* play); + +ActorInit Door_Spiral_InitVars = { ACTOR_DOOR_SPIRAL, ACTORCAT_DOOR, FLAGS, @@ -31,30 +40,223 @@ const ActorInit Door_Spiral_InitVars = { (ActorFunc)DoorSpiral_Init, (ActorFunc)DoorSpiral_Destroy, (ActorFunc)DoorSpiral_Update, - (ActorFunc)DoorSpiral_Draw + (ActorFunc)DoorSpiral_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2B60.s") +typedef struct { + /* 0x0 */ Gfx* dLists[2]; // represents a staircase up or down + /* 0x8 */ u32 unk_08; + /* 0x9 */ u8 unk_09; + /* 0xA */ u8 translateZ; + /* 0xB */ u8 unk_0B; + /* 0xC */ u8 unk_0C; +} SpiralInfo; // size = 0x10 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2B70.s") +SpiralInfo sSpiralInfoTable[] = { + { { NULL, NULL }, 0, 130, 12, 50, 15 }, + { { gameplay_dangeon_keep_DL_0219E0, gameplay_dangeon_keep_DL_01D980 }, 0, 130, 12, 50, 15 }, + { { object_numa_obj_DL_004448, object_numa_obj_DL_0007A8 }, 0, 130, 12, 50, 15 }, + { { object_numa_obj_DL_0051B8, object_numa_obj_DL_0014C8 }, 0, 130, 12, 50, 15 }, + { { object_hakugin_obj_DL_009278, object_hakugin_obj_DL_006128 }, 0, 130, 12, 50, 15 }, + { { object_ikana_obj_DL_013EA8, object_ikana_obj_DL_012B70 }, 0, 130, 12, 50, 15 }, + { { object_ikninside_obj_DL_000EA0, object_ikninside_obj_DL_000590 }, 0, 130, 12, 50, 15 }, + { { object_danpei_object_DL_002110, object_danpei_object_DL_0012C0 }, 0, 130, 12, 50, 15 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2BF8.s") +typedef struct { + /* 0x0 */ s16 objectId; + /* 0x2 */ u8 index; +} SpiralObjectInfo; // size = 0x4 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Init.s") +SpiralObjectInfo sSpiralObjectInfoTable[] = { + { GAMEPLAY_KEEP, 0 }, { GAMEPLAY_DANGEON_KEEP, 1 }, { OBJECT_NUMA_OBJ, 2 }, { OBJECT_HAKUGIN_OBJ, 4 }, + { OBJECT_IKANA_OBJ, 5 }, { OBJECT_DANPEI_OBJECT, 7 }, { OBJECT_IKNINSIDE_OBJ, 6 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Destroy.s") +typedef struct { + /* 0x0 */ s16 sceneId; + /* 0x2 */ u8 index; +} SpiralSceneInfo; // size = 0x4 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2DB0.s") +SpiralSceneInfo sSpiralSceneInfoTable[] = { + { SCENE_MITURIN, 2 }, { SCENE_HAKUGIN, 3 }, { SCENE_INISIE_N, 4 }, { SCENE_INISIE_R, 4 }, + { SCENE_DANPEI2TEST, 5 }, { SCENE_IKNINSIDE, 6 }, { SCENE_CASTLE, 6 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2E08.s") +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2EA0.s") +void DoorSpiral_SetupAction(DoorSpiral* this, DoorSpiralActionFunc actionFunc) { + this->actionFunc = actionFunc; + this->unk14A = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2FF8.s") +s32 func_809A2B70(DoorSpiral* this, PlayState* play) { + SpiralObjectInfo* spiralObjectInfo = &sSpiralObjectInfoTable[this->unk147]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A3098.s") + this->unk148 = spiralObjectInfo->index; + if ((this->unk148 == 7) || ((this->unk148 == 2) && play->roomCtx.curRoom.enablePosLights)) { + if (this->unk148 == 2) { + this->unk148 = 3; + } + this->actor.flags |= ACTOR_FLAG_10000000; + } + DoorSpiral_SetupAction(this, func_809A2FF8); + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Update.s") +u8 func_809A2BF8(PlayState* play) { + SpiralSceneInfo* spiralSceneInfo = sSpiralSceneInfoTable; + s32 i; + u8 var_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Draw.s") + for (i = 0; i < ARRAY_COUNT(sSpiralSceneInfoTable); i++) { + if (play->sceneId == spiralSceneInfo->sceneId) { + break; + } + spiralSceneInfo++; + } + if (i < ARRAY_COUNT(sSpiralSceneInfoTable)) { + var_v1 = spiralSceneInfo->index; + } else { + var_v1 = (Object_GetSlot(&play->objectCtx, GAMEPLAY_DANGEON_KEEP) > OBJECT_SLOT_NONE) ? 1 : 0; + } + return var_v1; +} + +void DoorSpiral_Init(Actor* thisx, PlayState* play) { + DoorSpiral* this = THIS; + s32 transitionId = DOOR_GET_TRANSITION_ID(thisx); + s8 objectSlot; + + if (this->actor.room != play->doorCtx.transitionActorList[transitionId].sides[0].room) { + Actor_Kill(&this->actor); + return; + } + Actor_ProcessInitChain(&this->actor, sInitChain); + this->type = DOORSPIRAL_GET_TYPE(thisx); + this->direction = DOORSPIRAL_GET_DIRECTION(thisx); + this->unk147 = func_809A2BF8(play); + objectSlot = Object_GetSlot(&play->objectCtx, sSpiralObjectInfoTable[this->unk147].objectId); + this->objectSlot = objectSlot; + if (objectSlot <= OBJECT_SLOT_NONE) { + Actor_Kill(&this->actor); + return; + } + DoorSpiral_SetupAction(this, func_809A2DB0); + Actor_SetFocus(&this->actor, 60.0f); +} + +void DoorSpiral_Destroy(Actor* thisx, PlayState* play) { + s32 transitionId = DOOR_GET_TRANSITION_ID(thisx); + + play->doorCtx.transitionActorList[transitionId].id = -play->doorCtx.transitionActorList[transitionId].id; +} + +void func_809A2DB0(DoorSpiral* this, PlayState* play) { + if (Object_IsLoaded(&play->objectCtx, this->objectSlot)) { + this->actor.objectSlot = this->objectSlot; + func_809A2B70(this, play); + } +} + +f32 func_809A2E08(PlayState* play, DoorSpiral* this, f32 arg2, f32 arg3, f32 arg4) { + Player* player = GET_PLAYER(play); + Vec3f point; + Vec3f offset; + + point.x = player->actor.world.pos.x; + point.y = player->actor.world.pos.y + arg2; + point.z = player->actor.world.pos.z; + + Actor_OffsetOfPointInActorCoords(&this->actor, &offset, &point); + + if ((arg3 < fabsf(offset.x)) || (arg4 < fabsf(offset.y))) { + return FLT_MAX; + } else { + return offset.z; + } +} + +s32 func_809A2EA0(DoorSpiral* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (!Player_InCsMode(play)) { + SpiralInfo* spiralInfo = &sSpiralInfoTable[this->unk148]; + f32 temp_fv0 = func_809A2E08(play, this, 0.0f, spiralInfo->unk_0B, spiralInfo->unk_0C); + + if (fabsf(temp_fv0) < 64.0f) { + s16 var_v0 = player->actor.shape.rot.y - this->actor.shape.rot.y; + + if (temp_fv0 > 0.0f) { + var_v0 = 0x8000 - var_v0; + } + if (ABS_ALT(var_v0) < 0x3000) { + return (temp_fv0 >= 0.0f) ? 1.0f : -1.0f; + } + } + } + return 0; +} + +void func_809A2FF8(DoorSpiral* this, PlayState* play) { + Player* player; + u32 transitionId; + + if (this->shouldClimb) { + DoorSpiral_SetupAction(this, func_809A3098); + } else if (func_809A2EA0(this, play) != 0) { + player = GET_PLAYER(play); + player->doorType = PLAYER_DOORTYPE_STAIRCASE; + player->doorDirection = this->direction; + player->doorActor = &this->actor; + transitionId = DOOR_GET_TRANSITION_ID(&this->actor); + player->doorNext = (play->doorCtx.transitionActorList[transitionId].params >> 0xA); + func_80122F28(player); + } +} + +void func_809A3098(DoorSpiral* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if (!(player->stateFlags1 & PLAYER_STATE1_20000000)) { + DoorSpiral_SetupAction(this, func_809A2DB0); + this->shouldClimb = false; + } +} + +void DoorSpiral_Update(Actor* thisx, PlayState* play) { + DoorSpiral* this = THIS; + Player* player = GET_PLAYER(play); + + if (!(player->stateFlags1 & (PLAYER_STATE1_40 | PLAYER_STATE1_80 | PLAYER_STATE1_400 | PLAYER_STATE1_10000000)) || + (this->actionFunc == func_809A2DB0)) { + this->actionFunc(this, play); + } +} + +void DoorSpiral_Draw(Actor* thisx, PlayState* play) { + s32 pad; + DoorSpiral* this = THIS; + + if (this->actor.objectSlot == this->objectSlot) { + SpiralInfo* spiralInfo = &sSpiralInfoTable[this->unk148]; + Gfx* dList = spiralInfo->dLists[this->direction]; + + if (dList != NULL) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, spiralInfo->dLists[this->direction]); + + CLOSE_DISPS(play->state.gfxCtx); + } + } +} diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h index af4f27aea..6d9aac7e6 100644 --- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h +++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h @@ -2,13 +2,25 @@ #define Z_DOOR_SPIRAL_H #include "global.h" +#include "z64door.h" struct DoorSpiral; +typedef void (*DoorSpiralActionFunc)(struct DoorSpiral*, PlayState*); + +#define DOORSPIRAL_GET_TYPE(thisx) (((thisx)->params >> 8) & 0x3) +#define DOORSPIRAL_GET_DIRECTION(thisx) (((thisx)->params >> 7) & 0x1) + typedef struct DoorSpiral { /* 0x000 */ Actor actor; /* 0x144 */ u8 shouldClimb; - /* 0x145 */ UNK_TYPE1 unk_145[0xB]; + /* 0x145 */ s8 type; + /* 0x146 */ u8 direction; // represents a staircase up or down + /* 0x147 */ u8 unk147; + /* 0x148 */ u8 unk148; + /* 0x149 */ s8 objectSlot; + /* 0x14A */ s8 unk14A; + /* 0x14C */ DoorSpiralActionFunc actionFunc; } DoorSpiral; // size = 0x150 #endif // Z_DOOR_SPIRAL_H From 576cf6964cf5155ac208e6cebb5f8d5cb53120bd Mon Sep 17 00:00:00 2001 From: Wimmer <71473855+Wimmerrad@users.noreply.github.com> Date: Fri, 13 Oct 2023 19:23:09 +0200 Subject: [PATCH 4/9] Obj_visiblock (#1422) * Obj_visiblock Object for the Lens of Truth Platforms * Update assets/xml/objects/object_visiblock.xml DList update Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update assets/xml/objects/object_visiblock.xml Tex outname update Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update z_obj_visiblock.c DList name update * Revert "Update assets/xml/objects/object_visiblock.xml " This reverts commit 228d6e8914d1a9df7f996809bd876b44130ddf86. * Revert "Update assets/xml/objects/object_visiblock.xml " This reverts commit 53a8786f269e60899408946283e2e55513890486. * Update object_visiblock.xml --------- Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> --- assets/xml/objects/object_visiblock.xml | 9 +++++---- src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/assets/xml/objects/object_visiblock.xml b/assets/xml/objects/object_visiblock.xml index d714338fc..cae048322 100644 --- a/assets/xml/objects/object_visiblock.xml +++ b/assets/xml/objects/object_visiblock.xml @@ -1,8 +1,9 @@  + - - - - + + + + diff --git a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c index 9859d9c0f..c685f2836 100644 --- a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c +++ b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c @@ -39,7 +39,7 @@ void ObjVisiblock_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, 0); - DynaPolyActor_LoadMesh(play, &this->dyna, &object_visiblock_Colheader_000AD0); + DynaPolyActor_LoadMesh(play, &this->dyna, &gLensOfTruthPlatformCol); } void ObjVisiblock_Destroy(Actor* thisx, PlayState* play) { @@ -49,5 +49,5 @@ void ObjVisiblock_Destroy(Actor* thisx, PlayState* play) { } void ObjVisiblock_Draw(Actor* thisx, PlayState* play) { - Gfx_DrawDListXlu(play, object_visiblock_DL_000140); + Gfx_DrawDListXlu(play, gLensOfTruthPlatformDL); } From 93713a1da05ba0c728a0da3eb07d281d700341eb Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Sat, 14 Oct 2023 07:39:10 +1100 Subject: [PATCH 5/9] Audio Sequences Decompiled & Documented (z_obj_sound OK, more code_8019AF00.c) (#1407) * import audio docs * cleanup * SEQ_SCREEN_WEIGHTED_DIST * PR * PR --- include/functions.h | 22 +- spec | 3 +- src/audio/code_8019AF00.c | 481 +++++++++++++++++- src/code/z_actor.c | 4 +- .../actors/ovl_En_Guruguru/z_en_guruguru.c | 4 +- .../actors/ovl_En_Minifrog/z_en_minifrog.c | 6 +- src/overlays/actors/ovl_En_Rz/z_en_rz.c | 20 +- src/overlays/actors/ovl_En_Zob/z_en_zob.c | 10 +- src/overlays/actors/ovl_En_Zod/z_en_zod.c | 2 +- src/overlays/actors/ovl_En_Zos/z_en_zos.c | 10 +- .../actors/ovl_Obj_Sound/z_obj_sound.c | 52 +- .../actors/ovl_Obj_Sound/z_obj_sound.h | 15 +- tools/disasm/functions.txt | 32 +- tools/disasm/variables.txt | 2 +- tools/sizes/code_functions.csv | 32 +- 15 files changed, 583 insertions(+), 112 deletions(-) diff --git a/include/functions.h b/include/functions.h index 74b593152..829291c25 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1292,21 +1292,13 @@ void Audio_SetBgmVolumeOn(void); void func_801A0204(s8 seqId); void Audio_SetMainBgmVolume(u8 targetVolume, u8 volumeFadeTimer); void AudioSfx_SetChannelIO(Vec3f* pos, u16 sfxId, u8 ioData); -// void func_801A1290(void); -// void func_801A1348(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -// void func_801A13BC(void); -// void func_801A153C(void); -// void func_801A17F4(void); -// void func_801A1904(void); -// void func_801A1A10(void); -// void func_801A1A8C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -void func_801A1D44(Vec3f* vec, u8 seqId, f32 arg2); -void func_801A1DB8(Vec3f* vec, u8 seqId, f32 arg2); -// void func_801A1E0C(void); -void func_801A1F00(u8 arg0, u16 seqId); -void func_801A1F88(void); -void func_801A1FB4(u8 playerIndex, Vec3f* pos, u16 seqId, f32 maxDist); -// void func_801A2090(void); +void Audio_PlayObjSoundBgm(Vec3f* pos, s8 seqId); +void Audio_PlayObjSoundFanfare(Vec3f* pos, s8 seqId); +void Audio_PlaySubBgmAtPos(Vec3f* pos, u8 seqId, f32 maxDist); +void Audio_PlaySubBgmAtPosWithFilter(Vec3f* pos, u8 seqId, f32 arg2); +void Audio_PlaySequenceAtDefaultPos(u8 seqPlayerIndex, u16 seqId); +void Audio_StopSequenceAtDefaultPos(void); +void Audio_PlaySequenceAtPos(u8 seqPlayerIndex, Vec3f* pos, u16 seqId, f32 maxDist); void func_801A246C(u8 param_1, u8 param_2); void Audio_PlayMorningSceneSequence(u16 seqId, u8 dayMinusOne); void Audio_PlaySceneSequence(u16 seqId, u8 dayMinusOne); diff --git a/spec b/spec index 9b7dcc1fb..6cd76563c 100644 --- a/spec +++ b/spec @@ -2000,8 +2000,7 @@ beginseg name "ovl_Obj_Sound" compress include "build/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.o" - include "build/data/ovl_Obj_Sound/ovl_Obj_Sound.data.o" - include "build/data/ovl_Obj_Sound/ovl_Obj_Sound.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Sound/ovl_Obj_Sound_reloc.o" endseg beginseg diff --git a/src/audio/code_8019AF00.c b/src/audio/code_8019AF00.c index dcefd2eae..5fb24860f 100644 --- a/src/audio/code_8019AF00.c +++ b/src/audio/code_8019AF00.c @@ -77,10 +77,10 @@ void Audio_PlayAmbience(u8 ambienceId); void Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(u8 volume); void Audio_UpdateRiverSoundVolumes(void); -void func_801A1290(void); -void func_801A1904(void); -void func_801A1E0C(void); -void func_801A2090(void); +void Audio_UpdateObjSoundProperties(void); +void Audio_UpdateObjSoundFanfare(void); +void Audio_UpdateSubBgmAtPos(void); +void Audio_UpdateSequenceAtPos(void); void Audio_UpdateSceneSequenceResumePoint(void); void func_801A312C(void); void func_801A3AC0(void); @@ -116,7 +116,14 @@ u8 sRiverSoundBgmTimer; u8 sFanfareState; u16 sFanfareSeqId; u8 sMuteOnlySfxAndAmbienceSeq; -u8 sAllPlayersMutedExceptOcaAndSys; +u8 sAllPlayersMutedExceptSystemAndOcarina; + +typedef enum { + /* 0 */ AUDIO_PAUSE_STATE_CLOSED, + /* 1 */ AUDIO_PAUSE_STATE_CLOSING, + /* 2 */ AUDIO_PAUSE_STATE_OPEN +} AudioPauseState; + u8 sAudioPauseState; u8 sSpatialSeqIsActive[4]; u8 sSequenceFilter[8 * 4]; @@ -237,6 +244,10 @@ Vec3f* sRiverSoundBgmPos = NULL; f32 sRiverSoundXZDistToPlayer = 2000.0f; u8 sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX; +// Weights distance strongest by depth (z), weaker by left/right screen (x), and weakest by top/bottom screen (y) +#define SEQ_SCREEN_WEIGHTED_DIST(projectedPos) \ + (sqrtf(SQ((projectedPos)->z) + ((SQ((projectedPos)->x) / 4.0f) + (SQ((projectedPos)->y) / 6.0f)))) + // Allows enemy bgm #define SEQ_FLAG_ENEMY (1 << 0) @@ -3639,11 +3650,11 @@ void Audio_Update(void) { Audio_UpdateSceneSequenceResumePoint(); func_801A312C(); Audio_UpdateSfxVolumeTransition(); - func_801A1E0C(); - func_801A1904(); - func_801A2090(); + Audio_UpdateSubBgmAtPos(); + Audio_UpdateObjSoundFanfare(); + Audio_UpdateSequenceAtPos(); func_801A3AC0(); - func_801A1290(); + Audio_UpdateObjSoundProperties(); Audio_ResetRequestedSceneSeqId(); AudioSfx_ProcessRequests(); AudioSeq_ProcessSeqCmds(); @@ -4870,37 +4881,455 @@ void Audio_SplitBgmChannels(s8 volumeSplit) { } } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0E44.s") +void Audio_SetSequenceProperties(u8 seqPlayerIndex, Vec3f* projectedPos, s16 flags, f32 minDist, f32 maxDist, + f32 maxVolume, f32 minVolume) { + f32 dist; + f32 volume; + s8 surroundEffectIndex; + s8 pan; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1290.s") + // calculating surround sound effect from screen depth + if (projectedPos->z > 0.0f) { + if (projectedPos->z > 100.0f) { + surroundEffectIndex = 0; + } else { + surroundEffectIndex = ((100.0f - projectedPos->z) / 100.0f) * 64.0f; + } + } else { + if (projectedPos->z < -100.0f) { + surroundEffectIndex = 0x7F; + } else { + surroundEffectIndex = (s8)((-projectedPos->z / 100.0f) * 64.0f) + 0x3F; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1348.s") + // calculating pan from left-right screen position + if (projectedPos->x > 0.0f) { + if (projectedPos->x > 200.0f) { + pan = 0x6C; + } else { + pan = (s8)((projectedPos->x / 200.0f) * 45.0f) + 0x3F; + } + } else { + if (projectedPos->x < -200.0f) { + pan = 0x14; + } else { + pan = (s8)(((projectedPos->x + 200.0f) / 200.0f) * 44.0f) + 0x14; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A13BC.s") + // Calculate weighted volume + dist = SEQ_SCREEN_WEIGHTED_DIST(projectedPos); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A153C.s") + if (dist > maxDist) { + volume = minVolume; + } else if (dist < minDist) { + volume = 1.0f; + } else { + volume = (((maxDist - dist) / (maxDist - minDist)) * (1.0f - minVolume)) + minVolume; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A17F4.s") + AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, 0xFFFF); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1904.s") + if (flags & 1) { + AUDIOCMD_CHANNEL_SET_SURROUND_EFFECT_INDEX(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, surroundEffectIndex); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A10.s") + if (flags & 2) { + AUDIOCMD_CHANNEL_SET_PAN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, pan); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A8C.s") + if (flags & 4) { + AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x7F); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1D44.s") + // applies filter, stores result in sSequenceFilter + if (flags & 8) { + // Uses new filter gBandPassFilterData + AUDIOCMD_CHANNEL_SET_FILTER(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x54, + ((u32)&sSequenceFilter[0] & ~0xF) + 0x10); + } else { + // Identity Filter + AUDIOCMD_CHANNEL_SET_FILTER(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0, ((u32)&sSequenceFilter[0] & ~0xF) + 0x10); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1DB8.s") + if (flags & 0x10) { + AUDIOCMD_CHANNEL_SET_GAIN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x7F); + } else { + AUDIOCMD_CHANNEL_SET_GAIN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1E0C.s") + if (flags & 0x20) { + AUDIOCMD_CHANNEL_SET_VOL_SCALE(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, maxVolume * volume); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F00.s") + if (flags & 0x40) { + AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x40); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F88.s") + if (flags & 0x80) { + AUDIOCMD_CHANNEL_SET_REVERB_INDEX(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1FB4.s") + if (flags & 0x100) { + AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 55); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2090.s") +// ======== BEGIN Z_OBJ_SOUND FUNCTIONS ======== + +/** + * Used for Main Bgm and Fanfares + */ +void Audio_UpdateObjSoundProperties(void) { + if (sObjSoundPlayerIndex != SEQ_PLAYER_INVALID) { + if ((AudioSeq_GetActiveSeqId(sObjSoundPlayerIndex) != NA_BGM_FINAL_HOURS) && + AudioSeq_IsSeqCmdNotQueued((sObjSoundPlayerIndex << 24) + NA_BGM_FINAL_HOURS, + SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK | + SEQCMD_SEQID_MASK) && + !sIsFinalHoursOrSoaring) { + Audio_SetSequenceProperties(sObjSoundPlayerIndex, &sObjSoundPos, sObjSoundFlags, sObjSoundMinDist, + sObjSoundMaxDist, sObjSoundMaxVol, sObjSoundMinVol); + } + sObjSoundPlayerIndex = SEQ_PLAYER_INVALID; + } +} + +/** + * Used for Main Bgm and Fanfares + */ +void Audio_SetObjSoundProperties(u8 seqPlayerIndex, Vec3f* pos, s16 flags, f32 minDist, f32 maxDist, f32 maxVolume, + f32 minVolume) { + sObjSoundPlayerIndex = seqPlayerIndex; + sObjSoundPos.x = pos->x; + sObjSoundPos.y = pos->y; + sObjSoundPos.z = pos->z; + sObjSoundFlags = flags; + sObjSoundMinDist = minDist; + sObjSoundMaxDist = maxDist; + sObjSoundMaxVol = maxVolume; + sObjSoundMinVol = minVolume; +} + +void Audio_StartObjSoundFanfare(u8 seqPlayerIndex, Vec3f* pos, s8 seqId, u16 seqIdOffset) { + s32 pad[3]; + u32 mask; + + if ((AudioSeq_GetActiveSeqId(seqPlayerIndex) == NA_BGM_FINAL_HOURS) || + !AudioSeq_IsSeqCmdNotQueued((seqPlayerIndex << 0x18) + NA_BGM_FINAL_HOURS, + SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK | SEQCMD_SEQID_MASK) || + sIsFinalHoursOrSoaring) { + sIsFinalHoursOrSoaring = true; + } else if (pos != NULL) { + if ((seqId != (s8)(AudioSeq_GetActiveSeqId(seqPlayerIndex) & 0xFFFF)) && + !gAudioCtx.seqPlayers[seqPlayerIndex].enabled && (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX)) { + + mask = 0xFFFF; + + SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, ((((AudioThread_NextRandom() % 30) & 0xFF) + 1)), + ((seqId & mask) + seqIdOffset)); + sObjSoundMainBgmSeqId = seqId; + } + + Audio_SetObjSoundProperties(seqPlayerIndex, pos, 0x7F, 320.0f, 1280.0f, 1.0f, 0.0f); + } else { + SEQCMD_STOP_SEQUENCE(seqPlayerIndex, 5); + } +} + +void Audio_PlayObjSoundBgm(Vec3f* pos, s8 seqId) { + s32 pad[2]; + u16 sp36; + s32 sp2C; + u16 seqId0 = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); + u32 temp_a0; + + if ((seqId0 == NA_BGM_FINAL_HOURS) || + !AudioSeq_IsSeqCmdNotQueued(NA_BGM_FINAL_HOURS, + SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK | SEQCMD_SEQID_MASK) || + sIsFinalHoursOrSoaring) { + sIsFinalHoursOrSoaring = true; + return; + } + + if (seqId0 == NA_BGM_SONG_OF_SOARING) { + sIsFinalHoursOrSoaring = true; + } + + if (pos != NULL) { + if (seqId == NA_BGM_ASTRAL_OBSERVATORY) { + + if ((seqId != (u8)(seqId0 & 0xFF)) && !sAllPlayersMutedExceptSystemAndOcarina) { + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, (u16)seqId); + sObjSoundMainBgmSeqId = seqId; + } else if ((seqId == (u8)(seqId0 & 0xFF)) && (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX)) { + sObjSoundMainBgmSeqId = seqId; + } + + Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x20, 100.0f, 1500.0f, 0.9f, 0.0f); + } else { + if (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX) { + temp_a0 = ((((AudioThread_NextRandom() % 30) & 0xFF) + 1) << 0x10) | ((u16)seqId + 0x7F00); + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, temp_a0); + sObjSoundMainBgmSeqId = seqId; + } + + if (seqId == NA_BGM_MILK_BAR_DUPLICATE) { + Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x1E3, 0.0f, 600.0f, 0.9f, 0.55f); + } else if (seqId == NA_BGM_MILK_BAR) { + Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x1FF, 0.0f, 600.0f, 0.9f, 0.55f); + } else { + Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x3F, 0.0f, 600.0f, 0.9f, 0.55f); + } + } + } else { + if (sObjSoundMainBgmSeqId == NA_BGM_ASTRAL_OBSERVATORY) { + AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(SEQ_PLAYER_BGM_MAIN, 0xFFFF); + AUDIOCMD_CHANNEL_SET_VOL_SCALE(SEQ_PLAYER_BGM_MAIN, AUDIOCMD_ALL_CHANNELS, 1.0f); + SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 10, NA_BGM_CAVERN); + } else { + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 5); + } + + sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX; + } +} + +void Audio_PlayObjSoundFanfare(Vec3f* pos, s8 seqId) { + s32 requestFanfare = false; + s32 pad; + + if (sObjSoundFanfareSeqId == NA_BGM_GENERAL_SFX) { + // No spatial fanfare is currently playing + requestFanfare = true; + } else if (SEQ_SCREEN_WEIGHTED_DIST(pos) < SEQ_SCREEN_WEIGHTED_DIST(&sObjSoundFanfarePos)) { + // The spatial fanfare requested is closer than the spatial fanfare currently playing + requestFanfare = true; + } + + if (requestFanfare) { + sObjSoundFanfarePos.x = pos->x; + sObjSoundFanfarePos.y = pos->y; + sObjSoundFanfarePos.z = pos->z; + sObjSoundFanfareSeqId = seqId; + sObjSoundFanfareRequested = true; + } +} + +void Audio_UpdateObjSoundFanfare(void) { + if (sObjSoundFanfareRequested && (sAudioPauseState == AUDIO_PAUSE_STATE_CLOSED)) { + if (sObjSoundFanfareSeqId != NA_BGM_GENERAL_SFX) { + Audio_StartObjSoundFanfare(SEQ_PLAYER_FANFARE, &sObjSoundFanfarePos, sObjSoundFanfareSeqId, 0); + + if (AudioSeq_GetActiveSeqId(SEQ_PLAYER_FANFARE) == NA_BGM_DISABLED) { + func_801A3038(); + } + + if ((AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) && + (AudioSeq_GetActiveSeqId(SEQ_PLAYER_AMBIENCE) == NA_BGM_DISABLED)) { + Audio_PlayAmbience(AMBIENCE_ID_09); + } + + sAudioCutsceneFlag = true; + } else { + Audio_StartObjSoundFanfare(SEQ_PLAYER_FANFARE, NULL, sObjSoundFanfareSeqId, 0); + if (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) { + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, 0); + } + sObjSoundFanfareRequested = false; + sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX; + sAudioCutsceneFlag = false; + } + sObjSoundFanfareSeqId = NA_BGM_GENERAL_SFX; + } +} + +// ======== END Z_OBJ_SOUND FUNCTIONS ======== + +void Audio_StopSequenceAtPos(u8 seqPlayerIndex, u8 volumeFadeTimer) { + SEQCMD_STOP_SEQUENCE((u32)seqPlayerIndex, 20); + if ((seqPlayerIndex == SEQ_PLAYER_BGM_SUB) && (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED)) { + AudioSeq_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, 0x7F, volumeFadeTimer); + Audio_SplitBgmChannels(0); + } +} + +void Audio_StartSubBgmAtPos(u8 seqPlayerIndex, Vec3f* projectedPos, u8 seqId, u8 flags, f32 minDist, f32 maxDist, + f32 arg6) { + f32 dist = SEQ_SCREEN_WEIGHTED_DIST(projectedPos); + u8 targetVolume; + u16 seqId0 = AudioSeq_GetActiveSeqId(seqPlayerIndex); + f32 relVolume; + s32 pad; + + if (dist > maxDist) { + if ((u8)seqId0 == seqId) { + Audio_StopSequenceAtPos(seqPlayerIndex, 10); + sSpatialSeqIsActive[seqPlayerIndex] = false; + } + return; + } + + if ((!gAudioCtx.seqPlayers[seqPlayerIndex].enabled && !sAllPlayersMutedExceptSystemAndOcarina) || + (seqId0 == (NA_BGM_ENEMY | 0x800))) { + if (seqPlayerIndex == SEQ_PLAYER_BGM_SUB) { + AudioSeq_SetVolumeScale(seqPlayerIndex, VOL_SCALE_INDEX_BGM_SUB, 0x7F, 1); + } + + SEQCMD_PLAY_SEQUENCE((u32)seqPlayerIndex, 1, seqId); + + sSpatialSeqIsActive[seqPlayerIndex] = true; + } + + Audio_SetSequenceProperties(seqPlayerIndex, projectedPos, flags, minDist, maxDist, 1.0, 0.05f); + + if ((seqPlayerIndex == SEQ_PLAYER_BGM_SUB) && (gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].enabled == true)) { + + if (dist > maxDist) { + relVolume = 1.0f; + } else if (dist < minDist) { + relVolume = 0.0f; + } else { + relVolume = 1.0f - ((maxDist - dist) / (maxDist - minDist)); + } + + targetVolume = (u8)(relVolume * 127.0f); + + AudioSeq_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, targetVolume, 10); + Audio_SplitBgmChannels(0x7F - targetVolume); + } +} + +/** + * sSpatialSeqNoFilterPos takes priority over sSpatialSeqFilterPos + * Used only by guru guru for song of storms + */ +void Audio_PlaySubBgmAtPos(Vec3f* pos, u8 seqId, f32 maxDist) { + if (gAudioSpecId != 0xC) { + sSpatialSeqNoFilterPos.x = pos->x; + sSpatialSeqNoFilterPos.y = pos->y; + sSpatialSeqNoFilterPos.z = pos->z; + sSpatialSeqSeqId = seqId; + sSpatialSeqMaxDist = maxDist; + sSpatialSeqFlags |= 2; // Only update volume + sSpatialSubBgmFadeTimer = 4; + } +} + +// Used only by guru guru for song of storms in stock pot from hallway or neighboring room +void Audio_PlaySubBgmAtPosWithFilter(Vec3f* pos, u8 seqId, f32 maxDist) { + sSpatialSeqFilterPos.x = pos->x; + sSpatialSeqFilterPos.y = pos->y; + sSpatialSeqFilterPos.z = pos->z; + sSpatialSeqSeqId = seqId; + //! @bug Did not set sSpatialSeqMaxDist = maxDist; This will use the previously set value of sSpatialSeqMaxDist + sSpatialSeqFlags |= 1; // Update with volume and filter + sSpatialSubBgmFadeTimer = 4; +} + +// Another bgm by pos, less customization +void Audio_UpdateSubBgmAtPos(void) { + if (sSpatialSubBgmFadeTimer != 0) { + if (sSpatialSeqFlags & 2) { + // Affects only volume + Audio_StartSubBgmAtPos(SEQ_PLAYER_BGM_SUB, &sSpatialSeqNoFilterPos, sSpatialSeqSeqId, 0x20, 100.0f, + sSpatialSeqMaxDist, 1.0f); + } else { + // Set volume with band-pass filter + Audio_StartSubBgmAtPos(SEQ_PLAYER_BGM_SUB, &sSpatialSeqFilterPos, sSpatialSeqSeqId, 0x28, 100.0f, + sSpatialSeqMaxDist, 1.0f); + } + + sSpatialSubBgmFadeTimer--; + if (sSpatialSubBgmFadeTimer == 0) { + Audio_StopSequenceAtPos(SEQ_PLAYER_BGM_SUB, 10); + } + + sSpatialSeqFlags = 0; + } +} + +/** + * Play sequence at the default center of the screen. Does not check for final hours or soaring bgms playing + * Used only by minifrog for the frog song + */ +void Audio_PlaySequenceAtDefaultPos(u8 seqPlayerIndex, u16 seqId) { + if (!sAudioCutsceneFlag && (gAudioSpecId != 0xC)) { + sSpatialSeqFilterPos.x = gSfxDefaultPos.x; + sSpatialSeqFilterPos.y = gSfxDefaultPos.y; + sSpatialSeqFilterPos.z = gSfxDefaultPos.z; + sSpatialSeqMaxDist = 10000.0f; + sSpatialSeqFadeTimer = 128; + sSpatialSeqSeqId = seqId; + sSpatialSeqPlayerIndex = seqPlayerIndex; + } +} + +// Used only by minifrog +void Audio_StopSequenceAtDefaultPos(void) { + if (gAudioSpecId != 0xC) { + sSpatialSeqFadeTimer = 1; + sSpatialSeqSeqId = NA_BGM_GENERAL_SFX; + } +} + +/** + * Play the requested sequence at a position. Valid for sequences on players 0 - 3 + */ +void Audio_PlaySequenceAtPos(u8 seqPlayerIndex, Vec3f* pos, u16 seqId, f32 maxDist) { + if ((!sAudioCutsceneFlag) && ((AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) & 0xFF) != NA_BGM_SONG_OF_SOARING) && + (gAudioSpecId != 0xC) && (pos != NULL) && + ((sSpatialSeqPlayerIndex != SEQ_PLAYER_BGM_MAIN) || + (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_FINAL_HOURS))) { + sSpatialSeqFilterPos.x = pos->x; + sSpatialSeqFilterPos.y = pos->y; + sSpatialSeqFilterPos.z = pos->z; + sSpatialSeqMaxDist = maxDist; + sSpatialSeqFadeTimer = 2; + sSpatialSeqSeqId = seqId & 0xFF; + sSpatialSeqPlayerIndex = seqPlayerIndex; + } +} + +void Audio_UpdateSequenceAtPos(void) { + u16 mainBgmSeqId = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); + u8 volumeFadeTimer; + + if ((sSpatialSeqFadeTimer != 0) && (sAudioPauseState == AUDIO_PAUSE_STATE_CLOSED)) { + if ((sSpatialSeqSeqId == NA_BGM_GENERAL_SFX) || (mainBgmSeqId == NA_BGM_SONG_OF_SOARING)) { + volumeFadeTimer = 10; + + if (mainBgmSeqId == NA_BGM_SONG_OF_SOARING) { + sSpatialSeqFadeTimer = 0; + volumeFadeTimer = 1; + } else if (sSpatialSeqFadeTimer < 128) { + sSpatialSeqFadeTimer--; + } + + if (sSpatialSeqFadeTimer == 0) { + Audio_StopSequenceAtPos(sSpatialSeqPlayerIndex, volumeFadeTimer); + sSpatialSeqIsActive[sSpatialSeqPlayerIndex] = false; + } + } else { + if ((sSpatialSeqPlayerIndex == SEQ_PLAYER_BGM_MAIN) && (mainBgmSeqId == NA_BGM_FINAL_HOURS)) { + Audio_StopSequenceAtPos(sSpatialSeqPlayerIndex, 10); + sSpatialSeqIsActive[sSpatialSeqPlayerIndex] = false; + return; + } + + Audio_StartSubBgmAtPos(sSpatialSeqPlayerIndex, &sSpatialSeqFilterPos, sSpatialSeqSeqId, 0x20, 200.0f, + sSpatialSeqMaxDist, 1.0f); + if (!sSpatialSeqIsActive[sSpatialSeqPlayerIndex]) { + sSpatialSeqFadeTimer = 0; + } + } + + if (sSpatialSeqFadeTimer < 128) { + sSpatialSeqSeqId = NA_BGM_GENERAL_SFX; + } + } +} /** * Unused remnant of OoT's EnRiverSound @@ -5408,7 +5837,7 @@ void Audio_StartSfxPlayer(void) { void Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(u8 volume) { u8 channelIndex; - if (!sAllPlayersMutedExceptOcaAndSys) { + if (!sAllPlayersMutedExceptSystemAndOcarina) { for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { switch (channelIndex) { case SFX_CHANNEL_SYSTEM0: diff --git a/src/code/z_actor.c b/src/code/z_actor.c index eb5ba018d..e1c13ae4a 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -2767,11 +2767,11 @@ void Actor_UpdateFlaggedAudio(Actor* actor) { if (sfxId != NA_SE_NONE) {} if (actor->audioFlags & ACTOR_AUDIO_FLAG_SEQ_MUSIC_BOX_HOUSE) { - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &actor->projectedPos, NA_BGM_MUSIC_BOX_HOUSE, 1500.0f); + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &actor->projectedPos, NA_BGM_MUSIC_BOX_HOUSE, 1500.0f); } if (actor->audioFlags & ACTOR_AUDIO_FLAG_SEQ_KAMARO_DANCE) { - func_801A1FB4(SEQ_PLAYER_BGM_MAIN, &actor->projectedPos, NA_BGM_KAMARO_DANCE, 900.0f); + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_MAIN, &actor->projectedPos, NA_BGM_KAMARO_DANCE, 900.0f); } } diff --git a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c index 92afb3083..b3ae6bbeb 100644 --- a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c +++ b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c @@ -350,12 +350,12 @@ void EnGuruguru_Update(Actor* thisx, PlayState* play) { if (this->actor.params == 2) { if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 100.0f) { - func_801A1DB8(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); + Audio_PlaySubBgmAtPosWithFilter(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); } return; } if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 200.0f) { - func_801A1D44(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); + Audio_PlaySubBgmAtPos(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); } if (this->unusedTimer != 0) { this->unusedTimer--; diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c index 8495411d5..ce3beaa2a 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -150,7 +150,7 @@ void EnMinifrog_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); if (this->flags & 0x100) { - func_801A1F88(); + Audio_StopSequenceAtDefaultPos(); } } @@ -438,7 +438,7 @@ void EnMinifrog_SetupNextFrogChoir(EnMinifrog* this, PlayState* play) { this->actionFunc = EnMinifrog_NextFrogMissing; this->timer = 60; this->actor.home.rot.y = Actor_WorldYawTowardActor(&this->actor, &this->frog->actor); - func_801A1F88(); + Audio_StopSequenceAtDefaultPos(); this->flags &= ~0x100; this->flags &= ~(0x2 << FROG_YELLOW | 0x2 << FROG_CYAN | 0x2 << FROG_PINK | 0x2 << FROG_BLUE | 0x2 << FROG_WHITE); @@ -460,7 +460,7 @@ void EnMinifrog_BeginChoirCutscene(EnMinifrog* this, PlayState* play) { CutsceneManager_Start(this->actor.csId, &this->actor); this->actionFunc = EnMinifrog_SetupNextFrogChoir; this->timer = 5; - func_801A1F00(3, NA_BGM_FROG_SONG); + Audio_PlaySequenceAtDefaultPos(SEQ_PLAYER_BGM_SUB, NA_BGM_FROG_SONG); this->flags |= 0x100; play->setPlayerTalkAnim(play, &gPlayerAnim_pn_gakkiplay, ANIMMODE_LOOP); } else { diff --git a/src/overlays/actors/ovl_En_Rz/z_en_rz.c b/src/overlays/actors/ovl_En_Rz/z_en_rz.c index a7bfd13f0..a1ed46868 100644 --- a/src/overlays/actors/ovl_En_Rz/z_en_rz.c +++ b/src/overlays/actors/ovl_En_Rz/z_en_rz.c @@ -417,7 +417,7 @@ void func_80BFC058(EnRz* this, PlayState* play) { void func_80BFC078(EnRz* this, PlayState* play) { s32 pad; - Vec3f sp28; + Vec3f seqPos; EnRz_UpdateSkelAnime(this, play); @@ -443,10 +443,10 @@ void func_80BFC078(EnRz* this, PlayState* play) { } if (EN_RZ_GET_SISTER(&this->actor) == EN_RZ_JUDO) { - sp28.x = this->actor.projectedPos.x; - sp28.y = this->actor.projectedPos.y; - sp28.z = this->actor.projectedPos.z; - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_ROSA_SISTERS, 900.0f); + seqPos.x = this->actor.projectedPos.x; + seqPos.y = this->actor.projectedPos.y; + seqPos.z = this->actor.projectedPos.z; + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_ROSA_SISTERS, 900.0f); } } @@ -504,7 +504,7 @@ void func_80BFC36C(EnRz* this, PlayState* play) { void func_80BFC3F8(EnRz* this, PlayState* play) { s32 pad; - Vec3f bgmPos; + Vec3f seqPos; EnRz_UpdateSkelAnime(this, play); @@ -544,10 +544,10 @@ void func_80BFC3F8(EnRz* this, PlayState* play) { } if (EN_RZ_GET_SISTER(&this->actor) == EN_RZ_JUDO) { - bgmPos.x = this->actor.projectedPos.x; - bgmPos.y = this->actor.projectedPos.y; - bgmPos.z = this->actor.projectedPos.z; - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &bgmPos, NA_BGM_ROSA_SISTERS, 900.0f); + seqPos.x = this->actor.projectedPos.x; + seqPos.y = this->actor.projectedPos.y; + seqPos.z = this->actor.projectedPos.z; + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_ROSA_SISTERS, 900.0f); } } } diff --git a/src/overlays/actors/ovl_En_Zob/z_en_zob.c b/src/overlays/actors/ovl_En_Zob/z_en_zob.c index 9e6310a71..68dbd0e48 100644 --- a/src/overlays/actors/ovl_En_Zob/z_en_zob.c +++ b/src/overlays/actors/ovl_En_Zob/z_en_zob.c @@ -558,7 +558,7 @@ void func_80BA06BC(EnZob* this, PlayState* play) { void func_80BA0728(EnZob* this, PlayState* play) { s32 pad; - Vec3f sp28; + Vec3f seqPos; func_80B9F86C(this); @@ -585,10 +585,10 @@ void func_80BA0728(EnZob* this, PlayState* play) { func_800B874C(&this->actor, play, 200.0f, 150.0f); } - sp28.x = this->actor.projectedPos.x; - sp28.y = this->actor.projectedPos.y; - sp28.z = this->actor.projectedPos.z; - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_BASS_PLAY, 1000.0f); + seqPos.x = this->actor.projectedPos.x; + seqPos.y = this->actor.projectedPos.y; + seqPos.z = this->actor.projectedPos.z; + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_BASS_PLAY, 1000.0f); } void func_80BA08E8(EnZob* this, PlayState* play) { diff --git a/src/overlays/actors/ovl_En_Zod/z_en_zod.c b/src/overlays/actors/ovl_En_Zod/z_en_zod.c index ab1f940ce..f30aa51b8 100644 --- a/src/overlays/actors/ovl_En_Zod/z_en_zod.c +++ b/src/overlays/actors/ovl_En_Zod/z_en_zod.c @@ -387,7 +387,7 @@ void EnZod_PlayDrumsSequence(EnZod* this, PlayState* play) { seqPos.y = this->actor.projectedPos.y; seqPos.z = this->actor.projectedPos.z; - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_DRUMS_PLAY, 700.0f); + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_DRUMS_PLAY, 700.0f); } void func_80BAFA44(EnZod* this, PlayState* play) { diff --git a/src/overlays/actors/ovl_En_Zos/z_en_zos.c b/src/overlays/actors/ovl_En_Zos/z_en_zos.c index 8a942ce17..249b8f6bb 100644 --- a/src/overlays/actors/ovl_En_Zos/z_en_zos.c +++ b/src/overlays/actors/ovl_En_Zos/z_en_zos.c @@ -542,7 +542,7 @@ void func_80BBBD5C(EnZos* this, PlayState* play) { void func_80BBBDE0(EnZos* this, PlayState* play) { Actor* thisx = &this->actor; - Vec3f sp28; + Vec3f seqPos; if (this->unk_2B6 & 1) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200); @@ -578,10 +578,10 @@ void func_80BBBDE0(EnZos* this, PlayState* play) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_52_10); } - sp28.x = this->actor.projectedPos.x; - sp28.y = this->actor.projectedPos.y; - sp28.z = this->actor.projectedPos.z; - func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_PIANO_PLAY, 1000.0f); + seqPos.x = this->actor.projectedPos.x; + seqPos.y = this->actor.projectedPos.y; + seqPos.z = this->actor.projectedPos.z; + Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_PIANO_PLAY, 1000.0f); } void func_80BBBFBC(EnZos* this, PlayState* play) { diff --git a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c index 42c2bcc95..1bcfd0ab5 100644 --- a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c +++ b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c @@ -1,7 +1,7 @@ /* * File: z_obj_sound.c * Overlay: ovl_Obj_Sound - * Description: Plays certain sounds (e.g., swamp waterfall noise) + * Description: An invisible point-source to play sounds, including sfx and sequences. */ #include "z_obj_sound.h" @@ -13,8 +13,8 @@ void ObjSound_Init(Actor* thisx, PlayState* play); void ObjSound_Destroy(Actor* thisx, PlayState* play); void ObjSound_Update(Actor* thisx, PlayState* play); +void ObjSound_Draw(Actor* thisx, PlayState* play); -#if 0 ActorInit Obj_Sound_InitVars = { ACTOR_OBJ_SOUND, ACTORCAT_ITEMACTION, @@ -27,12 +27,50 @@ ActorInit Obj_Sound_InitVars = { (ActorFunc)NULL, }; -#endif +void ObjSound_Init(Actor* thisx, PlayState* play) { + ObjSound* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Init.s") + this->unk_144 = false; + this->soundType = OBJ_SOUND_GET_TYPE(&this->actor); + this->sfxType = OBJ_SOUND_GET_SFX_TYPE(&this->actor); + this->actor.params &= OBJ_SOUND_ID_MASK; + if (this->soundType == OBJ_SOUND_TYPE_FANFARE) { + this->actor.draw = ObjSound_Draw; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Destroy.s") +void ObjSound_Destroy(Actor* thisx, PlayState* play) { + ObjSound* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Update.s") + if (this->soundType == OBJ_SOUND_TYPE_BGM) { + Audio_PlayObjSoundBgm(NULL, NA_BGM_GENERAL_SFX); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/func_8099AA84.s") +void ObjSound_Update(Actor* thisx, PlayState* play) { + ObjSound* this = THIS; + + if (this->soundType == OBJ_SOUND_TYPE_SFX) { + if (this->sfxType != 0) { + Actor_PlaySfx_Flagged(&this->actor, gAudioEnvironmentalSfx[this->actor.params]); + } else { + Actor_PlaySfx_FlaggedCentered3(&this->actor, gAudioEnvironmentalSfx[this->actor.params]); + } + } else if (this->unk_144) { + if (this->soundType == OBJ_SOUND_TYPE_BGM) { + Audio_PlayObjSoundBgm(&this->actor.projectedPos, this->actor.params); + } else if (this->soundType == OBJ_SOUND_TYPE_FIXED_SFX) { + Audio_PlaySfx_AtFixedPos(&this->actor.projectedPos, gAudioEnvironmentalSfx[this->actor.params]); + } + } else { + this->unk_144 = true; + } +} + +void ObjSound_Draw(Actor* thisx, PlayState* play) { + ObjSound* this = THIS; + + if (CHECK_EVENTINF(EVENTINF_41) || CHECK_EVENTINF(EVENTINF_35)) { + Audio_PlayObjSoundFanfare(&this->actor.projectedPos, this->actor.params); + } +} diff --git a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h index a83aa840b..f9ec7fa8f 100644 --- a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h +++ b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h @@ -5,9 +5,22 @@ struct ObjSound; +#define OBJ_SOUND_GET_TYPE(thisx) (((thisx)->params >> 8) & 0xFF) +#define OBJ_SOUND_GET_SFX_TYPE(thisx) (((thisx)->params >> 7) & 1) +#define OBJ_SOUND_ID_MASK 0x7F + +typedef enum { + /* 0 */ OBJ_SOUND_TYPE_SFX, + /* 1 */ OBJ_SOUND_TYPE_BGM, + /* 2 */ OBJ_SOUND_TYPE_FIXED_SFX, + /* 3 */ OBJ_SOUND_TYPE_FANFARE +} ObjSoundType; + typedef struct ObjSound { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ u8 unk_144; + /* 0x145 */ u8 sfxType; + /* 0x146 */ s16 soundType; } ObjSound; // size = 0x148 #endif // Z_OBJ_SOUND_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 9ad15cf7d..a902899ea 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -3919,22 +3919,22 @@ 0x801A0C70:("Audio_ClearSariaBgm",), 0x801A0C90:("Audio_ClearSariaBgmAtPos",), 0x801A0CB0:("Audio_SplitBgmChannels",), - 0x801A0E44:("func_801A0E44",), - 0x801A1290:("func_801A1290",), - 0x801A1348:("func_801A1348",), - 0x801A13BC:("func_801A13BC",), - 0x801A153C:("func_801A153C",), - 0x801A17F4:("func_801A17F4",), - 0x801A1904:("func_801A1904",), - 0x801A1A10:("func_801A1A10",), - 0x801A1A8C:("func_801A1A8C",), - 0x801A1D44:("func_801A1D44",), - 0x801A1DB8:("func_801A1DB8",), - 0x801A1E0C:("func_801A1E0C",), - 0x801A1F00:("func_801A1F00",), - 0x801A1F88:("func_801A1F88",), - 0x801A1FB4:("func_801A1FB4",), - 0x801A2090:("func_801A2090",), + 0x801A0E44:("Audio_SetSequenceProperties",), + 0x801A1290:("Audio_UpdateObjSoundProperties",), + 0x801A1348:("Audio_SetObjSoundProperties",), + 0x801A13BC:("Audio_StartObjSoundFanfare",), + 0x801A153C:("Audio_PlayObjSoundBgm",), + 0x801A17F4:("Audio_PlayObjSoundFanfare",), + 0x801A1904:("Audio_UpdateObjSoundFanfare",), + 0x801A1A10:("Audio_StopSequenceAtPos",), + 0x801A1A8C:("Audio_StartSubBgmAtPos",), + 0x801A1D44:("Audio_PlaySubBgmAtPos",), + 0x801A1DB8:("Audio_PlaySubBgmAtPosWithFilter",), + 0x801A1E0C:("Audio_UpdateSubBgmAtPos",), + 0x801A1F00:("Audio_PlaySequenceAtDefaultPos",), + 0x801A1F88:("Audio_StopSequenceAtDefaultPos",), + 0x801A1FB4:("Audio_PlaySequenceAtPos",), + 0x801A2090:("Audio_UpdateSequenceAtPos",), 0x801A21FC:("Audio_PlaySariaBgm",), 0x801A2460:("Audio_ClearSariaBgm2",), 0x801A246C:("func_801A246C",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 7fd394acc..ad17bf28b 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -4181,7 +4181,7 @@ 0x801FD3AB:("sFanfareState","UNK_TYPE1","",0x1), 0x801FD3AC:("sFanfareSeqId","UNK_TYPE1","",0x1), 0x801FD3AE:("sMuteOnlySfxAndAmbienceSeq","UNK_TYPE1","",0x1), - 0x801FD3AF:("sAllPlayersMutedExceptOcaAndSys","UNK_TYPE1","",0x1), + 0x801FD3AF:("sAllPlayersMutedExceptSystemAndOcarina","UNK_TYPE1","",0x1), 0x801FD3B0:("sAudioPauseState","UNK_TYPE1","",0x1), 0x801FD3B4:("sSpatialSeqIsActive","u8","[4]",0x4), 0x801FD3B8:("sSequenceFilter","UNK_TYPE1","",0x1), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 240f6a0b1..54ec93503 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -3436,22 +3436,22 @@ asm/non_matchings/code/code_8019AF00/func_801A09D4.s,func_801A09D4,0x801A09D4,0x asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm.s,Audio_ClearSariaBgm,0x801A0C70,0x8 asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgmAtPos.s,Audio_ClearSariaBgmAtPos,0x801A0C90,0x8 asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s,Audio_SplitBgmChannels,0x801A0CB0,0x65 -asm/non_matchings/code/code_8019AF00/func_801A0E44.s,func_801A0E44,0x801A0E44,0x113 -asm/non_matchings/code/code_8019AF00/func_801A1290.s,func_801A1290,0x801A1290,0x2E -asm/non_matchings/code/code_8019AF00/func_801A1348.s,func_801A1348,0x801A1348,0x1D -asm/non_matchings/code/code_8019AF00/func_801A13BC.s,func_801A13BC,0x801A13BC,0x60 -asm/non_matchings/code/code_8019AF00/func_801A153C.s,func_801A153C,0x801A153C,0xAE -asm/non_matchings/code/code_8019AF00/func_801A17F4.s,func_801A17F4,0x801A17F4,0x44 -asm/non_matchings/code/code_8019AF00/func_801A1904.s,func_801A1904,0x801A1904,0x43 -asm/non_matchings/code/code_8019AF00/func_801A1A10.s,func_801A1A10,0x801A1A10,0x1F -asm/non_matchings/code/code_8019AF00/func_801A1A8C.s,func_801A1A8C,0x801A1A8C,0xAE -asm/non_matchings/code/code_8019AF00/func_801A1D44.s,func_801A1D44,0x801A1D44,0x1D -asm/non_matchings/code/code_8019AF00/func_801A1DB8.s,func_801A1DB8,0x801A1DB8,0x15 -asm/non_matchings/code/code_8019AF00/func_801A1E0C.s,func_801A1E0C,0x801A1E0C,0x3D -asm/non_matchings/code/code_8019AF00/func_801A1F00.s,func_801A1F00,0x801A1F00,0x22 -asm/non_matchings/code/code_8019AF00/func_801A1F88.s,func_801A1F88,0x801A1F88,0xB -asm/non_matchings/code/code_8019AF00/func_801A1FB4.s,func_801A1FB4,0x801A1FB4,0x37 -asm/non_matchings/code/code_8019AF00/func_801A2090.s,func_801A2090,0x801A2090,0x5B +asm/non_matchings/code/code_8019AF00/Audio_SetSequenceProperties.s,Audio_SetSequenceProperties,0x801A0E44,0x113 +asm/non_matchings/code/code_8019AF00/Audio_UpdateObjSoundProperties.s,Audio_UpdateObjSoundProperties,0x801A1290,0x2E +asm/non_matchings/code/code_8019AF00/Audio_SetObjSoundProperties.s,Audio_SetObjSoundProperties,0x801A1348,0x1D +asm/non_matchings/code/code_8019AF00/Audio_StartObjSoundFanfare.s,Audio_StartObjSoundFanfare,0x801A13BC,0x60 +asm/non_matchings/code/code_8019AF00/Audio_PlayObjSoundBgm.s,Audio_PlayObjSoundBgm,0x801A153C,0xAE +asm/non_matchings/code/code_8019AF00/Audio_PlayObjSoundFanfare.s,Audio_PlayObjSoundFanfare,0x801A17F4,0x44 +asm/non_matchings/code/code_8019AF00/Audio_UpdateObjSoundFanfare.s,Audio_UpdateObjSoundFanfare,0x801A1904,0x43 +asm/non_matchings/code/code_8019AF00/Audio_StopSequenceAtPos.s,Audio_StopSequenceAtPos,0x801A1A10,0x1F +asm/non_matchings/code/code_8019AF00/Audio_StartSubBgmAtPos.s,Audio_StartSubBgmAtPos,0x801A1A8C,0xAE +asm/non_matchings/code/code_8019AF00/Audio_PlaySubBgmAtPos.s,Audio_PlaySubBgmAtPos,0x801A1D44,0x1D +asm/non_matchings/code/code_8019AF00/Audio_PlaySubBgmAtPosWithFilter.s,Audio_PlaySubBgmAtPosWithFilter,0x801A1DB8,0x15 +asm/non_matchings/code/code_8019AF00/Audio_UpdateSubBgmAtPos.s,Audio_UpdateSubBgmAtPos,0x801A1E0C,0x3D +asm/non_matchings/code/code_8019AF00/Audio_PlaySequenceAtDefaultPos.s,Audio_PlaySequenceAtDefaultPos,0x801A1F00,0x22 +asm/non_matchings/code/code_8019AF00/Audio_StopSequenceAtDefaultPos.s,Audio_StopSequenceAtDefaultPos,0x801A1F88,0xB +asm/non_matchings/code/code_8019AF00/Audio_PlaySequenceAtPos.s,Audio_PlaySequenceAtPos,0x801A1FB4,0x37 +asm/non_matchings/code/code_8019AF00/Audio_UpdateSequenceAtPos.s,Audio_UpdateSequenceAtPos,0x801A2090,0x5B asm/non_matchings/code/code_8019AF00/Audio_PlaySariaBgm.s,Audio_PlaySariaBgm,0x801A21FC,0x99 asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm2.s,Audio_ClearSariaBgm2,0x801A2460,0x3 asm/non_matchings/code/code_8019AF00/func_801A246C.s,func_801A246C,0x801A246C,0x36 From a1bdc6c3824233551a436e479637bf2bc9030e3e Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Sat, 14 Oct 2023 23:39:47 -0700 Subject: [PATCH 6/9] EnJso (Garo) OK and documented (#1440) * EnJso (Garo) OK and documented * Respond to review * Replace some weird ifs with early returns * Respond to Anghelo's review --- spec | 3 +- .../actors/ovl_En_Hint_Skb/z_en_hint_skb.c | 5 +- src/overlays/actors/ovl_En_Jso/z_en_jso.c | 1744 ++++++++++++++++- src/overlays/actors/ovl_En_Jso/z_en_jso.h | 95 +- src/overlays/actors/ovl_En_Part/z_en_part.h | 2 + .../actors/ovl_En_Rail_Skb/z_en_rail_skb.c | 7 +- src/overlays/actors/ovl_En_Sb/z_en_sb.c | 7 +- src/overlays/actors/ovl_En_Skb/z_en_skb.c | 9 +- tools/disasm/functions.txt | 76 +- tools/disasm/variables.txt | 30 +- undefined_syms.txt | 5 - 11 files changed, 1803 insertions(+), 180 deletions(-) diff --git a/spec b/spec index 6cd76563c..a375a6692 100644 --- a/spec +++ b/spec @@ -2162,8 +2162,7 @@ beginseg name "ovl_En_Jso" compress include "build/src/overlays/actors/ovl_En_Jso/z_en_jso.o" - include "build/data/ovl_En_Jso/ovl_En_Jso.data.o" - include "build/data/ovl_En_Jso/ovl_En_Jso.reloc.o" + include "build/src/overlays/actors/ovl_En_Jso/ovl_En_Jso_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c index 86cb7235d..e62be0095 100644 --- a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c +++ b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c @@ -5,6 +5,7 @@ */ #include "z_en_hint_skb.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10) @@ -903,12 +904,12 @@ void EnHintSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* Collider_UpdateSpheres(limbIndex, &this->collider); if ((limbIndex == STALCHILD_LIMB_HEAD) && (this->unk_3E8 & 1) && !(this->unk_3E8 & 2)) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); this->unk_3E8 |= 2; } else if ((this->unk_3E8 & 4) && !(this->unk_3E8 & 8) && ((limbIndex != STALCHILD_LIMB_HEAD) || !(this->unk_3E8 & 1)) && (limbIndex != STALCHILD_LIMB_LOWER_JAW)) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); } if (this->drawDmgEffTimer != 0) { diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.c b/src/overlays/actors/ovl_En_Jso/z_en_jso.c index 43a27759f..5d083246a 100644 --- a/src/overlays/actors/ovl_En_Jso/z_en_jso.c +++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.c @@ -5,6 +5,9 @@ */ #include "z_en_jso.h" +#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h" +#include "overlays/actors/ovl_En_Encount3/z_en_encount3.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10) @@ -13,60 +16,135 @@ void EnJso_Init(Actor* thisx, PlayState* play); void EnJso_Destroy(Actor* thisx, PlayState* play); void EnJso_Update(Actor* thisx, PlayState* play); +void EnJso_Draw(Actor* thisx, PlayState* play); -void func_809ADCB8(EnJso* this, PlayState* play); -void func_809AE87C(EnJso* this, PlayState* play); -void func_809AEA08(EnJso* this, PlayState* play); -void func_809AED00(EnJso* this, PlayState* play); -void func_809AEDAC(EnJso* this, PlayState* play); -void func_809AEEC0(EnJso* this, PlayState* play); -void func_809AF110(EnJso* this, PlayState* play); -void func_809AF2F8(EnJso* this, PlayState* play); -void func_809AF3C0(EnJso* this, PlayState* play); -void func_809AF440(EnJso* this, PlayState* play); -void func_809AF53C(EnJso* this, PlayState* play); -void func_809AF714(EnJso* this, PlayState* play); -void func_809AF7F4(EnJso* this, PlayState* play); -void func_809AF99C(EnJso* this, PlayState* play); -void func_809AFAF4(EnJso* this, PlayState* play); -void func_809AFC10(EnJso* this, PlayState* play); -void func_809AFE38(EnJso* this, PlayState* play); +void EnJso_SetupHandleIntroCutscene(EnJso* this); +void EnJso_HandleIntroCutscene(EnJso* this, PlayState* play); +void EnJso_Reappear(EnJso* this, PlayState* play); +void EnJso_SetupCirclePlayer(EnJso* this, PlayState* play); +void EnJso_CirclePlayer(EnJso* this, PlayState* play); +void EnJso_Guard(EnJso* this, PlayState* play); +void EnJso_SetupSpinBeforeAttack(EnJso* this); +void EnJso_SpinBeforeAttack(EnJso* this, PlayState* play); +void EnJso_SetupDashAttack(EnJso* this); +void EnJso_DashAttack(EnJso* this, PlayState* play); +void EnJso_SetupSlash(EnJso* this, PlayState* play); +void EnJso_Slash(EnJso* this, PlayState* play); +void EnJso_SetupWaitAfterSlash(EnJso* this); +void EnJso_WaitAfterSlash(EnJso* this, PlayState* play); +void EnJso_SetupKnockedBack(EnJso* this); +void EnJso_KnockedBack(EnJso* this, PlayState* play); +void EnJso_SetupCower(EnJso* this); +void EnJso_Cower(EnJso* this, PlayState* play); +void EnJso_Stunned(EnJso* this, PlayState* play); +void EnJso_Damaged(EnJso* this, PlayState* play); +void EnJso_SetupJumpBack(EnJso* this); +void EnJso_JumpBack(EnJso* this, PlayState* play); +void EnJso_Dead(EnJso* this, PlayState* play); +void EnJso_SetupFallDownAndTalk(EnJso* this, PlayState* play); +void EnJso_FallDownAndTalk(EnJso* this, PlayState* play); +void EnJso_TellHint(EnJso* this, PlayState* play); +void EnJso_BurstIntoFlames(EnJso* this, PlayState* play); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_809B0F48 = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0xF), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0xF), - /* Normal arrow */ DMG_ENTRY(1, 0xF), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0x1), - /* Goron punch */ DMG_ENTRY(1, 0xF), - /* Sword */ DMG_ENTRY(1, 0xF), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(2, 0x2), - /* Ice arrow */ DMG_ENTRY(2, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0x1), - /* Deku bubble */ DMG_ENTRY(1, 0xF), - /* Deku launch */ DMG_ENTRY(2, 0xF), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(0, 0x5), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0xF), - /* Zora punch */ DMG_ENTRY(1, 0xF), - /* Spin attack */ DMG_ENTRY(1, 0xF), - /* Sword beam */ DMG_ENTRY(0, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0xF), +typedef enum { + /* 0 */ EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE, + /* 1 */ EN_JSO_ACTION_REAPPEAR, + /* 2 */ EN_JSO_ACTION_CIRCLE_PLAYER, + /* 3 */ EN_JSO_ACTION_GUARD, + /* 4 */ EN_JSO_ACTION_SPIN_BEFORE_ATTACK, + /* 5 */ EN_JSO_ACTION_DASH_ATTACK, + /* 6 */ EN_JSO_ACTION_SLASH, + /* 7 */ EN_JSO_ACTION_WAIT_AFTER_SLASH, + /* 8 */ EN_JSO_ACTION_STUNNED, + /* 9 */ EN_JSO_ACTION_KNOCKED_BACK, + /* 10 */ EN_JSO_ACTION_COWER, + /* 11 */ EN_JSO_ACTION_DAMAGED, + /* 12 */ EN_JSO_ACTION_JUMP_BACK, + /* 13 */ EN_JSO_ACTION_DEAD, + /* 14 */ EN_JSO_ACTION_FALL_DOWN_AND_TALK, + /* 15 */ EN_JSO_ACTION_UNK_15 // Checked in EnJso_Update, but never actually used +} EnJsoAction; + +typedef enum { + /* 0 */ EN_JSO_INTRO_SPIN_UP_FROM_GROUND, + /* 1 */ EN_JSO_INTRO_JUMP_OUT_FROM_GROUND, + /* 2 */ EN_JSO_INTRO_LAND_FROM_ABOVE, + /* 3 */ EN_JSO_INTRO_SCALE_UP +} EnJsoIntroType; + +typedef enum { + // Either the cutscene started (in which case, we'll transition to the next state on the next frame) or it's done. + /* 0 */ EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED, + // Waits for the Garo to finish their intro animation and open the first textbox. + /* 1 */ EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_APPEAR, + // Waits for the player to press a button to continue on from the Garo's first textbox. + /* 2 */ EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_CONTINUE, + // Lifts the Garo's right arm such that, when they draw their sword, it's pointed at the player. Waits until the + // player has finished reading all of the Garo's dialogue before continuing. + /* 3 */ EN_JSO_INTRO_CS_STATE_RAISE_ARM_AND_DRAW_RIGHT_SWORD, + // Waits 10 frames, then the Garo draws its left sword and continues to the next state. + /* 4 */ EN_JSO_INTRO_CS_STATE_DRAW_LEFT_SWORD, + // Waits 10 frames, then the Garo jumps back and the cutscene ends. + /* 5 */ EN_JSO_INTRO_CS_STATE_ENDING +} EnJsoIntroCsState; + +typedef enum { + /* 0 */ EN_JSO_SWORD_STATE_BOTH_DRAWN, + /* 1 */ EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS, + /* 2 */ EN_JSO_SWORD_STATE_RIGHT_DRAWN, + /* 3 */ EN_JSO_SWORD_STATE_LEFT_DRAWN, + /* 5 */ EN_JSO_SWORD_STATE_NONE_DRAWN = 5 +} EnJsoSwordState; + +// Seemingly a duplicate of the isAttacking instance variable. Its purpose is unknown. +static s32 sIsAttacking = false; + +// Seemingly a duplicate of the isPlayerLockedOn instance variable. Its purpose is unknown. +static s32 sIsPlayerLockedOn = false; + +typedef enum { + /* 0x0 */ EN_JSO_DMGEFF_IMMUNE, // Deals no damage and has no special effect + /* 0x1 */ EN_JSO_DMGEFF_STUN, // Deals no damage but stuns the Garo + /* 0x2 */ EN_JSO_DMGEFF_FIRE, // Damages and sets the Garo on fire + /* 0x3 */ EN_JSO_DMGEFF_FREEZE, // Damages and surrounds the Garo with ice + /* 0x4 */ EN_JSO_DMGEFF_LIGHT_ORB, // Damages and surrounds the Garo with light orbs + /* 0x5 */ EN_JSO_DMGEFF_ELECTRIC_STUN, // Deals no damage but stuns the Garo and surrounds them with electric sparks + /* 0xF */ EN_JSO_DMGEFF_NONE = 0xF // Damages the Garo and has no special effect +} EnJsoDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Explosives */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Hookshot */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN), + /* Goron punch */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_FREEZE), + /* Light arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_LIGHT_ORB), + /* Goron spikes */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, EN_JSO_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, EN_JSO_DMGEFF_ELECTRIC_STUN), + /* Normal shield */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Light ray */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Thrown object */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Normal Roll */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Unblockable */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE), + /* Powder Keg */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE), }; ActorInit En_Jso_InitVars = { @@ -81,106 +159,1560 @@ ActorInit En_Jso_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809B0F88 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x08, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x08, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 22, 55, 0, { 0, 0, 0 } }, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_809B0FB4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x08 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, BUMP_NONE, OCELEM_NONE, }, +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x08 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -#endif +// These text IDs are the ones common to all Garos, regardless of which hint they provide. This includes their dialogue +// during their intro cutscene, as well as most of their dialogue when they are defeated. +static u16 sTextIds[] = { + 0x1396, + 0x1397, + 0x1398, + 0x1399, +}; -extern DamageTable D_809B0F48; -extern ColliderCylinderInit D_809B0F88; -extern ColliderQuadInit D_809B0FB4; +typedef enum { + /* 0 */ EN_JSO_ANIM_APPEAR, + /* 1 */ EN_JSO_ANIM_IDLE, + /* 2 */ EN_JSO_ANIM_BOUNCE, + /* 3 */ EN_JSO_ANIM_GUARD, + /* 4 */ EN_JSO_ANIM_DASH_ATTACK, + /* 5 */ EN_JSO_ANIM_SLASH_START, + /* 6 */ EN_JSO_ANIM_SLASH_LOOP, + /* 7 */ EN_JSO_ANIM_KNOCKED_BACK, + /* 8 */ EN_JSO_ANIM_COWER, + /* 9 */ EN_JSO_ANIM_DAMAGED, + /* 10 */ EN_JSO_ANIM_JUMP_BACK, + /* 11 */ EN_JSO_ANIM_FALL_DOWN, + /* 12 */ EN_JSO_ANIM_MAX +} EnJsoAnimation; -extern UNK_TYPE D_060081F4; +static AnimationHeader* sAnimations[EN_JSO_ANIM_MAX] = { + &gGaroAppearAnim, // EN_JSO_ANIM_APPEAR + &gGaroIdleAnim, // EN_JSO_ANIM_IDLE + &gGaroBounceAnim, // EN_JSO_ANIM_BOUNCE + &gGaroGuardAnim, // EN_JSO_ANIM_GUARD + &gGaroDashAttackAnim, // EN_JSO_ANIM_DASH_ATTACK + &gGaroSlashStartAnim, // EN_JSO_ANIM_SLASH_START + &gGaroSlashLoopAnim, // EN_JSO_ANIM_SLASH_LOOP + &gGaroKnockedBackAnim, // EN_JSO_ANIM_KNOCKED_BACK + &gGaroCowerAnim, // EN_JSO_ANIM_COWER + &gGaroDamagedAnim, // EN_JSO_ANIM_DAMAGED + &gGaroJumpBackAnim, // EN_JSO_ANIM_JUMP_BACK + &gGaroFallDownAnim, // EN_JSO_ANIM_FALL_DOWN +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Init.s") +static u8 sAnimationModes[EN_JSO_ANIM_MAX] = { + ANIMMODE_ONCE, // EN_JSO_ANIM_APPEAR + ANIMMODE_LOOP, // EN_JSO_ANIM_IDLE + ANIMMODE_LOOP, // EN_JSO_ANIM_BOUNCE + ANIMMODE_ONCE, // EN_JSO_ANIM_GUARD + ANIMMODE_ONCE, // EN_JSO_ANIM_DASH_ATTACK + ANIMMODE_ONCE, // EN_JSO_ANIM_SLASH_START + ANIMMODE_LOOP, // EN_JSO_ANIM_SLASH_LOOP + ANIMMODE_ONCE, // EN_JSO_ANIM_KNOCKED_BACK + ANIMMODE_LOOP, // EN_JSO_ANIM_COWER + ANIMMODE_LOOP, // EN_JSO_ANIM_DAMAGED + ANIMMODE_ONCE, // EN_JSO_ANIM_JUMP_BACK + ANIMMODE_ONCE, // EN_JSO_ANIM_FALL_DOWN +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Destroy.s") +void EnJso_Init(Actor* thisx, PlayState* play) { + EnJso* this = THIS; + EffectBlureInit1 rightSwordBlureInit; + EffectBlureInit1 leftSwordBlureInit; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADBC8.s") + this->actor.hintId = TATL_HINT_ID_GARO; + this->actor.targetMode = TARGET_MODE_5; + this->actor.colChkInfo.mass = 80; + this->actor.colChkInfo.health = 3; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.shape.shadowScale = 0.0f; + SkelAnime_InitFlex(play, &this->skelAnime, &gGaroSkel, &gGaroAppearAnim, this->jointTable, this->morphTable, + GARO_LIMB_MAX); + this->actor.focus.pos = this->actor.world.pos; + Collider_InitAndSetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInit); + Collider_InitAndSetQuad(play, &this->rightSwordCollider, &this->actor, &sQuadInit); + Collider_InitAndSetQuad(play, &this->leftSwordCollider, &this->actor, &sQuadInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADC7C.s") + rightSwordBlureInit.p1StartColor[0] = leftSwordBlureInit.p1StartColor[0] = rightSwordBlureInit.p1StartColor[1] = + leftSwordBlureInit.p1StartColor[1] = rightSwordBlureInit.p1StartColor[2] = leftSwordBlureInit.p1StartColor[2] = + rightSwordBlureInit.p1StartColor[3] = leftSwordBlureInit.p1StartColor[3] = + rightSwordBlureInit.p2StartColor[0] = leftSwordBlureInit.p2StartColor[0] = + rightSwordBlureInit.p2StartColor[1] = leftSwordBlureInit.p2StartColor[1] = + rightSwordBlureInit.p2StartColor[2] = leftSwordBlureInit.p2StartColor[2] = + rightSwordBlureInit.p1EndColor[0] = leftSwordBlureInit.p1EndColor[0] = + rightSwordBlureInit.p1EndColor[1] = leftSwordBlureInit.p1EndColor[1] = + rightSwordBlureInit.p1EndColor[2] = leftSwordBlureInit.p1EndColor[2] = + rightSwordBlureInit.p2EndColor[0] = leftSwordBlureInit.p2EndColor[0] = + rightSwordBlureInit.p2EndColor[1] = leftSwordBlureInit.p2EndColor[1] = + rightSwordBlureInit.p2EndColor[2] = leftSwordBlureInit.p2EndColor[2] = + 255; + leftSwordBlureInit.p2StartColor[3] = rightSwordBlureInit.p2StartColor[3] = 64; + rightSwordBlureInit.p1EndColor[3] = leftSwordBlureInit.p1EndColor[3] = rightSwordBlureInit.p2EndColor[3] = + leftSwordBlureInit.p2EndColor[3] = 0; + rightSwordBlureInit.elemDuration = leftSwordBlureInit.elemDuration = 8; + rightSwordBlureInit.unkFlag = leftSwordBlureInit.unkFlag = 0; + rightSwordBlureInit.calcMode = leftSwordBlureInit.calcMode = 2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADCB8.s") + Effect_Add(play, &this->rightSwordBlureIndex, EFFECT_BLURE1, 0, 0, &rightSwordBlureInit); + Effect_Add(play, &this->leftSwordBlureIndex, EFFECT_BLURE1, 0, 0, &leftSwordBlureInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE754.s") + this->actor.gravity = -3.0f; + this->scale = 0.035f; + this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; + this->hintType = EN_JSO_GET_HINT_TYPE(&this->actor); + this->introCsType = this->hintType & EN_JSO_INTRO_SCALE_UP; + EnJso_SetupHandleIntroCutscene(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE87C.s") +void EnJso_Destroy(Actor* thisx, PlayState* play) { + EnJso* this = THIS; + EnEncount3* parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE9B0.s") + Collider_DestroyCylinder(play, &this->bodyCollider); + Collider_DestroyQuad(play, &this->rightSwordCollider); + Collider_DestroyQuad(play, &this->leftSwordCollider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEA08.s") + if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) { + parent = (EnEncount3*)this->actor.parent; + if (parent->actor.update != NULL) { + parent->child = NULL; + if (parent->unk14E > 0) { + parent->unk14E--; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AECA8.s") + Effect_Destroy(play, this->rightSwordBlureIndex); + Effect_Destroy(play, this->leftSwordBlureIndex); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AED00.s") +void EnJso_ChangeAnim(EnJso* this, s32 animIndex) { + f32 morphFrames = -4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AED54.s") + this->animEndFrame = Animation_GetLastFrame(sAnimations[animIndex]); + if ((animIndex == EN_JSO_ANIM_GUARD) || (animIndex == EN_JSO_ANIM_DAMAGED)) { + morphFrames = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEDAC.s") + Animation_Change(&this->skelAnime, sAnimations[animIndex], 1.0f, 0.0f, this->animEndFrame, + sAnimationModes[animIndex], morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEE44.s") +void EnJso_SetupHandleIntroCutscene(EnJso* this) { + EnEncount3* parent = (EnEncount3*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEEC0.s") + this->csId = parent->csId; + this->swordState = EN_JSO_SWORD_STATE_NONE_DRAWN; + this->action = EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE; + this->actor.flags |= ACTOR_FLAG_100000; + this->actionFunc = EnJso_HandleIntroCutscene; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF064.s") +/** + * Responsible for handling all aspects of the intro cutscene, including manipulating the sub-camera, making the Garo + * appear in one of four different ways, activating the ring of fire, etc. When the cutscene is over, the Garo will + * jump back to start the fight. + */ +void EnJso_HandleIntroCutscene(EnJso* this, PlayState* play) { + Player* player = GET_PLAYER(play); + f32 curFrame = this->skelAnime.curFrame; + s16 showTextbox; + s16 diffToTargetRobeRightRot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF110.s") + switch (this->introCsState) { + case EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED: + if (!CutsceneManager_IsNext(this->csId)) { + CutsceneManager_Queue(this->csId); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF28C.s") + CutsceneManager_StartWithPlayerCs(this->csId, &this->actor); + func_800B7298(play, &this->actor, PLAYER_CSMODE_21); + this->subCamId = CutsceneManager_GetCurrentSubCamId(this->actor.csId); + player->actor.world.pos.x = this->actor.home.pos.x + 30.0f; + player->actor.world.pos.z = this->actor.home.pos.z + 30.0f; + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + this->subCamEyeNext.x = player->actor.world.pos.x; + this->subCamEyeNext.y = player->actor.world.pos.y; + this->subCamEyeNext.z = player->actor.world.pos.z; + this->subCamAtNext.x = player->actor.world.pos.x; + this->subCamAtNext.y = player->actor.world.pos.y; + this->subCamAtNext.z = player->actor.world.pos.z; + player->actor.shape.rot.y = player->actor.world.rot.y = + Math_Vec3f_Yaw(&player->actor.world.pos, &this->actor.world.pos); + Math_Vec3f_Copy(&this->subCamEye, &this->subCamEyeNext); + Math_Vec3f_Copy(&this->subCamAt, &this->subCamAtNext); + EnJso_ChangeAnim(this, EN_JSO_ANIM_IDLE); + this->actor.draw = EnJso_Draw; + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY); + this->actor.shape.yOffset = 970.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF2F8.s") + switch (this->introCsType) { + case EN_JSO_INTRO_SPIN_UP_FROM_GROUND: + this->actor.shape.yOffset = -300.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF368.s") + case EN_JSO_INTRO_JUMP_OUT_FROM_GROUND: + EnJso_ChangeAnim(this, EN_JSO_ANIM_APPEAR); + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, + 1, 8.0f, 500, 10, true); + this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF3C0.s") + case EN_JSO_INTRO_LAND_FROM_ABOVE: + this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.pos.y = this->actor.home.pos.y + 200.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF3FC.s") + case EN_JSO_INTRO_SCALE_UP: + this->scale = 0.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF440.s") + default: + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF470.s") + this->introCsTimer = 0; + this->introCsState++; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF53C.s") + case EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_APPEAR: + player->actor.world.pos.x = this->actor.home.pos.x + 30.0f; + player->actor.world.pos.z = this->actor.home.pos.z + 90.0f; + this->subCamEyeNext.x = player->actor.world.pos.x - 170.0f; + this->subCamEyeNext.y = player->actor.world.pos.y + 30.0f; + this->subCamEyeNext.z = player->actor.world.pos.z - 80.0f; + this->subCamAtNext.x = player->actor.world.pos.x + 200.0f; + this->subCamAtNext.y = player->actor.world.pos.y + 10.0f; + this->subCamAtNext.z = player->actor.world.pos.z; + Math_ApproachF(&this->actor.shape.shadowScale, 16.0f, 0.4f, 4.0f); + showTextbox = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF5F8.s") + switch (this->introCsType) { + case EN_JSO_INTRO_SPIN_UP_FROM_GROUND: + Math_ApproachF(&this->actor.shape.yOffset, 970.0f, 0.5f, 100.0f); + this->actor.shape.rot.y += 0x1770; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF714.s") + if (this->actor.shape.yOffset >= 969.0f) { + showTextbox = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF76C.s") + if ((play->gameplayFrames % 4) == 0) { + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF7F4.s") + case EN_JSO_INTRO_JUMP_OUT_FROM_GROUND: + if (curFrame >= this->animEndFrame) { + showTextbox = true; + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF8D0.s") + case EN_JSO_INTRO_LAND_FROM_ABOVE: + if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + showTextbox = true; + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF99C.s") + case EN_JSO_INTRO_SCALE_UP: + Math_ApproachF(&this->scale, 0.035f, 0.2f, 0.03f); + if (this->scale >= 0.034f) { + this->scale = 0.035f; + showTextbox = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFA58.s") + default: + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFAF4.s") + if (showTextbox) { + func_800B7298(play, &this->actor, PLAYER_CSMODE_4); + Message_StartTextbox(play, sTextIds[this->textIndex], &this->actor); + this->textIndex++; + this->actor.shape.yOffset = 970.0f; + this->introCsTimer = 0; + this->introCsState++; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFC10.s") + case EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_CONTINUE: + this->subCamEyeNext.x = player->actor.world.pos.x - 30.0f; + this->subCamEyeNext.y = player->actor.world.pos.y + 30.0f; + this->subCamEyeNext.z = player->actor.world.pos.z + 70.0f; + this->subCamAtNext.x = player->actor.world.pos.x - 20.0f; + this->subCamAtNext.y = player->actor.world.pos.y + 20.0f; + this->subCamAtNext.z = player->actor.world.pos.z; + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFE38.s") + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + Message_CloseTextbox(play); + Message_ContinueTextbox(play, sTextIds[this->textIndex]); + this->introCsTimer = 0; + this->textIndex++; + this->introCsState++; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0034.s") + case EN_JSO_INTRO_CS_STATE_RAISE_ARM_AND_DRAW_RIGHT_SWORD: + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Update.s") + if (Message_GetState(&play->msgCtx) == TEXT_STATE_10) { + this->targetRobeRightRot.x = -0x2710; + this->targetRobeRightRot.z = -0x2710; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0734.s") + diffToTargetRobeRightRot = this->targetRobeRightRot.x - this->robeRightRot.x; + diffToTargetRobeRightRot = ABS_ALT(diffToTargetRobeRightRot); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0820.s") + if (this->targetRobeRightRot.x != 0) { + if ((ABS_ALT(diffToTargetRobeRightRot) < 0x64) && (this->swordState == EN_JSO_SWORD_STATE_NONE_DRAWN)) { + this->swordState = EN_JSO_SWORD_STATE_RIGHT_DRAWN; + this->targetRightArmRot.x = -0x32C8; + this->targetRightArmRot.y = -0xBB8; + this->rightArmRot.z = this->targetRightArmRot.z = -0x32C8; + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0B70.s") + this->subCamEyeNext.x = player->actor.world.pos.x + 100.0f; + this->subCamEyeNext.y = player->actor.world.pos.y + 60.0f; + this->subCamEyeNext.z = player->actor.world.pos.z - 30.0f; + this->subCamAtNext.x = player->actor.world.pos.x - 35.0f; + this->subCamAtNext.y = player->actor.world.pos.y + 30.0f; + this->subCamAtNext.z = player->actor.world.pos.z - 40.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0BB0.s") + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + Message_CloseTextbox(play); + this->targetRightArmRot.x = this->targetRightArmRot.y = this->targetRightArmRot.z = + this->targetRobeRightRot.x = this->targetRobeRightRot.y = this->targetRobeRightRot.z = 0; + this->introCsTimer = 0; + this->introCsState++; + } + break; + + case EN_JSO_INTRO_CS_STATE_DRAW_LEFT_SWORD: + this->subCamEyeNext.x = player->actor.world.pos.x - 40.0f; + this->subCamEyeNext.y = player->actor.world.pos.y + 20.0f; + this->subCamEyeNext.z = player->actor.world.pos.z; + this->subCamAtNext.x = player->actor.world.pos.x - 30.0f; + this->subCamAtNext.y = player->actor.world.pos.y + 40.0f; + this->subCamAtNext.z = player->actor.world.pos.z - 130.0f; + this->introCsTimer++; + + if (this->introCsTimer >= 10) { + this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN; + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD); + if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) { + EnEncount3* parent = (EnEncount3*)this->actor.parent; + + if (parent->actor.update != NULL) { + parent->unk148 = 1; + play->unk_18880 = 1; + } + } + + EnJso_ChangeAnim(this, EN_JSO_ANIM_IDLE); + this->introCsTimer = 0; + this->introCsState++; + } + break; + + case EN_JSO_INTRO_CS_STATE_ENDING: + this->subCamEyeNext.x = player->actor.world.pos.x - 40.0f; + this->subCamEyeNext.y = player->actor.world.pos.y + 20.0f; + this->subCamEyeNext.z = player->actor.world.pos.z; + this->subCamAtNext.x = player->actor.world.pos.x - 30.0f; + this->subCamAtNext.y = player->actor.world.pos.y + 40.0f; + this->subCamAtNext.z = player->actor.world.pos.z - 130.0f; + this->introCsTimer++; + + if (this->introCsTimer >= 10) { + func_800B7298(play, &this->actor, PLAYER_CSMODE_END); + CutsceneManager_Stop(this->csId); + this->rightArmRot.x = this->rightArmRot.y = this->rightArmRot.z = this->robeRightRot.x = + this->robeRightRot.y = this->robeRightRot.z = 0; + this->introCsState = EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED; + this->subCamId = SUB_CAM_ID_DONE; + this->actor.flags &= ~ACTOR_FLAG_100000; + this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON; + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + EnJso_SetupJumpBack(this); + } + break; + } + + Math_SmoothStepToS(&this->rightArmRot.x, this->targetRightArmRot.x, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->rightArmRot.y, this->targetRightArmRot.y, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->rightArmRot.z, this->targetRightArmRot.z, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->robeRightRot.x, this->targetRobeRightRot.x, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->robeRightRot.y, this->targetRobeRightRot.y, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->robeRightRot.z, this->targetRobeRightRot.z, 1, 0xBB8, 0); + Math_Vec3f_Copy(&this->subCamEye, &this->subCamEyeNext); + Math_Vec3f_Copy(&this->subCamAt, &this->subCamAtNext); + + if (this->subCamId != SUB_CAM_ID_DONE) { + this->subCamUp.x = 0.0f; + this->subCamUp.y = 1.0f; + this->subCamUp.z = 0.0f; + Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp); + } +} + +void EnJso_SetupReappear(EnJso* this, PlayState* play) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_APPEAR); + this->actor.speed = 0.0f; + this->actor.velocity.y = 0.0f; + + if (this->isPlayerLockedOn) { + this->isPlayerLockedOn = false; + sIsPlayerLockedOn = false; + } + + if (this->isAttacking) { + this->isAttacking = false; + sIsAttacking = false; + } + + if (this->swordState != EN_JSO_SWORD_STATE_BOTH_DRAWN) { + this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN; + } + + this->actor.shape.rot.x = this->actor.world.rot.x = 0; + this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.floorHeight = this->actor.home.pos.y; + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, 500, + 10, true); + this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY); + this->afterimageCount = 0; + this->action = EN_JSO_ACTION_REAPPEAR; + this->actor.gravity = 0.0f; + this->actionFunc = EnJso_Reappear; +} + +/** + * This function makes the Garo jump out of the ground from its home position. It's intended to be used if the Garo gets + * too far away from the player (for example, if the Garo's dash attack makes it fall off a ledge); this will ensure the + * Garo is back inside the ring of fire, so the player can interact with them again. + */ +void EnJso_Reappear(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->actor.colChkInfo.health <= 0) { + Player* player = GET_PLAYER(play); + + player->actor.freezeTimer = 3; + } + + Math_ApproachF(&this->actor.shape.shadowScale, 16.0f, 0.4f, 4.0f); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xBB8, 0x14); + + if ((play->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, + 500, 10, true); + } + + if (curFrame >= this->animEndFrame) { + this->actor.gravity = -3.0f; + if (this->actor.colChkInfo.health > 0) { + this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON; + EnJso_SetupCirclePlayer(this, play); + } else { + EnJso_SetupFallDownAndTalk(this, play); + } + } +} + +void EnJso_SetupCirclePlayer(EnJso* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + EnJso_ChangeAnim(this, EN_JSO_ANIM_BOUNCE); + this->circlingAngularVelocity = 0x258; + this->action = EN_JSO_ACTION_CIRCLE_PLAYER; + this->circlingAngle = player->actor.shape.rot.y; + this->actionFunc = EnJso_CirclePlayer; +} + +/** + * Makes the Garo bounce in a circle around the player, sometimes randomly switching the direction it's traveling, until + * the attack wait timer reaches 0. Once it does, then the Garo will prepare to attack. + */ +void EnJso_CirclePlayer(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + Player* player = GET_PLAYER(play); + Vec3f targetPos; + s32 pad; + + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_MOVING - SFX_FLAG); + if ((this->action != EN_JSO_ACTION_REAPPEAR) && (this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) && + (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) > 60.0f)) { + EnJso_SetupReappear(this, play); + return; + } + + if (curFrame < this->animEndFrame) { + SkelAnime_Update(&this->skelAnime); + } else if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + SkelAnime_Update(&this->skelAnime); + } + + if (Animation_OnFrame(&this->skelAnime, 6.0f)) { + this->actor.velocity.y = 10.0f; + if ((play->gameplayFrames % 2) == 0) { + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_CRYING); + } + } + + if (Animation_OnFrame(&this->skelAnime, 12.0f)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SKIP); + this->actor.speed = 0.0f; + if (Rand_ZeroFloat(1.0f) < 0.5f) { + this->circlingAngularVelocity = -this->circlingAngularVelocity; + } + } + + //! @note: Since sIsPlayerLockedOn always mirrors the value of this->isPlayerLockedOn, the last part of this + //! if-statement is always true and has no impact on the logic. In other words, the Garo doesn't care whether or not + //! the player is locked on; it will attack regardless as long as the other conditions are met. + if ((this->attackWaitTimer == 0) && !sIsAttacking && (!sIsPlayerLockedOn || this->isPlayerLockedOn)) { + sIsAttacking = true; + this->isAttacking = true; + this->action = EN_JSO_ACTION_SPIN_BEFORE_ATTACK; + this->actor.speed = 0.0f; + EnJso_SetupSpinBeforeAttack(this); + return; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xFA0, 0x14); + Math_ApproachF(&this->actor.speed, 5.0f, 0.3f, 2.0f); + this->circlingAngle += this->circlingAngularVelocity; + targetPos.x = (Math_SinS(this->circlingAngle) * 200.0f) + player->actor.world.pos.x; + targetPos.y = this->actor.world.pos.y; + targetPos.z = (Math_CosS(this->circlingAngle) * 200.0f) + player->actor.world.pos.z; + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &targetPos), 0xA, 0xFA0, 0x14); +} + +void EnJso_SetupGuard(EnJso* this) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_GUARD); + this->action = EN_JSO_ACTION_GUARD; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Actor_PlaySfx(&this->actor, NA_SE_IT_SHIELD_BOUND); + this->bodyCollider.base.acFlags |= AC_HARD; + this->actionFunc = EnJso_Guard; +} + +/** + * Plays the guard animation to completion, then goes back to circling the player. + */ +void EnJso_Guard(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + if (curFrame >= this->animEndFrame) { + this->isGuarding = false; + + if (this->isAttacking) { + this->isAttacking = false; + sIsAttacking = false; + } + + EnJso_SetupCirclePlayer(this, play); + } +} + +void EnJso_SetupSpinBeforeAttack(EnJso* this) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_DASH_ATTACK); + this->actor.world.rot.y = -this->actor.yawTowardsPlayer; + this->actor.speed = 10.0f; + this->actor.velocity.y = 20.0f; + this->actionFunc = EnJso_SpinBeforeAttack; +} + +/** + * Leaps into the air while spinning forward. Once the Garo touches the ground, it will begin a dash attack. + */ +void EnJso_SpinBeforeAttack(EnJso* this, PlayState* play) { + this->actor.world.rot.x += 0x1770; + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xFA0, 0x14); + + if (this->actor.velocity.y > 0.0f) { + return; + } + + if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + this->actor.world.rot.x = 0; + this->actor.velocity.y = 0.0f; + this->actor.speed = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + EnJso_SetupDashAttack(this); + } +} + +void EnJso_SetupDashAttack(EnJso* this) { + this->action = EN_JSO_ACTION_DASH_ATTACK; + this->dashAttackTimer = 40; + this->bodyCollider.base.colType = COLTYPE_HIT2; + this->bodyCollider.base.acFlags &= ~AC_HARD; + this->actor.speed = 15.0f; + this->actor.velocity.y = 13.0f; + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY); + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DASH_2); + this->actionFunc = EnJso_DashAttack; +} + +/** + * Dashes toward the player with its swords out. If the player shields the attack, the Garo will be knocked back and + * drop its swords. The Garo will stop dashing and perform a slash if it's close enough to the player, if the difference + * between its y-rotation and the yaw towards the player is large enough (usually indicating that it has dashed past the + * player), or if 40 frames have passed, whichever comes first. + */ +void EnJso_DashAttack(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + s16 yawDiff; + s16 absYawDiff; + Vec3f knockbackVelocity; + + if ((this->rightSwordCollider.base.atFlags & AT_BOUNCED) || (this->leftSwordCollider.base.atFlags & AT_BOUNCED)) { + this->rightSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + this->leftSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + if (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN) { + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + knockbackVelocity.x = 0.0f; + knockbackVelocity.y = 0.0f; + knockbackVelocity.z = -10.0f; + Matrix_MultVec3f(&knockbackVelocity, &this->knockbackVelocity); + this->swordState = EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS; + this->dashAttackTimer = 0; + this->disableBlure = true; + AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0); + EnJso_SetupKnockedBack(this); + return; + } + } + + if ((this->actor.velocity.y < 0.0f) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) { + this->actor.velocity.y = 13.0f; + } + + if (curFrame < this->animEndFrame) { + return; + } + + yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + absYawDiff = ABS_ALT(yawDiff); + + if ((this->dashAttackTimer == 0) || (this->actor.xzDistToPlayer < 100.0f) || (absYawDiff > 0x4300)) { + AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0); + Math_ApproachZeroF(&this->actor.speed, 0.3f, 3.0f); + EnJso_SetupSlash(this, play); + } +} + +void EnJso_SetupSlash(EnJso* this, PlayState* play) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_START); + this->action = EN_JSO_ACTION_SLASH; + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, 500, + 10, true); + Math_ApproachZeroF(&this->actor.speed, 0.3f, 3.0f); + this->swordHitSomething = false; + Actor_PlaySfx(&this->actor, NA_SE_IT_SWORD_SWING_HARD); + this->actionFunc = EnJso_Slash; +} + +/** + * Slash in place with both swords. If the player shields the attack, the Garo will be knocked back and drop its swords. + * Once the slash animation ends, this function will transition the Garo to a waiting state. + */ +void EnJso_Slash(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + Math_ApproachZeroF(&this->actor.speed, 0.5f, 5.0f); + + if ((play->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, + 500, 10, true); + } + + if ((this->rightSwordCollider.base.atFlags & AT_HIT) || (this->leftSwordCollider.base.atFlags & AT_HIT)) { + this->swordHitSomething = true; + this->rightSwordCollider.base.atFlags &= ~AT_HIT; + this->leftSwordCollider.base.atFlags &= ~AT_HIT; + } + + if ((this->rightSwordCollider.base.atFlags & AT_BOUNCED) || (this->leftSwordCollider.base.atFlags & AT_BOUNCED)) { + this->rightSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + this->leftSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + + if (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN) { + Vec3f knockbackVelocity; + + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + knockbackVelocity.x = 0.0f; + knockbackVelocity.y = 0.0f; + knockbackVelocity.z = -10.0f; + Matrix_MultVec3f(&knockbackVelocity, &this->knockbackVelocity); + this->swordState = EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS; + this->disableBlure = true; + EnJso_SetupKnockedBack(this); + return; + } + } + + if (curFrame >= this->animEndFrame) { + this->actor.speed = 0.0f; + this->disableBlure = true; + EnJso_SetupWaitAfterSlash(this); + } +} + +void EnJso_SetupWaitAfterSlash(EnJso* this) { + if (this->swordHitSomething) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_LOOP); + this->timer = 20; + } else { + EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_LOOP); + this->timer = 40; + } + + this->action = EN_JSO_ACTION_WAIT_AFTER_SLASH; + this->actionFunc = EnJso_WaitAfterSlash; +} + +/** + * Waits either 20 or 40 frames, depending on whether or not the Garo hit the player with its slash attack. Once this + * waiting period ends, the Garo starts circling the player again. + */ +void EnJso_WaitAfterSlash(EnJso* this, PlayState* play) { + if (this->timer == 0) { + this->attackWaitTimer = Rand_S16Offset(30, 30); + this->bodyCollider.base.colType = COLTYPE_NONE; + this->bodyCollider.base.acFlags |= AC_HARD; + this->swordHitSomething = false; + sIsAttacking = false; + this->isAttacking = false; + EnJso_SetupCirclePlayer(this, play); + } +} + +void EnJso_SetupKnockedBack(EnJso* this) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_KNOCKED_BACK); + this->bodyCollider.base.acFlags &= ~AC_HARD; + this->timer = 30; + this->action = EN_JSO_ACTION_KNOCKED_BACK; + this->actor.speed = 0.0f; + this->actionFunc = EnJso_KnockedBack; +} + +/** + * Plays the knocked back animation to completion, then transitions to cowering on the ground. + */ +void EnJso_KnockedBack(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + if (curFrame >= this->animEndFrame) { + EnJso_SetupCower(this); + } +} + +void EnJso_SetupCower(EnJso* this) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_COWER); + this->action = EN_JSO_ACTION_COWER; + this->timer = 30; + this->actionFunc = EnJso_Cower; +} + +/** + * Cower on the ground for 30 frames, then jump back. + */ +void EnJso_Cower(EnJso* this, PlayState* play) { + if (this->timer == 0) { + EnJso_SetupJumpBack(this); + } +} + +/** + * Unlike most enemies, this will make the Garo play its damaged animation rather than stopping all animations. + */ +void EnJso_SetupStunned(EnJso* this) { + Vec3f knockbackVelocity; + + AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0); + EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED); + + // This assignment is immediately overriden below. + this->timer = 30; + this->actor.speed = 0.0f; + if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) && + (this->drawDmgEffAlpha == 0)) { + this->drawDmgEffAlpha = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } + + this->timer = 40; + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + Matrix_MultVecZ(-10.0f, &knockbackVelocity); + Math_Vec3f_Copy(&this->knockbackVelocity, &knockbackVelocity); + this->action = EN_JSO_ACTION_STUNNED; + this->bodyCollider.base.acFlags &= ~AC_HARD; + this->actionFunc = EnJso_Stunned; +} + +/** + * Makes the Garo play its damaged animation and stop moving until 40 frames have passed, then it jumps back. + */ +void EnJso_Stunned(EnJso* this, PlayState* play) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) { + if ((this->drawDmgEffAlpha != 0) && (this->drawDmgEffAlpha < 60)) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + } + } + + if ((this->timer == 0) && (this->drawDmgEffAlpha == 0)) { + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) { + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f); + this->drawDmgEffAlpha = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } + + EnJso_SetupJumpBack(this); + } +} + +void EnJso_SetupDamaged(EnJso* this, PlayState* play) { + Vec3f knockbackVelocity; + + AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0); + EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED); + this->swordHitSomething = false; + this->actor.velocity.y = 10.0f; + this->actor.speed = 0.0f; + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + Matrix_MultVecZ(-20.0f, &knockbackVelocity); + Math_Vec3f_Copy(&this->knockbackVelocity, &knockbackVelocity); + + if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) && + (this->drawDmgEffAlpha != 0)) { + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f); + this->drawDmgEffAlpha = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } + + Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 8); + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DAMAGE); + this->action = EN_JSO_ACTION_DAMAGED; + this->actionFunc = EnJso_Damaged; +} + +/** + * Plays the damaged animation until the Garo is touching the ground and no longer has its red color filter, at which + * point it will jump back. + */ +void EnJso_Damaged(EnJso* this, PlayState* play) { + if (this->actor.velocity.y > 0.0f) { + return; + } + + if ((this->actor.colorFilterTimer == 0) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) { + EnJso_SetupJumpBack(this); + } +} + +void EnJso_SetupJumpBack(EnJso* this) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_JUMP_BACK); + this->action = EN_JSO_ACTION_JUMP_BACK; + this->timer = 30; + this->actor.speed = 7.0f; + this->actor.velocity.y = 20.0f; + + if (this->swordState != EN_JSO_SWORD_STATE_BOTH_DRAWN) { + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD); + this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN; + } + + this->actor.world.rot.y += 0x8000; + this->actionFunc = EnJso_JumpBack; +} + +/** + * Jump backwards away from the player. After the Garo touches the ground, the jump back animation completes, and 30 + * frames have passed, the Garo will transition to circling the player. + */ +void EnJso_JumpBack(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xBB8, 0x14); + + if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + this->actor.speed = 0.0f; + } + + if ((this->timer == 0) || ((curFrame >= this->animEndFrame) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND))) { + this->actor.world.rot.x = 0; + this->actor.velocity.y = 0.0f; + this->actor.speed = 0.0f; + this->timer = 0; + sIsAttacking = false; + this->isAttacking = false; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->attackWaitTimer = Rand_S16Offset(10, 10); + EnJso_SetupCirclePlayer(this, play); + } +} + +void EnJso_SetupDead(EnJso* this, PlayState* play) { + AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0); + EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED); + + if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) && + (this->drawDmgEffAlpha == 0)) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } + + this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY); + this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; + this->actor.speed = 0.0f; + this->disableBlure = true; + this->timer = 30; + Enemy_StartFinishingBlow(play, &this->actor); + Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DEAD); + this->action = EN_JSO_ACTION_DEAD; + this->actionFunc = EnJso_Dead; +} + +/** + * Plays the damaged animation for 30 frames, then the Garo falls down and starts talking to the player. + */ +void EnJso_Dead(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) { + if (this->drawDmgEffAlpha != 0) { + Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f); + this->drawDmgEffAlpha = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else { + return; + } + } + + if ((curFrame >= this->animEndFrame) && (this->timer == 0)) { + EnJso_SetupFallDownAndTalk(this, play); + } +} + +void EnJso_SetupFallDownAndTalk(EnJso* this, PlayState* play) { + EnJso_ChangeAnim(this, EN_JSO_ANIM_FALL_DOWN); + this->textIndex = 2; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.flags |= (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY); + func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_NPC); + this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON; + this->actor.flags &= ~ACTOR_FLAG_100000; + this->action = EN_JSO_ACTION_FALL_DOWN_AND_TALK; + this->actionFunc = EnJso_FallDownAndTalk; +} + +/** + * Handles the first part of the dialogue the Garo gives when defeated. + */ +void EnJso_FallDownAndTalk(EnJso* this, PlayState* play) { + f32 curFrame = this->skelAnime.curFrame; + Player* player = GET_PLAYER(play); + + if (curFrame < this->animEndFrame) { + return; + } + + if (!Play_InCsMode(play) && (play->msgCtx.msgLength == 0)) { + if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 60.0f) { + Player* player2 = GET_PLAYER(play); + + this->actor.textId = sTextIds[this->textIndex]; + Message_StartTextbox(play, this->actor.textId, &this->actor); + player2->stateFlags1 |= PLAYER_STATE1_10000000; + player2->actor.freezeTimer = 3; + this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; + this->actionFunc = EnJso_TellHint; + } else { + EnJso_SetupReappear(this, play); + } + } +} + +/** + * Handles the second part of the dialogue the Garo gives when defeated involving its specific hint. If the player has + * the Elegy of Emptiness, then the Garo ignore its specific hint and will instead always tell them that the Elegy can + * be used to climb Stone Tower. Once the Garo has given its hint, this function will have it say one final piece of + * dialogue and prepare for it to burst into flames. + */ +void EnJso_TellHint(EnJso* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + player->actor.freezeTimer = 3; + + // Checking for Dawn of the Second Day, Night of the First Day, etc. messages + if ((play->msgCtx.currentTextId >= 0x1BB2) && (play->msgCtx.currentTextId < 0x1BB7)) { + this->actor.textId = sTextIds[this->textIndex]; + Message_StartTextbox(play, this->actor.textId, &this->actor); + return; + } + + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + Message_CloseTextbox(play); + if (this->textIndex == 2) { + u16 textId = 0x139C; // Hint about using Elegy to climb Stone Tower + + switch (this->hintType) { + case EN_JSO_HINT_FREEZE_OCTOROKS: + textId = 0x139A; // Hint about freezing the Octoroks + break; + + case EN_JSO_HINT_FLATS_LOCATION: + textId = 0x139B; // Hint about Flat being in the Graveyard + break; + + case EN_JSO_HINT_VARIABLE_1: + textId = 0x139D; // Hint about Pamela's family being in the house with the waterwheel + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) { + textId = 0x13A1; // Hint about using the Song of Healing on Pamela's father + } + break; + + case EN_JSO_HINT_VARIABLE_2: + textId = 0x139E; // Hint about Pamela leaving her house to check something + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) { + textId = 0x13A2; // Hint about the well being connected to Ikana Castle + } + break; + + case EN_JSO_HINT_VARIABLE_3: + textId = 0x139F; // Hint about restoring the river by going into Sharp's cave + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) { + textId = 0x13A3; // Hint about the Gibdos in the well wanting items + } + break; + + case EN_JSO_HINT_VARIABLE_4: + textId = 0x13A0; // Hint about needing the Song of Storms to pacify Sharp + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) { + textId = 0x13A4; // Hint about the items the Gibdos want being in the well + } + break; + + case EN_JSO_HINT_DANCING_REDEADS: + textId = 0x13A5; // Hint about the Redeads being able to dance + break; + + case EN_JSO_HINT_DESTRUCTIBLE_CEILING_IN_CASTLE: + textId = 0x13A6; // Hint about the destructible ceiling in Ikana Castle + break; + + case EN_JSO_HINT_SECOND_ENTRANCE_TO_CASTLE: + textId = 0x13A7; // Hint about the second entrance to Ikana Castle + break; + + case EN_JSO_HINT_KING_WEAK_TO_MIRROR_SHIELD: + textId = 0x13A8; // Hint about using the Mirror Shield on Igos du Ikana + break; + + default: + break; + } + + if (CHECK_QUEST_ITEM(QUEST_SONG_ELEGY)) { + textId = 0x139C; // Hint about using Elegy to climb Stone Tower + } + + Message_ContinueTextbox(play, textId); + this->textIndex++; + } else if (this->textIndex == 3) { + Message_ContinueTextbox(play, sTextIds[this->textIndex]); + this->actionFunc = EnJso_BurstIntoFlames; + } + } +} + +/** + * Once the player closes the Garo's final textbox, this function will spawn nine green flames to obscure the Garo and + * kill the actor. + */ +void EnJso_BurstIntoFlames(EnJso* this, PlayState* play) { + Vec3f firePos; + Vec3f fireVelocityAndAccel[] = { + { 1.0f, 0.0f, 0.5f }, { 1.0f, 0.0f, -0.5f }, { -1.0f, 0.0f, 0.5f }, + { -1.0f, 0.0f, -0.5f }, { 0.5f, 0.0f, 1.0f }, { -0.5f, 0.0f, 1.0f }, + { 0.5f, 0.0f, -1.0f }, { -0.5f, 0.0f, -1.0f }, { 0.0f, 0.0f, 0.0f }, + }; + Player* player = GET_PLAYER(play); + f32 scale; + f32 scaleStep; + s32 i; + + player->actor.freezeTimer = 3; + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + Player* player2 = GET_PLAYER(play); + + Message_CloseTextbox(play); + for (i = 0; i < ARRAY_COUNT(fireVelocityAndAccel); i++) { + Math_Vec3f_Copy(&firePos, &this->actor.world.pos); + firePos.x += Rand_CenteredFloat(30.0f); + firePos.y = this->actor.floorHeight; + firePos.z += Rand_CenteredFloat(30.0f); + scale = (Rand_ZeroFloat(1.0f) * 100.0f) + 100.0f; + scaleStep = 20.0f; + func_800B3030(play, &firePos, &fireVelocityAndAccel[i], &fireVelocityAndAccel[i], scale, scaleStep, 1); + } + + SoundSource_PlaySfxEachFrameAtFixedWorldPos(play, &this->actor.world.pos, 10, + NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + + sIsAttacking = false; + this->isAttacking = false; + if (this->isPlayerLockedOn) { + this->isPlayerLockedOn = false; + sIsPlayerLockedOn = false; + } + + player2->stateFlags1 &= ~PLAYER_STATE1_10000000; + Actor_Kill(&this->actor); + } +} + +void EnJso_UpdateDamage(EnJso* this, PlayState* play) { + s32 attackDealsDamage = false; + + if (this->bodyCollider.base.acFlags & AC_HIT) { + this->bodyCollider.base.acFlags &= ~AC_HIT; + if ((this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_STUN) || + (this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_ELECTRIC_STUN)) { + if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) && + (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) || + (this->drawDmgEffAlpha == 0)) { + Actor_PlaySfx(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA, 40); + if (this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_ELECTRIC_STUN) { + this->drawDmgEffAlpha = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + } + + EnJso_SetupStunned(this); + } + } else { + switch (this->action) { + case EN_JSO_ACTION_CIRCLE_PLAYER: + case EN_JSO_ACTION_GUARD: + this->actor.speed = 0.0f; + EnJso_SetupGuard(this); + attackDealsDamage = false; + break; + + case EN_JSO_ACTION_DASH_ATTACK: + case EN_JSO_ACTION_SLASH: + case EN_JSO_ACTION_WAIT_AFTER_SLASH: + case EN_JSO_ACTION_STUNNED: + case EN_JSO_ACTION_COWER: + switch (this->actor.colChkInfo.damageEffect) { + case EN_JSO_DMGEFF_NONE: + attackDealsDamage = true; + break; + + case EN_JSO_DMGEFF_FIRE: + this->drawDmgEffAlpha = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + attackDealsDamage = true; + break; + + case EN_JSO_DMGEFF_LIGHT_ORB: + if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) && + (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) || + (this->drawDmgEffAlpha == 0)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->actor.focus.pos.x, + this->actor.focus.pos.y, this->actor.focus.pos.z, 0, 0, 0, + CLEAR_TAG_PARAMS(CLEAR_TAG_LARGE_LIGHT_RAYS)); + this->drawDmgEffAlpha = 20; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + attackDealsDamage = true; + } + break; + + case EN_JSO_DMGEFF_FREEZE: + if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) && + (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) || + (this->drawDmgEffAlpha == 0)) { + attackDealsDamage = false; + Actor_ApplyDamage(&this->actor); + this->drawDmgEffAlpha = 80; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffFrozenSteamScale = 1.5f; + } + + if (this->actor.colChkInfo.health <= 0) { + EnJso_SetupDead(this, play); + attackDealsDamage = false; + } else { + EnJso_SetupStunned(this); + attackDealsDamage = false; + } + break; + + default: + break; + } + break; + + default: + break; + } + + if (attackDealsDamage) { + Actor_ApplyDamage(&this->actor); + this->bodyCollider.base.colType = COLTYPE_NONE; + this->bodyCollider.base.acFlags |= AC_HARD; + if (this->actor.colChkInfo.health > 0) { + EnJso_SetupDamaged(this, play); + } else { + EnJso_SetupDead(this, play); + } + } + } + } +} + +void EnJso_Update(Actor* thisx, PlayState* play) { + EnJso* this = THIS; + s32 pad; + + if ((this->action != EN_JSO_ACTION_CIRCLE_PLAYER) && !this->disableAnimations) { + SkelAnime_Update(&this->skelAnime); + } + + EnJso_UpdateDamage(this, play); + if (this->actor.isLockedOn) { + sIsPlayerLockedOn = true; + this->isPlayerLockedOn = true; + } else if (this->isPlayerLockedOn) { + this->isPlayerLockedOn = false; + sIsPlayerLockedOn = false; + } + + this->actionFunc(this, play); + DECR(this->dashAttackTimer); + DECR(this->attackWaitTimer); + DECR(this->timer); + DECR(this->drawDmgEffAlpha); + + if (this->action != EN_JSO_ACTION_FALL_DOWN_AND_TALK) { + Actor_SetFocus(&this->actor, 50.0f); + } else { + Actor_SetFocus(&this->actor, 30.0f); + } + + Actor_SetScale(&this->actor, this->scale); + Actor_MoveWithGravity(&this->actor); + this->actor.world.pos.x += this->knockbackVelocity.x; + this->actor.world.pos.z += this->knockbackVelocity.z; + + if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { + Math_ApproachZeroF(&this->knockbackVelocity.x, 1.0f, 2.0f); + Math_ApproachZeroF(&this->knockbackVelocity.z, 1.0f, 2.0f); + } + + if (this->action != EN_JSO_ACTION_REAPPEAR) { + Actor_UpdateBgCheckInfo(play, &this->actor, 35.0f, 40.0f, 40.0f, + UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_4 | + UPDBGCHECKINFO_FLAG_8 | UPDBGCHECKINFO_FLAG_10); + } + + if ((this->action == EN_JSO_ACTION_SPIN_BEFORE_ATTACK) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) { + this->afterimageIndex++; + if (this->afterimageIndex >= EN_JSO_AFTERIMAGE_COUNT) { + this->afterimageIndex = 0; + } + + if (this->afterimageCount < EN_JSO_AFTERIMAGE_COUNT - 1) { + this->afterimageCount++; + } + + this->afterimagePos[this->afterimageIndex] = this->actor.world.pos; + this->afterimagePos[this->afterimageIndex].y += 40.0f; + this->afterimageRot[this->afterimageIndex] = this->actor.world.rot; + + { + s32 i; + + for (i = 0; i < EN_JSO_AFTERIMAGE_COUNT; i++) { + this->afterimageJointTable[this->afterimageIndex][i] = this->jointTable[i]; + } + } + } else { + this->afterimageCount = 0; + } + + if ((this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) && (this->action != EN_JSO_ACTION_CIRCLE_PLAYER) && + (this->action != EN_JSO_ACTION_SPIN_BEFORE_ATTACK) && (this->action != EN_JSO_ACTION_DAMAGED) && + (this->action != EN_JSO_ACTION_JUMP_BACK)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + } + + this->actor.shape.rot.x = this->actor.world.rot.x; + Collider_UpdateCylinder(&this->actor, &this->bodyCollider); + + if ((this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) && (this->action != EN_JSO_ACTION_REAPPEAR) && + (this->action != EN_JSO_ACTION_DAMAGED) && (this->action != EN_JSO_ACTION_SPIN_BEFORE_ATTACK) && + (this->action != EN_JSO_ACTION_DEAD) && (this->action != EN_JSO_ACTION_FALL_DOWN_AND_TALK) && + (this->action != EN_JSO_ACTION_UNK_15)) { + CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base); + + if ((this->action == EN_JSO_ACTION_SLASH) && !this->swordHitSomething && + (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN)) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->rightSwordCollider.base); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->leftSwordCollider.base); + } + } +} + +s32 EnJso_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnJso* this = THIS; + + if (limbIndex == GARO_LIMB_RIGHT_ARM) { + rot->x += this->rightArmRot.x; + rot->y += this->rightArmRot.y; + rot->z += this->rightArmRot.z; + } + + if (limbIndex == GARO_LIMB_ROBE_RIGHT) { + rot->x += this->robeRightRot.x; + rot->y += this->robeRightRot.y; + rot->z += this->robeRightRot.z; + } + + if ((limbIndex == GARO_LIMB_LEFT_SWORD) || (limbIndex == GARO_LIMB_RIGHT_SWORD)) { + if (this->swordState == EN_JSO_SWORD_STATE_NONE_DRAWN) { + *dList = NULL; + } else if (limbIndex == GARO_LIMB_LEFT_SWORD) { + if (this->swordState == EN_JSO_SWORD_STATE_RIGHT_DRAWN) { + *dList = NULL; + } + } else if ((limbIndex == GARO_LIMB_RIGHT_SWORD) && (this->swordState == EN_JSO_SWORD_STATE_LEFT_DRAWN)) { + *dList = NULL; + } + } + + return false; +} + +void EnJso_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f sSwordTipOffset = { 1600.0f, 0.0f, 0.0f }; + static Vec3f sSwordBaseOffset = { 0.0f, 0.0f, 0.0f }; + static Vec3f sSwordTipQuadOffset = { 1700.0f, 0.0f, 0.0f }; + static Vec3f sSwordBaseQuadOffset = { 0.0f, 0.0f, 0.0f }; + EnJso* this = THIS; + Vec3f swordTipPos; + Vec3f swordBasePos; + + Matrix_Push(); + + if (limbIndex == GARO_LIMB_LEFT_SWORD) { + if (this->swordState == EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS) { + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_15), dList); + } + + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Math_Vec3f_Copy(&this->leftSwordCollider.dim.quad[3], &this->leftSwordCollider.dim.quad[1]); + Math_Vec3f_Copy(&this->leftSwordCollider.dim.quad[2], &this->leftSwordCollider.dim.quad[0]); + Matrix_MultVec3f(&sSwordTipQuadOffset, &this->leftSwordCollider.dim.quad[1]); + Matrix_MultVec3f(&sSwordBaseQuadOffset, &this->leftSwordCollider.dim.quad[0]); + Collider_SetQuadVertices(&this->leftSwordCollider, &this->leftSwordCollider.dim.quad[0], + &this->leftSwordCollider.dim.quad[1], &this->leftSwordCollider.dim.quad[2], + &this->leftSwordCollider.dim.quad[3]); + Matrix_MultVec3f(&sSwordTipOffset, &swordTipPos); + Matrix_MultVec3f(&sSwordBaseOffset, &swordBasePos); + + if (((this->action == EN_JSO_ACTION_SLASH) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) && + !this->disableBlure) { + EffectBlure_AddVertex(Effect_GetByIndex(this->leftSwordBlureIndex), &swordTipPos, &swordBasePos); + } else if (this->disableBlure == true) { + EffectBlure_AddSpace(Effect_GetByIndex(this->leftSwordBlureIndex)); + } + } + + if (limbIndex == GARO_LIMB_RIGHT_SWORD) { + if (this->swordState == EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS) { + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_15), dList); + this->swordState = EN_JSO_SWORD_STATE_NONE_DRAWN; + } + + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Math_Vec3f_Copy(&this->rightSwordCollider.dim.quad[3], &this->rightSwordCollider.dim.quad[1]); + Math_Vec3f_Copy(&this->rightSwordCollider.dim.quad[2], &this->rightSwordCollider.dim.quad[0]); + Matrix_MultVec3f(&sSwordTipQuadOffset, &this->rightSwordCollider.dim.quad[1]); + Matrix_MultVec3f(&sSwordBaseQuadOffset, &this->rightSwordCollider.dim.quad[0]); + Collider_SetQuadVertices(&this->rightSwordCollider, &this->rightSwordCollider.dim.quad[0], + &this->rightSwordCollider.dim.quad[1], &this->rightSwordCollider.dim.quad[2], + &this->rightSwordCollider.dim.quad[3]); + Matrix_MultVec3f(&sSwordTipOffset, &swordTipPos); + Matrix_MultVec3f(&sSwordBaseOffset, &swordBasePos); + + if (((this->action == EN_JSO_ACTION_SLASH) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) && + !this->disableBlure) { + EffectBlure_AddVertex(Effect_GetByIndex(this->rightSwordBlureIndex), &swordTipPos, &swordBasePos); + } else if (this->disableBlure == true) { + EffectBlure_AddSpace(Effect_GetByIndex(this->rightSwordBlureIndex)); + this->disableBlure = false; + } + } + + if ((limbIndex == GARO_LIMB_LEFT_SWORD) || (limbIndex == GARO_LIMB_RIGHT_SWORD) || + (limbIndex == GARO_LIMB_ROBE_TOP) || (limbIndex == GARO_LIMB_ROBE_BACK) || (limbIndex == GARO_LIMB_ROBE_LEFT) || + (limbIndex == GARO_LIMB_ROBE_RIGHT) || (limbIndex == GARO_LIMB_ROBE_FRONT) || (limbIndex == GARO_LIMB_HEAD) || + (limbIndex == GARO_LIMB_RIGHT_THIGH) || (limbIndex == GARO_LIMB_RIGHT_FOOT) || + (limbIndex == GARO_LIMB_LEFT_THIGH) || (limbIndex == GARO_LIMB_LEFT_FOOT)) { + Matrix_MultZero(&this->bodyPartsPos[this->bodyPartIndex]); + this->bodyPartIndex++; + if (this->bodyPartIndex >= EN_JSO_BODYPART_MAX) { + this->bodyPartIndex = 0; + } + } + + Matrix_Pop(); +} + +Gfx* EnJso_SetAfterimageRenderMode(GraphicsContext* gfxCtx) { + Gfx* gfxHead = GRAPH_ALLOC(gfxCtx, 2 * sizeof(Gfx)); + Gfx* gfx = gfxHead; + + gDPSetRenderMode( + gfx++, AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | G_RM_FOG_SHADE_A, + AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); + gSPEndDisplayList(gfx++); + + return gfxHead; +} + +void EnJso_Draw(Actor* thisx, PlayState* play) { + static s16 sAfterimageAlpha[EN_JSO_AFTERIMAGE_COUNT] = { + 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, + }; + EnJso* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0C, D_801AEFA0); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnJso_OverrideLimbDraw, EnJso_PostLimbDraw, &this->actor); + + if (this->afterimageCount > 0) { + s32 i; + s32 index = this->afterimageIndex; + + for (i = 0; i < this->afterimageCount; i++) { + if (sAfterimageAlpha[i] == 0) { + continue; + } + + Matrix_Translate(this->afterimagePos[index].x, this->afterimagePos[index].y, this->afterimagePos[index].z, + MTXMODE_NEW); + Matrix_Scale(this->scale, this->scale, this->scale, MTXMODE_APPLY); + //! @bug: These matrix rotation functions are supposed to be passed binangs, so using BINANG_TO_RAD here + //! is incorrect. Specifically, it results in rotation values far smaller than expected, since + //! BINANG_TO_RAD divides the angle by 0x8000. In-game, this bug manifests as the Garo's afterimages + //! looking the "wrong way", as they have a rotation close to (0, 0, 0) instead of matching the Garo's + //! rotation as intended. This bug can be fixed by using the correct matrix rotation functions (e.g., + //! Matrix_RotateYF instead of Matrix_RotateYS) or by removing BINANG_TO_RAD entirely. + Matrix_RotateYS(BINANG_TO_RAD(this->afterimageRot[index].y), MTXMODE_APPLY); + Matrix_RotateXS(BINANG_TO_RAD(this->afterimageRot[index].x), MTXMODE_APPLY); + Matrix_RotateZS(BINANG_TO_RAD(this->afterimageRot[index].z), MTXMODE_APPLY); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, sAfterimageAlpha[i]); + gSPSegment(POLY_XLU_DISP++, 0x0C, EnJso_SetAfterimageRenderMode(play->state.gfxCtx)); + POLY_XLU_DISP = SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->afterimageJointTable[index], + this->skelAnime.dListCount, NULL, NULL, &this->actor, POLY_XLU_DISP); + + index--; + if (index < 0) { + index = EN_JSO_AFTERIMAGE_COUNT - 1; + } + } + } + + if (this->drawDmgEffAlpha != 0) { + f32 drawDmgEffAlpha = this->drawDmgEffAlpha * 0.05f; + + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) { + this->drawDmgEffScale += 0.3f; + if (this->drawDmgEffScale > 0.5f) { + this->drawDmgEffScale = 0.5f; + } + + Math_ApproachF(&this->drawDmgEffFrozenSteamScale, this->drawDmgEffScale, 0.1f, 0.04f); + } else { + this->drawDmgEffScale = 0.8f; + this->drawDmgEffFrozenSteamScale = 0.8f; + } + + Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, drawDmgEffAlpha, this->drawDmgEffType); + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.h b/src/overlays/actors/ovl_En_Jso/z_en_jso.h index 7f5db0757..7f97e5008 100644 --- a/src/overlays/actors/ovl_En_Jso/z_en_jso.h +++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.h @@ -2,16 +2,107 @@ #define Z_EN_JSO_H #include "global.h" +#include "assets/objects/object_jso/object_jso.h" struct EnJso; +#define EN_JSO_GET_HINT_TYPE(thisx) ((thisx)->params) + +#define EN_JSO_AFTERIMAGE_COUNT 20 + typedef void (*EnJsoActionFunc)(struct EnJso*, PlayState*); +// For the four `VARIABLE` hint types, the former hint is used if the player hasn't restored the river in +// Ikana Canyon yet, and the latter hint is used if the player has. If the player has the Elegy of Emptiness, +// then all hints will be replaced with a hint telling the player to use the song to climb Stone Tower. +typedef enum { + /* 0 */ EN_JSO_HINT_FREEZE_OCTOROKS, + /* 1 */ EN_JSO_HINT_FLATS_LOCATION, + /* 2 */ EN_JSO_HINT_VARIABLE_1, // Hints that Pamela's family is in the house or that the Song of Healing can heal Pamela's father + /* 3 */ EN_JSO_HINT_VARIABLE_2, // Hints that Pamela leaves the house to check something or that the well is connected to Ikana Castle + /* 4 */ EN_JSO_HINT_VARIABLE_3, // Hints that they can restore the river by going to Sharp's cave or that the Gidbos in the well want items + /* 5 */ EN_JSO_HINT_VARIABLE_4, // Hints that they need to Song of Storms to stop Sharp or that the items the Gibdos want can be found in the well + /* 6 */ EN_JSO_HINT_DANCING_REDEADS, + /* 7 */ EN_JSO_HINT_DESTRUCTIBLE_CEILING_IN_CASTLE, + /* 8 */ EN_JSO_HINT_SECOND_ENTRANCE_TO_CASTLE, + /* 9 */ EN_JSO_HINT_KING_WEAK_TO_MIRROR_SHIELD +} EnJsoHintType; + +typedef enum { + /* 0 */ EN_JSO_BODYPART_LEFT_SWORD, + /* 1 */ EN_JSO_BODYPART_RIGHT_SWORD, + /* 2 */ EN_JSO_BODYPART_ROBE_TOP, + /* 3 */ EN_JSO_BODYPART_ROBE_BACK, + /* 4 */ EN_JSO_BODYPART_ROBE_LEFT, + /* 5 */ EN_JSO_BODYPART_ROBE_RIGHT, + /* 6 */ EN_JSO_BODYPART_ROBE_FRONT, + /* 7 */ EN_JSO_BODYPART_HEAD, + /* 8 */ EN_JSO_BODYPART_RIGHT_THIGH, + /* 9 */ EN_JSO_BODYPART_RIGHT_FOOT, + /* 10 */ EN_JSO_BODYPART_LEFT_THIGH, + /* 11 */ EN_JSO_BODYPART_LEFT_FOOT, + /* 12 */ EN_JSO_BODYPART_MAX +} EnJsoBodyPart; + + typedef struct EnJso { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x134]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[GARO_LIMB_MAX]; + /* 0x200 */ Vec3s morphTable[GARO_LIMB_MAX]; /* 0x278 */ EnJsoActionFunc actionFunc; - /* 0x27C */ char unk_27C[0xD70]; + /* 0x27C */ s16 action; + /* 0x27E */ s16 circlingAngle; + /* 0x280 */ s16 circlingAngularVelocity; + /* 0x282 */ s16 dashAttackTimer; + /* 0x284 */ UNK_TYPE1 unk_284[0x2]; + /* 0x286 */ s16 attackWaitTimer; // while bouncing, the Garo cannot start an attack until this reaches 0 + /* 0x288 */ s16 timer; + /* 0x28A */ s16 isGuarding; // Set to false when the guard animation ends, never checked or set otherwise. Name is inferred based on how it's being set. + /* 0x28C */ s16 isPlayerLockedOn; + /* 0x28E */ s16 isAttacking; + /* 0x290 */ Vec3s robeRightRot; + /* 0x296 */ Vec3s targetRobeRightRot; + /* 0x29C */ Vec3s rightArmRot; + /* 0x2A2 */ Vec3s targetRightArmRot; + /* 0x2A8 */ s16 drawDmgEffAlpha; + /* 0x2AA */ s16 drawDmgEffType; + /* 0x2AC */ f32 drawDmgEffScale; + /* 0x2B0 */ f32 drawDmgEffFrozenSteamScale; + /* 0x2B4 */ Vec3f bodyPartsPos[EN_JSO_BODYPART_MAX]; + /* 0x344 */ s16 bodyPartIndex; + /* 0x346 */ s16 disableAnimations; // Checked but never set, so it's implicitly always false. Name is inferred based on how it's being checked. + /* 0x348 */ s16 textIndex; + /* 0x34A */ s16 hintType; + /* 0x34C */ u8 disableBlure; + /* 0x34D */ u8 swordState; + /* 0x34E */ u8 swordHitSomething; + /* 0x350 */ f32 animEndFrame; + /* 0x354 */ f32 scale; + /* 0x358 */ UNK_TYPE1 unk_358[0x4]; + /* 0x35C */ ColliderCylinder bodyCollider; + /* 0x3A8 */ ColliderQuad rightSwordCollider; + /* 0x428 */ ColliderQuad leftSwordCollider; + /* 0x4A8 */ s32 rightSwordBlureIndex; + /* 0x4AC */ s32 leftSwordBlureIndex; + /* 0x4B0 */ s16 afterimageIndex; + /* 0x4B4 */ s32 afterimageCount; + /* 0x4B8 */ s16 csId; + /* 0x4BC */ u32 introCsTimer; + /* 0x4C0 */ s16 introCsState; + /* 0x4C2 */ s16 subCamId; + /* 0x4C4 */ UNK_TYPE1 unk_4C4[0x4]; + /* 0x4C8 */ Vec3f subCamEye; + /* 0x4D4 */ Vec3f subCamAt; + /* 0x4E0 */ Vec3f subCamUp; + /* 0x4EC */ Vec3f subCamEyeNext; + /* 0x4F8 */ Vec3f subCamAtNext; + /* 0x504 */ UNK_TYPE1 unk_504[0x10]; + /* 0x514 */ s16 introCsType; + /* 0x518 */ Vec3f afterimagePos[EN_JSO_AFTERIMAGE_COUNT]; + /* 0x608 */ Vec3s afterimageRot[EN_JSO_AFTERIMAGE_COUNT]; + /* 0x680 */ Vec3s afterimageJointTable[EN_JSO_AFTERIMAGE_COUNT][GARO_LIMB_MAX]; + /* 0xFE0 */ Vec3f knockbackVelocity; // Adds a little push backwards when the Garo is bounced off the player's shield, damaged, or stunned } EnJso; // size = 0xFEC #endif // Z_EN_JSO_H diff --git a/src/overlays/actors/ovl_En_Part/z_en_part.h b/src/overlays/actors/ovl_En_Part/z_en_part.h index 5bd4de503..4a766276d 100644 --- a/src/overlays/actors/ovl_En_Part/z_en_part.h +++ b/src/overlays/actors/ovl_En_Part/z_en_part.h @@ -5,6 +5,8 @@ struct EnPart; +#define ENPART_PARAMS(type) (type) + typedef void (*EnPartActionFunc)(struct EnPart*, PlayState*); typedef enum { diff --git a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c index 226aec92b..fdda7ed14 100644 --- a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c +++ b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c @@ -5,8 +5,9 @@ */ #include "z_en_rail_skb.h" -#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "objects/object_skb/object_skb.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10) @@ -1119,10 +1120,10 @@ void EnRailSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* Collider_UpdateSpheres(limbIndex, &this->collider); if ((limbIndex == 11) && (this->unk_402 & 1) && !(this->unk_402 & 2)) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); this->unk_402 |= 2; } else if ((this->unk_402 & 0x40) && ((limbIndex != 11) || !(this->unk_402 & 1)) && (limbIndex != 12)) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); } if (this->drawDmgEffTimer != 0) { diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/src/overlays/actors/ovl_En_Sb/z_en_sb.c index 08b1ad240..eaf5b88d3 100644 --- a/src/overlays/actors/ovl_En_Sb/z_en_sb.c +++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.c @@ -6,6 +6,7 @@ #include "z_en_sb.h" #include "objects/object_sb/object_sb.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY) @@ -388,13 +389,13 @@ void EnSb_Update(Actor* thisx, PlayState* play) { } void EnSb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { - s8 phi_a2; + s8 partParams; EnSb* this = THIS; if (this->isDrawn) { if (limbIndex < 7) { - phi_a2 = (this->actor.depthInWater > 0) ? 4 : 1; - Actor_SpawnBodyParts(thisx, play, phi_a2, dList); + partParams = (this->actor.depthInWater > 0) ? ENPART_PARAMS(ENPART_TYPE_4) : ENPART_PARAMS(ENPART_TYPE_1); + Actor_SpawnBodyParts(thisx, play, partParams, dList); } if (limbIndex == 6) { this->isDrawn = false; diff --git a/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/src/overlays/actors/ovl_En_Skb/z_en_skb.c index 98223faea..e2f40f35c 100644 --- a/src/overlays/actors/ovl_En_Skb/z_en_skb.c +++ b/src/overlays/actors/ovl_En_Skb/z_en_skb.c @@ -5,9 +5,10 @@ */ #include "z_en_skb.h" -#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" -#include "overlays/actors/ovl_En_Encount4/z_en_encount4.h" #include "objects/object_skb/object_skb.h" +#include "overlays/actors/ovl_En_Encount4/z_en_encount4.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY) @@ -1106,12 +1107,12 @@ void EnSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Collider_UpdateSpheres(limbIndex, &this->collider); if ((this->unk_3D8 & 1) && !(this->unk_3D8 & 2)) { if (limbIndex == 11) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); this->unk_3D8 |= 2; } } else if ((this->unk_3D8 & 0x40) && !(this->unk_3D8 & 0x80) && ((limbIndex != 11) || !(this->unk_3D8 & 1)) && (limbIndex != 12)) { - Actor_SpawnBodyParts(&this->actor, play, 1, dList); + Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList); } if (this->drawDmgEffTimer != 0) { diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index a902899ea..323b6a014 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8846,45 +8846,45 @@ 0x809AD614:("EnEncount3_Draw",), 0x809AD8E0:("EnJso_Init",), 0x809ADB24:("EnJso_Destroy",), - 0x809ADBC8:("func_809ADBC8",), - 0x809ADC7C:("func_809ADC7C",), - 0x809ADCB8:("func_809ADCB8",), - 0x809AE754:("func_809AE754",), - 0x809AE87C:("func_809AE87C",), - 0x809AE9B0:("func_809AE9B0",), - 0x809AEA08:("func_809AEA08",), - 0x809AECA8:("func_809AECA8",), - 0x809AED00:("func_809AED00",), - 0x809AED54:("func_809AED54",), - 0x809AEDAC:("func_809AEDAC",), - 0x809AEE44:("func_809AEE44",), - 0x809AEEC0:("func_809AEEC0",), - 0x809AF064:("func_809AF064",), - 0x809AF110:("func_809AF110",), - 0x809AF28C:("func_809AF28C",), - 0x809AF2F8:("func_809AF2F8",), - 0x809AF368:("func_809AF368",), - 0x809AF3C0:("func_809AF3C0",), - 0x809AF3FC:("func_809AF3FC",), - 0x809AF440:("func_809AF440",), - 0x809AF470:("func_809AF470",), - 0x809AF53C:("func_809AF53C",), - 0x809AF5F8:("func_809AF5F8",), - 0x809AF714:("func_809AF714",), - 0x809AF76C:("func_809AF76C",), - 0x809AF7F4:("func_809AF7F4",), - 0x809AF8D0:("func_809AF8D0",), - 0x809AF99C:("func_809AF99C",), - 0x809AFA58:("func_809AFA58",), - 0x809AFAF4:("func_809AFAF4",), - 0x809AFC10:("func_809AFC10",), - 0x809AFE38:("func_809AFE38",), - 0x809B0034:("func_809B0034",), + 0x809ADBC8:("EnJso_ChangeAnim",), + 0x809ADC7C:("EnJso_SetupHandleIntroCutscene",), + 0x809ADCB8:("EnJso_HandleIntroCutscene",), + 0x809AE754:("EnJso_SetupReappear",), + 0x809AE87C:("EnJso_Reappear",), + 0x809AE9B0:("EnJso_SetupCirclePlayer",), + 0x809AEA08:("EnJso_CirclePlayer",), + 0x809AECA8:("EnJso_SetupGuard",), + 0x809AED00:("EnJso_Guard",), + 0x809AED54:("EnJso_SetupSpinBeforeAttack",), + 0x809AEDAC:("EnJso_SpinBeforeAttack",), + 0x809AEE44:("EnJso_SetupDashAttack",), + 0x809AEEC0:("EnJso_DashAttack",), + 0x809AF064:("EnJso_SetupSlash",), + 0x809AF110:("EnJso_Slash",), + 0x809AF28C:("EnJso_SetupWaitAfterSlash",), + 0x809AF2F8:("EnJso_WaitAfterSlash",), + 0x809AF368:("EnJso_SetupKnockedBack",), + 0x809AF3C0:("EnJso_KnockedBack",), + 0x809AF3FC:("EnJso_SetupCower",), + 0x809AF440:("EnJso_Cower",), + 0x809AF470:("EnJso_SetupStunned",), + 0x809AF53C:("EnJso_Stunned",), + 0x809AF5F8:("EnJso_SetupDamaged",), + 0x809AF714:("EnJso_Damaged",), + 0x809AF76C:("EnJso_SetupJumpBack",), + 0x809AF7F4:("EnJso_JumpBack",), + 0x809AF8D0:("EnJso_SetupDead",), + 0x809AF99C:("EnJso_Dead",), + 0x809AFA58:("EnJso_SetupFallDownAndTalk",), + 0x809AFAF4:("EnJso_FallDownAndTalk",), + 0x809AFC10:("EnJso_TellHint",), + 0x809AFE38:("EnJso_BurstIntoFlames",), + 0x809B0034:("EnJso_UpdateDamage",), 0x809B02CC:("EnJso_Update",), - 0x809B0734:("func_809B0734",), - 0x809B0820:("func_809B0820",), - 0x809B0B70:("func_809B0B70",), - 0x809B0BB0:("func_809B0BB0",), + 0x809B0734:("EnJso_OverrideLimbDraw",), + 0x809B0820:("EnJso_PostLimbDraw",), + 0x809B0B70:("EnJso_SetAfterimageRenderMode",), + 0x809B0BB0:("EnJso_Draw",), 0x809B1550:("func_809B1550",), 0x809B162C:("ObjChikuwa_Init",), 0x809B179C:("ObjChikuwa_Destroy",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index ad17bf28b..2602149cf 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -9487,21 +9487,21 @@ 0x809AD82C:("D_809AD82C","f32","",0x4), 0x809AD830:("D_809AD830","f32","",0x4), 0x809AD834:("D_809AD834","f32","",0x4), - 0x809B0F40:("D_809B0F40","UNK_TYPE4","",0x4), - 0x809B0F44:("D_809B0F44","UNK_TYPE4","",0x4), - 0x809B0F48:("D_809B0F48","UNK_TYPE1","",0x1), - 0x809B0F68:("En_Jso_InitVars","UNK_TYPE1","",0x1), - 0x809B0F88:("D_809B0F88","UNK_TYPE1","",0x1), - 0x809B0FB4:("D_809B0FB4","UNK_TYPE1","",0x1), - 0x809B1004:("D_809B1004","UNK_TYPE1","",0x1), - 0x809B100C:("D_809B100C","UNK_TYPE1","",0x1), - 0x809B103C:("D_809B103C","UNK_TYPE1","",0x1), - 0x809B1048:("D_809B1048","UNK_TYPE4","",0x4), - 0x809B10B4:("D_809B10B4","UNK_TYPE1","",0x1), - 0x809B10C0:("D_809B10C0","UNK_TYPE1","",0x1), - 0x809B10CC:("D_809B10CC","UNK_TYPE1","",0x1), - 0x809B10D8:("D_809B10D8","UNK_TYPE1","",0x1), - 0x809B10E4:("D_809B10E4","UNK_TYPE2","",0x2), + 0x809B0F40:("sIsAttacking","s32","",0x4), + 0x809B0F44:("sIsPlayerLockedOn","s32","",0x4), + 0x809B0F48:("sDamageTable","DamageTable","",0x20), + 0x809B0F68:("En_Jso_InitVars","ActorInit","",0x20), + 0x809B0F88:("sCylinderInit","ColliderCylinderInit","",0x2C), + 0x809B0FB4:("sQuadInit","ColliderQuadInit","",0x50), + 0x809B1004:("sTextIds","u16","[4]",0x8), + 0x809B100C:("sAnimations","AnimationHeader*","[12]",0x30), + 0x809B103C:("sAnimationModes","u8","[12]",0xC), + 0x809B1048:("fireVelocityAndAccel","Vec3f","[9]",0x6C), + 0x809B10B4:("sSwordTipOffset","Vec3f","",0xC), + 0x809B10C0:("sSwordBaseOffset","Vec3f","",0xC), + 0x809B10CC:("sSwordTipQuadOffset","Vec3f","",0xC), + 0x809B10D8:("sSwordBaseQuadOffset","Vec3f","",0xC), + 0x809B10E4:("sAfterimageAlpha","s16","[20]",0x28), 0x809B1110:("D_809B1110","f32","",0x4), 0x809B1114:("jtbl_809B1114","UNK_PTR","",0x4), 0x809B112C:("D_809B112C","f32","",0x4), diff --git a/undefined_syms.txt b/undefined_syms.txt index 010f94c05..3a630cd3d 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -462,11 +462,6 @@ D_06015C28 = 0x06015C28; D_060156D8 = 0x060156D8; D_06016720 = 0x06016720; -// ovl_En_Jso - -D_060081F4 = 0x060081F4; -D_0600AA00 = 0x0600AA00; - // ovl_En_Jso2 D_06002ED8 = 0x06002ED8; From f545f164b4bd26a3438b6f5251042b558986268f Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:59:25 +1100 Subject: [PATCH 7/9] Switch Flag "None" macro (#1412) * switch flag none * cleanup brackets * individual actor switch flag none * missed some, small cleanup * <= 0x80 --- include/z64actor.h | 2 ++ src/code/z_actor.c | 6 +++--- .../ovl_Bg_F40_Switch/z_bg_f40_switch.c | 4 ++-- src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c | 6 +++--- src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c | 6 +++--- src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c | 6 +++--- src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c | 6 +++--- src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c | 6 +++--- src/overlays/actors/ovl_En_Bal/z_en_bal.c | 2 +- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c | 4 ++-- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h | 6 ++++-- .../actors/ovl_En_Daiku2/z_en_daiku2.c | 12 +++++------ .../actors/ovl_En_Daiku2/z_en_daiku2.h | 1 + src/overlays/actors/ovl_En_Egol/z_en_egol.c | 8 ++++---- src/overlays/actors/ovl_En_Egol/z_en_egol.h | 1 + .../actors/ovl_En_Encount2/z_en_encount2.c | 8 ++++---- .../actors/ovl_En_Encount2/z_en_encount2.h | 6 ++++-- .../actors/ovl_En_Encount3/z_en_encount3.c | 10 +++++----- .../actors/ovl_En_Encount3/z_en_encount3.h | 2 ++ .../actors/ovl_En_Encount4/z_en_encount4.c | 20 +++++++++---------- .../actors/ovl_En_Encount4/z_en_encount4.h | 6 ++++-- .../ovl_En_Hidden_Nuts/z_en_hidden_nuts.c | 8 ++++---- .../ovl_En_Hidden_Nuts/z_en_hidden_nuts.h | 1 + .../z_en_invisible_ruppe.c | 8 ++++---- .../z_en_invisible_ruppe.h | 2 ++ .../actors/ovl_En_Kaizoku/z_en_kaizoku.c | 8 ++++---- .../actors/ovl_En_Kaizoku/z_en_kaizoku.h | 8 +++++--- .../actors/ovl_En_Look_Nuts/z_en_look_nuts.c | 8 ++++---- .../actors/ovl_En_Look_Nuts/z_en_look_nuts.h | 3 ++- src/overlays/actors/ovl_En_Mnk/z_en_mnk.c | 2 +- src/overlays/actors/ovl_En_Mnk/z_en_mnk.h | 1 + .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 8 ++++---- .../ovl_En_Okarina_Tag/z_en_okarina_tag.h | 2 ++ .../actors/ovl_En_Onpuman/z_en_onpuman.c | 4 ++-- src/overlays/actors/ovl_En_Raf/z_en_raf.c | 10 +++++----- src/overlays/actors/ovl_En_Raf/z_en_raf.h | 2 ++ .../actors/ovl_En_S_Goro/z_en_s_goro.c | 4 ++-- .../ovl_En_Stop_heishi/z_en_stop_heishi.c | 6 +++--- .../ovl_En_Stop_heishi/z_en_stop_heishi.h | 2 ++ .../ovl_En_Talk_Gibud/z_en_talk_gibud.c | 8 ++++---- .../ovl_En_Talk_Gibud/z_en_talk_gibud.h | 2 ++ src/overlays/actors/ovl_En_Wiz/z_en_wiz.c | 8 ++++---- src/overlays/actors/ovl_En_Wiz/z_en_wiz.h | 2 ++ src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c | 2 +- .../actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c | 6 +++--- .../actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h | 2 ++ .../actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c | 6 +++--- .../actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h | 2 ++ src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c | 2 +- .../ovl_Obj_Ocarinalift/z_obj_ocarinalift.c | 2 +- .../actors/ovl_Obj_Syokudai/z_obj_syokudai.c | 14 +++++++------ .../actors/ovl_Obj_Syokudai/z_obj_syokudai.h | 12 ++++++----- 52 files changed, 160 insertions(+), 123 deletions(-) diff --git a/include/z64actor.h b/include/z64actor.h index b3e1fe77e..5d072d253 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -370,6 +370,8 @@ typedef struct ActorSharedMemoryEntry { /* 0x4 */ void* ptr; } ActorSharedMemoryEntry; // size = 0x8 +#define SWITCH_FLAG_NONE -1 + typedef struct ActorContextSceneFlags { /* 0x00 */ u32 switches[4]; // First 0x40 are permanent, second 0x40 are temporary /* 0x10 */ u32 chest; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index e1c13ae4a..b48484687 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -728,7 +728,7 @@ void Target_Update(TargetContext* targetCtx, Player* player, Actor* lockOnActor, * Tests if a current scene switch flag is set. */ s32 Flags_GetSwitch(PlayState* play, s32 flag) { - if ((flag >= 0) && (flag < 0x80)) { + if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) { return play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F)); } return 0; @@ -738,7 +738,7 @@ s32 Flags_GetSwitch(PlayState* play, s32 flag) { * Sets a current scene switch flag. */ void Flags_SetSwitch(PlayState* play, s32 flag) { - if ((flag >= 0) && (flag < 0x80)) { + if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) { play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F); } } @@ -747,7 +747,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) { * Unsets a current scene switch flag. */ void Flags_UnsetSwitch(PlayState* play, s32 flag) { - if ((flag >= 0) && (flag < 0x80)) { + if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) { play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] &= ~(1 << (flag & 0x1F)); } } diff --git a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c index 18063efce..cbeea4911 100644 --- a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c +++ b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c @@ -74,7 +74,7 @@ void BgF40Switch_CheckAll(BgF40Switch* this, PlayState* play) { } if (actorAsSwitch->isPressed) { switchFlag = BGF40SWITCH_GET_SWITCH_FLAG(&actorAsSwitch->dyna.actor); - if ((switchFlag >= 0) && (switchFlag < 0x80)) { + if ((switchFlag > SWITCH_FLAG_NONE) && (switchFlag < 0x80)) { pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] |= 1 << (switchFlag & 0x1F); if (!actorAsSwitch->wasPressed && (actorAsSwitch->actionFunc == BgF40Switch_IdleUnpressed) && !Flags_GetSwitch(play, switchFlag)) { @@ -88,7 +88,7 @@ void BgF40Switch_CheckAll(BgF40Switch* this, PlayState* play) { if ((actor->id == ACTOR_BG_F40_SWITCH) && (actor->room == this->dyna.actor.room) && (actor->update != NULL)) { switchFlag = BGF40SWITCH_GET_SWITCH_FLAG(actor); - if ((switchFlag >= 0) && (switchFlag < 0x80) && Flags_GetSwitch(play, switchFlag) && + if ((switchFlag > SWITCH_FLAG_NONE) && (switchFlag < 0x80) && Flags_GetSwitch(play, switchFlag) && !(pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] & (1 << (switchFlag & 0x1F)))) { Flags_UnsetSwitch(play, switchFlag); } diff --git a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c index f2089ca03..eb1d5761e 100644 --- a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -40,8 +40,8 @@ void ElfMsg_SetupAction(ElfMsg* this, ElfMsgActionFunc actionFunc) { } s32 func_8092DF9C(ElfMsg* this, PlayState* play) { - if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) && - (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) { + if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) && + Flags_GetSwitch(play, this->actor.home.rot.y - 1)) { (void)"共倒れ"; // "Collapse together" if (ELFMSG_GET_SWITCH_FLAG(&this->actor) != 0x7F) { Flags_SetSwitch(play, ELFMSG_GET_SWITCH_FLAG(&this->actor)); @@ -144,7 +144,7 @@ void ElfMsg_Update(Actor* thisx, PlayState* play) { } if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) || - (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) { + Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) { this->actionFunc(this, play); } } diff --git a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c index 552478ace..409202468 100644 --- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c +++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c @@ -40,8 +40,8 @@ void ElfMsg2_SetupAction(ElfMsg2* this, ElfMsg2ActionFunc actionFunc) { } s32 func_8096EC4C(ElfMsg2* this, PlayState* play) { - if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) && - (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) { + if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) && + Flags_GetSwitch(play, this->actor.home.rot.y - 1)) { (void)"共倒れ"; // "Collapse together" if (ELFMSG2_GET_SWITCH_FLAG(&this->actor) != 0x7F) { Flags_SetSwitch(play, ELFMSG2_GET_SWITCH_FLAG(&this->actor)); @@ -135,7 +135,7 @@ void func_8096EF98(ElfMsg2* this, PlayState* play) { void func_8096EFD0(ElfMsg2* this, PlayState* play) { if ((this->actor.home.rot.y < 0) && (this->actor.home.rot.y >= -0x80) && - (Flags_GetSwitch(play, -this->actor.home.rot.y - 1))) { + Flags_GetSwitch(play, -this->actor.home.rot.y - 1)) { ElfMsg2_SetupAction(this, func_8096EF98); this->actor.flags |= (ACTOR_FLAG_40000 | ACTOR_FLAG_TARGETABLE); this->actor.textId = func_8096EE50(this); diff --git a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c index b7b349dfe..ba8256361 100644 --- a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c +++ b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c @@ -39,8 +39,8 @@ void ElfMsg3_SetupAction(ElfMsg3* this, ElfMsg3ActionFunc actionFunc) { } s32 func_80A2CD1C(ElfMsg3* this, PlayState* play) { - if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) && - (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) { + if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) && + Flags_GetSwitch(play, this->actor.home.rot.y - 1)) { (void)"共倒れ"; // "Collapse together" if (ELFMSG3_GET_SWITCH_FLAG(&this->actor) != 0x7F) { Flags_SetSwitch(play, ELFMSG3_GET_SWITCH_FLAG(&this->actor)); @@ -142,7 +142,7 @@ void ElfMsg3_Update(Actor* thisx, PlayState* play) { } if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) || - (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) { + Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) { this->actionFunc(this, play); } } diff --git a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c index 423f8c351..5f1f0d3dc 100644 --- a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c +++ b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c @@ -40,8 +40,8 @@ static InitChainEntry sInitChain[] = { }; s32 func_80AFD380(ElfMsg4* this, PlayState* play) { - if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) && - (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) { + if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) && + Flags_GetSwitch(play, this->actor.home.rot.y - 1)) { (void)"共倒れ"; // "Collapse together" if (ELFMSG4_GET_SWITCH_FLAG(&this->actor) != 0x7F) { Flags_SetSwitch(play, ELFMSG4_GET_SWITCH_FLAG(&this->actor)); @@ -169,7 +169,7 @@ void ElfMsg4_Update(Actor* thisx, PlayState* play) { } if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) || - (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) { + Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) { this->actionFunc(this, play); } } diff --git a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c index c44ab8e0a..236933fc9 100644 --- a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c +++ b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c @@ -35,8 +35,8 @@ static InitChainEntry sInitChainsInitChain[] = { }; s32 func_80AFD990(ElfMsg5* this, PlayState* play) { - if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) && - (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) { + if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) && + Flags_GetSwitch(play, this->actor.home.rot.y - 1)) { (void)"共倒れ"; // Collapse together if (ELFMSG5_GET_SWITCH_FLAG(&this->actor) != 0x7F) { Flags_SetSwitch(play, ELFMSG5_GET_SWITCH_FLAG(&this->actor)); @@ -87,7 +87,7 @@ void ElfMsg5_Update(Actor* thisx, PlayState* play) { ElfMsg5* this = THIS; if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) || - (Flags_GetSwitch(play, -this->actor.home.rot.y - 1))) { + Flags_GetSwitch(play, -this->actor.home.rot.y - 1)) { this->actionFunc(this, play); } } diff --git a/src/overlays/actors/ovl_En_Bal/z_en_bal.c b/src/overlays/actors/ovl_En_Bal/z_en_bal.c index 490517e09..95b495124 100644 --- a/src/overlays/actors/ovl_En_Bal/z_en_bal.c +++ b/src/overlays/actors/ovl_En_Bal/z_en_bal.c @@ -864,7 +864,7 @@ void EnBal_TryPurchaseMap(EnBal* this, PlayState* play) { void EnBal_HandleConversation(EnBal* this, PlayState* play) { if (((this->textId != 0x1D07) || Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) && - (Message_ShouldAdvance(play))) { + Message_ShouldAdvance(play)) { switch (this->textId) { case 0x1D00: Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, TINGLE_ANIM_TALK); diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c index e754ff5b8..4fa521de3 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -222,7 +222,7 @@ void EnBigpo_Init(Actor* thisx, PlayState* play2) { this->mainColor.b = 210; this->mainColor.a = 0; // fully invisible - if ((this->switchFlag != 0xFF) && (Flags_GetSwitch(play, this->switchFlag))) { + if ((this->switchFlag != BIG_POE_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); } @@ -756,7 +756,7 @@ void EnBigpo_SetupLanternDrop(EnBigpo* this, PlayState* play) { void EnBigpo_LanternFalling(EnBigpo* this, PlayState* play) { if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND || this->actor.floorHeight == BGCHECK_Y_MIN) { - if (this->switchFlag != 0xFF) { + if (this->switchFlag != BIG_POE_SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h index d5bdaf1e8..6fd0db8a3 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h @@ -8,6 +8,10 @@ struct EnBigpo; typedef void (*EnBigPoActionFunc)(struct EnBigpo*, PlayState*); +#define BIG_POE_GET_SWITCH_FLAG(thisx) (u8)((thisx)->params >> 0x8) + +#define BIG_POE_SWITCH_FLAG_NONE 0xFF + typedef enum BigPoeBodyPart { /* 0 */ BIG_POE_BODYPART_0, /* 1 */ BIG_POE_BODYPART_1, @@ -75,6 +79,4 @@ typedef enum EnBigpoType { /* 5 */ BIG_POE_TYPE_UNK5 } EnBigpoType; -#define BIG_POE_GET_SWITCH_FLAG(thisx) (u8)((thisx)->params >> 0x8) - #endif // Z_EN_BIGPO_H diff --git a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c index 1e322650e..90d8673f6 100644 --- a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c +++ b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c @@ -97,8 +97,8 @@ void EnDaiku2_Init(Actor* thisx, PlayState* play) { return; } - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENDAIKU2_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } else if (Flags_GetSwitch(play, this->switchFlag)) { this->unk_25C = this->path->count - 1; func_80BE61D0(this); @@ -185,7 +185,7 @@ s32 func_80BE64C0(EnDaiku2* this, PlayState* play) { Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); bomb = (EnBom*)Actor_FindNearby(play, &this->actor, -1, ACTORCAT_EXPLOSIVES, BREG(7) + 240.0f); Math_Vec3f_Copy(&this->actor.world.pos, &sp30); - if ((this->switchFlag >= 0) && !Flags_GetSwitch(play, this->switchFlag) && (bomb != NULL) && + if ((this->switchFlag > SWITCH_FLAG_NONE) && !Flags_GetSwitch(play, this->switchFlag) && (bomb != NULL) && (bomb->actor.id == ACTOR_EN_BOM)) { if (!bomb->isPowderKeg) { this->actor.textId = 0x32D3; @@ -228,7 +228,7 @@ void func_80BE65B4(EnDaiku2* this, PlayState* play) { } this->unk_264 = 1.0f; - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->unk_28A = 5; if (this->animIndex != ENDAIKU2_ANIM_10) { EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10); @@ -251,7 +251,7 @@ void func_80BE66E4(EnDaiku2* this, PlayState* play) { Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.home.rot.y, 1, 0xBB8, 0x0); if (sp98 != 2) { - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->unk_28A = 5; if (this->animIndex != ENDAIKU2_ANIM_10) { EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10); @@ -433,7 +433,7 @@ void func_80BE6EF0(EnDaiku2* this, PlayState* play) { EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_3); } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->unk_28A = 5; if (this->animIndex != ENDAIKU2_ANIM_10) { EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10); diff --git a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h index c047b6577..a462d854f 100644 --- a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h +++ b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h @@ -12,6 +12,7 @@ typedef void (*EnDaiku2ActionFunc)(struct EnDaiku2*, PlayState*); #define ENDAIKU2_GET_PATH_INDEX(thisx) (((thisx)->params >> 7) & 0x3F) #define ENDAIKU2_GET_8000(thisx) (((thisx)->params >> 15) & 0x1) +#define ENDAIKU2_SWITCH_FLAG_NONE 0x7F #define ENDAIKU2_PATH_INDEX_NONE 0x3F typedef struct EnDaiku2Effect { diff --git a/src/overlays/actors/ovl_En_Egol/z_en_egol.c b/src/overlays/actors/ovl_En_Egol/z_en_egol.c index 775a14eb5..9d5c148f9 100644 --- a/src/overlays/actors/ovl_En_Egol/z_en_egol.c +++ b/src/overlays/actors/ovl_En_Egol/z_en_egol.c @@ -482,10 +482,10 @@ void EnEgol_Init(Actor* thisx, PlayState* play) { EYEGORE_SET_SPH_DIM(this->bodyCollider.elements[5], 2100, -300, 0, 37, 1.0f); this->switchFlag = EYEGORE_GET_SWITCH_FLAG(&this->actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == EYEGORE_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag > -1) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } @@ -1096,7 +1096,7 @@ void EnEgol_Death(EnEgol* this, PlayState* play) { Play_SetCameraAtEye(play, this->subCamId, &this->subCamEye, &this->subCamAt); Play_SetCameraFov(play, this->subCamId, this->subCamFov); if ((this->action == EYEGORE_ACTION_DEAD) && (this->waitTimer == 1)) { - if (this->switchFlag > -1) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } CutsceneManager_Stop(this->actor.csId); diff --git a/src/overlays/actors/ovl_En_Egol/z_en_egol.h b/src/overlays/actors/ovl_En_Egol/z_en_egol.h index 0861ce580..66c828922 100644 --- a/src/overlays/actors/ovl_En_Egol/z_en_egol.h +++ b/src/overlays/actors/ovl_En_Egol/z_en_egol.h @@ -12,6 +12,7 @@ typedef void (*EnEgolActionFunc)(struct EnEgol*, PlayState*); #define EYEGORE_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F) #define EYEGORE_PATH_INDEX_NONE 0x3F +#define EYEGORE_SWITCH_FLAG_NONE 0x7F #define EYEGORE_PARAMS(switch, pathIndex) ((((switch) & 0x7F) << 6) | ((pathIndex) & 0x3F)) diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c index c840c33e1..e56252b43 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -117,11 +117,11 @@ void EnEncount2_Init(Actor* thisx, PlayState* play) { this->scale = 0.1f; this->switchFlag = ENCOUNT2_GET_SWITCH_FLAG(&this->dyna.actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENCOUNT2_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->dyna.actor); return; } @@ -180,7 +180,7 @@ void EnEncount2_Popped(EnEncount2* this, PlayState* play) { void EnEncount2_Die(EnEncount2* this, PlayState* play) { if (this->deathTimer == 0) { - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } Actor_Kill(&this->dyna.actor); diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h index 0a9cb1394..12eb62428 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h @@ -7,6 +7,10 @@ struct EnEncount2; typedef void (*EnEncount2ActionFunc)(struct EnEncount2*, PlayState*); +#define ENCOUNT2_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) + +#define ENCOUNT2_SWITCH_FLAG_NONE 0x7F + typedef struct EnEncount2Effect{ /* 0x00 */ u8 isEnabled; /* 0x04 */ Vec3f pos; @@ -33,6 +37,4 @@ typedef struct EnEncount2 { /* 0x01D0 */ EnEncount2Effect effects[EN_ENCOUNT2_EFFECT_COUNT]; } EnEncount2; // size = 0x2A70 -#define ENCOUNT2_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) - #endif // Z_EN_ENCOUNT2_H diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c index fa37bcb38..61ff3039f 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c @@ -49,10 +49,10 @@ void EnEncount3_Init(Actor* thisx, PlayState* play) { } else if (this->unk16C > 1000.0f) { this->unk16C = 1000.0f; } - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENCOUNT3_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); } this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; @@ -71,7 +71,7 @@ void func_809AD058(EnEncount3* this) { } void func_809AD084(EnEncount3* this, PlayState* play) { - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } @@ -94,7 +94,7 @@ void func_809AD084(EnEncount3* this, PlayState* play) { void func_809AD194(EnEncount3* this, PlayState* play) { if (this->unk14E == 0) { this->unk178 = 0.0f; - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } this->actionFunc = func_809AD1EC; diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h index 9e8bd01ad..cd1df694b 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h @@ -13,6 +13,8 @@ typedef void (*EnEncount3ActionFunc)(struct EnEncount3*, PlayState*); #define ENCOUNT3_GET_ROTZ(thisx) ((thisx)->world.rot.z) +#define ENCOUNT3_SWITCH_FLAG_NONE 0x7F + typedef struct EnEncount3 { /* 0x000 */ Actor actor; /* 0x144 */ EnEncount3ActionFunc actionFunc; diff --git a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c index 077273309..376401ae4 100644 --- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c +++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c @@ -43,12 +43,12 @@ void EnEncount4_Init(Actor* thisx, PlayState* play) { s32 pad; EnEncount4* this = THIS; - this->unk_148 = ENENCOUNT4_GET_F000(thisx); - this->switchFlag = ENENCOUNT4_GET_FLAG(thisx); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + this->unk_148 = ENCOUNT4_GET_F000(thisx); + this->switchFlag = ENCOUNT4_GET_SWITCH_FLAG(thisx); + if (this->switchFlag == ENCOUNT4_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } @@ -64,7 +64,7 @@ void func_809C3FD8(EnEncount4* this, PlayState* play) { Actor* actor; this->unk_14E = 0; - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->timer = 100; this->actionFunc = func_809C464C; } else { @@ -89,7 +89,7 @@ void func_809C4078(EnEncount4* this, PlayState* play) { s32 i; EnBsb* captainKeeta = this->captainKeeta; - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->timer = 100; this->actionFunc = func_809C464C; } else if (BREG(1) == 0) { @@ -135,7 +135,7 @@ void func_809C42A8(EnEncount4* this, PlayState* play) { CollisionPoly* colPoly; s32 bgId; - if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->timer = 100; this->actionFunc = func_809C464C; @@ -185,12 +185,12 @@ void func_809C42A8(EnEncount4* this, PlayState* play) { } void func_809C4598(EnEncount4* this, PlayState* play) { - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { this->timer = 100; this->actionFunc = func_809C464C; } else if (this->unk_14E >= 2) { this->timer = 100; - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } this->actionFunc = func_809C464C; diff --git a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h index a692f796a..64dfdff92 100644 --- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h +++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h @@ -10,8 +10,10 @@ struct EnEncount4; typedef void (*EnEncount4ActionFunc)(struct EnEncount4*, PlayState*); -#define ENENCOUNT4_GET_FLAG(thisx) ((thisx)->params & 0x7F) -#define ENENCOUNT4_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) +#define ENCOUNT4_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) +#define ENCOUNT4_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) + +#define ENCOUNT4_SWITCH_FLAG_NONE 0x7F typedef struct EnEncount4 { /* 0x000 */ Actor actor; diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c index 48f75aa68..ef88474f8 100644 --- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c +++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c @@ -115,11 +115,11 @@ void EnHiddenNuts_Init(Actor* thisx, PlayState* play) { this->pathIndex = ENHIDDENNUTS_GET_PATH_INDEX(&this->actor); this->switchFlag = ENHIDDENNUTS_GET_SWITCH_FLAG(&this->actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENHIDDENNUTS_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } @@ -411,7 +411,7 @@ void func_80BDBB48(EnHiddenNuts* this, PlayState* play) { } void func_80BDBE70(EnHiddenNuts* this, PlayState* play) { - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } EnHiddenNuts_ChangeAnim(this, ENHIDDENNUTS_ANIM_8); diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h index 7df4b5f01..517ade964 100644 --- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h +++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h @@ -11,6 +11,7 @@ typedef void (*EnHiddenNutsActionFunc)(struct EnHiddenNuts*, PlayState*); #define ENHIDDENNUTS_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) #define ENHIDDENNUTS_GET_PATH_INDEX(thisx) (((thisx)->params >> 7) & 0x1F) +#define ENHIDDENNUTS_SWITCH_FLAG_NONE 0x7F #define ENHIDDENNUTS_PATH_INDEX_NONE 0x1F #define ENHIDDENNUTS_PATH_INDEX_NONE_ALT 0x3F diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c index dcecdac43..a9cf2e351 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c @@ -80,7 +80,7 @@ void func_80C2590C(EnInvisibleRuppe* this, PlayState* play) { break; } - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } @@ -98,11 +98,11 @@ void EnInvisibleRuppe_Init(Actor* thisx, PlayState* play) { this->switchFlag = INVISIBLERUPPE_GET_SWITCH_FLAG(&this->actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == INVISIBLERUPPE_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h index 2257a649a..1e6ae328e 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h @@ -10,6 +10,8 @@ typedef void (*EnInvisibleRuppeActionFunc)(struct EnInvisibleRuppe*, PlayState*) #define INVISIBLERUPPE_GET_3(thisx) ((thisx)->params & 3) #define INVISIBLERUPPE_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0x1FC) >> 2) +#define INVISIBLERUPPE_SWITCH_FLAG_NONE 0x7F + typedef struct EnInvisibleRuppe { /* 0x000 */ Actor actor; /* 0x144 */ ColliderCylinder collider; diff --git a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c index abba3efac..59ba5feb4 100644 --- a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c +++ b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c @@ -287,11 +287,11 @@ void EnKaizoku_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->picto.actor, 0.0125f); this->picto.actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; this->picto.actor.flags &= ~ACTOR_FLAG_TARGETABLE; - if (this->switchFlag == 127) { - this->switchFlag = -1; + if (this->switchFlag == KAIZOKU_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->picto.actor); return; } @@ -867,7 +867,7 @@ void func_80B86B74(EnKaizoku* this, PlayState* play) { this->subCamId = SUB_CAM_ID_DONE; func_800B7298(play, &this->picto.actor, PLAYER_CSMODE_END); CutsceneManager_Stop(this->csId); - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } Actor_Kill(&this->picto.actor); diff --git a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h index 423819eb3..15562ee2e 100644 --- a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h +++ b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h @@ -5,13 +5,15 @@ #include "z64snap.h" #include "objects/object_kz/object_kz.h" -#define KAIZOKU_GET_EXIT_INDEX(thisx) ((thisx)->params & 0x3F) -#define KAIZOKU_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F) - struct EnKaizoku; typedef void (*EnKaizokuActionFunc)(struct EnKaizoku*, PlayState*); +#define KAIZOKU_GET_EXIT_INDEX(thisx) ((thisx)->params & 0x3F) +#define KAIZOKU_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F) + +#define KAIZOKU_SWITCH_FLAG_NONE 0x7F + typedef enum EnKaizokuAnimation { /* 0 */ EN_KAIZOKU_ANIM_0, /* 1 */ EN_KAIZOKU_ANIM_1, diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c index 880f48e82..09358e034 100644 --- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c +++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c @@ -113,13 +113,13 @@ void EnLookNuts_Init(Actor* thisx, PlayState* play) { Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON; this->pathIndex = LOOKNUTS_GET_PATH_INDEX(&this->actor); - this->switchFlag = LOOKNUTS_GET_SCENE_FLAG(&this->actor); + this->switchFlag = LOOKNUTS_GET_SWITCH_FLAG(&this->actor); this->spawnIndex = LOOKNUTS_GET_SPAWN_INDEX(&this->actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == LOOKNUTS_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h index 92c24cfbd..1cce177d4 100644 --- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h +++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h @@ -9,9 +9,10 @@ struct EnLookNuts; typedef void (*EnLookNutsActionFunc)(struct EnLookNuts*, PlayState*); #define LOOKNUTS_GET_SPAWN_INDEX(thisx) (((thisx)->params >> 0xC) & 0xF) -#define LOOKNUTS_GET_SCENE_FLAG(thisx) ((thisx)->params & 0x7F) +#define LOOKNUTS_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) #define LOOKNUTS_GET_PATH_INDEX(thisx) (((thisx)->params >> 0x7) & 0x1F) +#define LOOKNUTS_SWITCH_FLAG_NONE 0x7F #define LOOKNUTS_PATH_INDEX_NONE 0x1F typedef struct EnLookNuts { diff --git a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c index 82e25a95d..1a2925f65 100644 --- a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c +++ b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c @@ -897,7 +897,7 @@ void EnMnk_Monkey_Run(EnMnk* this, PlayState* play) { this->picto.actor.speed = 0.0f; if (MONKEY_GET_TYPE(&this->picto.actor) == MONKEY_OUTSIDECHAMBER) { switchFlag = MONKEY_GET_SWITCH_FLAG(&this->picto.actor); - if (switchFlag != 0x7F) { + if (switchFlag != MONKEY_SWITCH_FLAG_NONE) { Flags_SetSwitch(play, switchFlag + 1); } Actor_Kill(&this->picto.actor); diff --git a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h index a9493208f..42a23f99c 100644 --- a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h +++ b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h @@ -14,6 +14,7 @@ typedef void (*EnMnkFunc)(PlayState*, struct EnMnk*); #define MONKEY_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) #define MONKEY_GET_PATH_INDEX(thisx) (((thisx)->params & 0xF800) >> 11) +#define MONKEY_SWITCH_FLAG_NONE 0x7F #define MONKEY_PATH_INDEX_NONE 0x1F typedef enum { diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 9119e0609..4b225880b 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -50,8 +50,8 @@ void EnOkarinaTag_Init(Actor* thisx, PlayState* play) { } this->unk154 = zRot * 50.0f; this->unk158 = i * 50.0f; - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENOKARINATAG_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } if (this->unk14A == 0xF) { this->unk14A = -1; @@ -66,7 +66,7 @@ void func_8093E518(EnOkarinaTag* this, PlayState* play) { s16 yDiff; u16 var_v1; - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { if (this->unk148 == 0) { if (Flags_GetSwitch(play, this->switchFlag)) { return; @@ -122,7 +122,7 @@ void func_8093E68C(EnOkarinaTag* this, PlayState* play) { (play->msgCtx.ocarinaMode == OCARINA_MODE_PLAYED_SUNS) || (play->msgCtx.ocarinaMode == OCARINA_MODE_PLAYED_STORMS) || (play->msgCtx.ocarinaMode == OCARINA_MODE_F)))) { - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { switch (this->unk148) { case 0: Flags_SetSwitch(play, this->switchFlag); diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h index 4c968b362..649f3b3da 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h @@ -11,6 +11,8 @@ typedef void (*EnOkarinaTagActionFunc)(struct EnOkarinaTag*, PlayState*); #define ENOKARINATAG_GET_780(thisx) (((thisx)->params >> 0x7) & 0xF) #define ENOKARINATAG_GET_F800(thisx) (((thisx)->params >> 0xB) & 0x1F) +#define ENOKARINATAG_SWITCH_FLAG_NONE 0x7F + typedef struct EnOkarinaTag { /* 0x000 */ Actor actor; /* 0x144 */ EnOkarinaTagActionFunc actionFunc; diff --git a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c index 4e666ed5c..eb6907c7c 100644 --- a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c +++ b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c @@ -102,7 +102,7 @@ void func_80B11F78(EnOnpuman* this, PlayState* play) { void func_80B1202C(EnOnpuman* this, PlayState* play2) { PlayState* play = play2; - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && (Message_ShouldAdvance(play))) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { switch (play->msgCtx.currentTextId) { case 0x8D4: this->unk_2A4 |= 1; @@ -138,7 +138,7 @@ void func_80B1202C(EnOnpuman* this, PlayState* play2) { } void func_80B1217C(EnOnpuman* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && (Message_ShouldAdvance(play))) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { this->actionFunc = func_80B121D8; Message_CloseTextbox(play); } diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.c b/src/overlays/actors/ovl_En_Raf/z_en_raf.c index 1c6a669a2..a7b7d9c13 100644 --- a/src/overlays/actors/ovl_En_Raf/z_en_raf.c +++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.c @@ -225,8 +225,8 @@ void EnRaf_Init(Actor* thisx, PlayState* play) { this->mainType = EN_RAF_GET_TYPE(&this->dyna.actor); this->reviveTimer = EN_RAF_GET_REVIVE_TIMER(&this->dyna.actor); this->switchFlag = EN_RAF_GET_SWITCH_FLAG(&this->dyna.actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == EN_RAF_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } if (this->reviveTimer == 31) { @@ -235,7 +235,7 @@ void EnRaf_Init(Actor* thisx, PlayState* play) { this->reviveTimer = 30; } - if (((this->switchFlag >= 0) || (this->mainType == EN_RAF_TYPE_DORMANT) || + if (((this->switchFlag > SWITCH_FLAG_NONE) || (this->mainType == EN_RAF_TYPE_DORMANT) || CHECK_WEEKEVENTREG(WEEKEVENTREG_12_01)) && (Flags_GetSwitch(play, this->switchFlag) || (this->mainType == EN_RAF_TYPE_DORMANT))) { s32 i; @@ -515,7 +515,7 @@ void EnRaf_Explode(EnRaf* this, PlayState* play) { CLEAR_TAG_PARAMS(CLEAR_TAG_SMALL_EXPLOSION)); Actor_PlaySfx(&this->dyna.actor, NA_SE_IT_BOMB_EXPLOSION); Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_SUISEN_DEAD); - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } @@ -579,7 +579,7 @@ void EnRaf_Convulse(EnRaf* this, PlayState* play) { if (this->endFrame <= curFrame) { this->chewCount++; if (this->chewCount > (BREG(2) + 2)) { - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.h b/src/overlays/actors/ovl_En_Raf/z_en_raf.h index a025046ab..ca6091233 100644 --- a/src/overlays/actors/ovl_En_Raf/z_en_raf.h +++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.h @@ -8,6 +8,8 @@ #define EN_RAF_GET_REVIVE_TIMER(thisx) (((thisx)->params >> 7) & 0x1F) #define EN_RAF_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) +#define EN_RAF_SWITCH_FLAG_NONE 0x7F + typedef enum { /* 0 */ EN_RAF_TYPE_NORMAL, /* 1 */ EN_RAF_TYPE_DORMANT, // Spawns without trap, so it can't eat bombs/player diff --git a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c index f7ec8f509..cd2b36634 100644 --- a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c +++ b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c @@ -1122,7 +1122,7 @@ void EnSGoro_WinterShrineGoron_Idle(EnSGoro* this, PlayState* play) { } void EnSGoro_WinterShrineGoron_Talk(EnSGoro* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && (Message_ShouldAdvance(play))) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { if (this->actionFlags & EN_S_GORO_ACTIONFLAG_LASTMESSAGE) { this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_LASTMESSAGE; this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_ENGAGED; @@ -1230,7 +1230,7 @@ void EnSGoro_ShopGoron_Talk(EnSGoro* this, PlayState* play) { this->textId = EnSGoro_BombshopGoron_NextTextId(this, play); Message_StartTextbox(play, this->textId, &this->actor); } - } else if ((talkState == TEXT_STATE_CHOICE) && (Message_ShouldAdvance(play))) { + } else if ((talkState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { switch (play->msgCtx.choiceIndex) { case 0: this->bombbuyFlags |= EN_S_GORO_BOMBBUYFLAG_YESBUY; diff --git a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c index 6a1b68bbc..99c5441a6 100644 --- a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c +++ b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c @@ -107,10 +107,10 @@ void EnStopheishi_Init(Actor* thisx, PlayState* play) { this->switchFlag = ENSTOPHEISHI_GET_SWITCH_FLAG(&this->actor); this->unk_288 = (this->actor.world.rot.z * 40.0f) + 50.0f; this->actor.world.rot.z = 0; - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == ENSTOPHEISHI_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } diff --git a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h index 651a66496..34cb9bf56 100644 --- a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h +++ b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h @@ -11,6 +11,8 @@ typedef void (*EnStopheishiActionFunc)(struct EnStopheishi*, PlayState*); #define ENSTOPHEISHI_GET_SWITCH_FLAG(thisx) (((thisx)->params) & 0x3F) #define ENSTOPHEISHI_GET_F000(thisx) ((((thisx)->params) >> 0xC) & 0xF) +#define ENSTOPHEISHI_SWITCH_FLAG_NONE 0x7F + typedef struct EnStopheishi { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c index 34ebe1d80..667f5d8c4 100644 --- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c +++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c @@ -264,11 +264,11 @@ void EnTalkGibud_Init(Actor* thisx, PlayState* play) { this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK; } - if (this->switchFlag == 0xFF) { - this->switchFlag = -1; + if (this->switchFlag == EN_TALK_GIBUD_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag != -1) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag != SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); } @@ -880,7 +880,7 @@ void EnTalkGibud_Disappear(EnTalkGibud* this, PlayState* play) { player->stateFlags1 |= PLAYER_STATE1_20000000; this->disappearanceTimer--; } else { - if (this->switchFlag != -1) { + if (this->switchFlag != SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } player->stateFlags1 &= ~PLAYER_STATE1_20; diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h index 06ccd3914..eb1121801 100644 --- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h +++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h @@ -7,6 +7,8 @@ #define EN_TALK_GIBUD_REQUESTED_ITEM_INDEX(thisx) ((thisx)->params & 0xF) #define EN_TALK_GIBUD_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF0) >> 4) +#define EN_TALK_GIBUD_SWITCH_FLAG_NONE 0xFF + struct EnTalkGibud; typedef void (*EnTalkGibudActionFunc)(struct EnTalkGibud*, PlayState*); diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c index 8ae7b0de4..c44ec1442 100644 --- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c +++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c @@ -339,8 +339,8 @@ void EnWiz_Init(Actor* thisx, PlayState* play) { this->switchFlag = EN_WIZ_GET_SWITCH_FLAG(&this->actor); this->type = EN_WIZ_GET_TYPE(&this->actor); - if (this->switchFlag == 0x7F) { - this->switchFlag = -1; + if (this->switchFlag == EN_WIZ_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } if ((this->type == EN_WIZ_TYPE_FIRE) || (this->type == EN_WIZ_TYPE_FIRE_NO_BGM)) { @@ -352,7 +352,7 @@ void EnWiz_Init(Actor* thisx, PlayState* play) { this->actor.colChkInfo.health = 6; } - if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) { + if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->actor); return; } @@ -1201,7 +1201,7 @@ void EnWiz_Dead(EnWiz* this, PlayState* play) { EnWiz_SelectPlatform(this, play); SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 50, NA_SE_EN_EXTINCT); Actor_Kill(&this->actor); - if (this->switchFlag >= 0) { + if (this->switchFlag > SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } } diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h index fa7156fc5..ea17a254d 100644 --- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h +++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h @@ -7,6 +7,8 @@ #define EN_WIZ_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) #define EN_WIZ_GET_TYPE(thisx) (((thisx)->params >> 8) & 0xFF) +#define EN_WIZ_SWITCH_FLAG_NONE 0x7F + typedef enum { /* 0 */ EN_WIZ_TYPE_FIRE, /* 1 */ EN_WIZ_TYPE_ICE, diff --git a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c index a809da57a..ba4782d02 100644 --- a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c +++ b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c @@ -33,7 +33,7 @@ void ObjDemo_Init(Actor* thisx, PlayState* play) { ObjDemo* this = THIS; thisx->params = OBJDEMO_GET_SWITCH_FLAG_MASK(thisx); - if ((OBJDEMO_GET_SWITCH_FLAG(thisx) != 0xFF) && (Flags_GetSwitch(play, OBJDEMO_GET_SWITCH_FLAG(thisx)))) { + if ((OBJDEMO_GET_SWITCH_FLAG(thisx) != 0xFF) && Flags_GetSwitch(play, OBJDEMO_GET_SWITCH_FLAG(thisx))) { Actor_Kill(&this->actor); return; } diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c index 8802a257d..a76476bde 100644 --- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c +++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c @@ -115,11 +115,11 @@ void ObjHakaisi_Init(Actor* thisx, PlayState* play) { this->switchFlag = OBJHAKAISI_GET_SWITCH_FLAG(thisx); this->csId = this->dyna.actor.csId; - if (this->switchFlag == 0xFF) { - this->switchFlag = -1; + if (this->switchFlag == OBJHAKAISI_SWITCH_FLAG_NONE) { + this->switchFlag = SWITCH_FLAG_NONE; } - if ((this->switchFlag != -1) && Flags_GetSwitch(play, this->switchFlag)) { + if ((this->switchFlag != SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { Actor_Kill(&this->dyna.actor); } diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h index 7ee84768a..937b3d64e 100644 --- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h +++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h @@ -10,6 +10,8 @@ typedef void (*ObjHakaisiActionFunc)(struct ObjHakaisi*, PlayState*); #define OBJHAKAISI_GET_FF(thisx) ((thisx)->params & 0xFF) #define OBJHAKAISI_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF00) >> 8) +#define OBJHAKAISI_SWITCH_FLAG_NONE 0xFF + typedef struct ObjHakaisi { /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ ObjHakaisiActionFunc actionFunc; diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c index 8df527f37..c98645d17 100644 --- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c +++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c @@ -115,7 +115,7 @@ void ObjIcePoly_Init(Actor* thisx, PlayState* play) { thisx->shape.rot.x = 0x500; thisx->shape.rot.z = -0x500; - if (((this->switchFlag != 0xFF) && Flags_GetSwitch(play, this->switchFlag)) || + if (((this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) || ((play->sceneId == SCENE_KAJIYA) && CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE))) { Actor_Kill(thisx); return; @@ -219,7 +219,7 @@ void func_80931A38(ObjIcePoly* this, PlayState* play) { } } while (actor != NULL); } - } else if ((this->switchFlag != 0xFF) && Flags_GetSwitch(play, this->switchFlag)) { + } else if ((this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) { CutsceneManager_Queue(this->actor.csId); this->unk_14A = 1; this->actionFunc = func_80931E58; @@ -328,7 +328,7 @@ void func_80931EEC(ObjIcePoly* this, PlayState* play) { if (this->unk_14A == 0) { CutsceneManager_Stop(this->actor.csId); - if (this->switchFlag != 0xFF) { + if (this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) { Flags_SetSwitch(play, this->switchFlag); } Actor_Kill(&this->actor); diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h index 3e59cd92e..acf62bb91 100644 --- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h +++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h @@ -9,6 +9,8 @@ typedef void (*ObjIcePolyActionFunc)(struct ObjIcePoly*, PlayState*); #define OBJICEPOLY_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0xFF) +#define OBJICEPOLY_SWITCH_FLAG_NONE 0xFF + typedef struct ObjIcePoly { /* 0x000 */ Actor actor; /* 0x144 */ ObjIcePolyActionFunc actionFunc; diff --git a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c index 9e92dcb11..61822bde7 100644 --- a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c +++ b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c @@ -101,7 +101,7 @@ void ObjLift_Init(Actor* thisx, PlayState* play) { this->unk_178 = this->dyna.actor.home.rot.z; this->dyna.actor.home.rot.z = this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z; DynaPolyActor_Init(&this->dyna, DYNA_TRANSFORM_POS); - if ((this->unk_178 <= 0) && (Flags_GetSwitch(play, OBJLIFT_GET_SWITCH_FLAG(&this->dyna.actor)))) { + if ((this->unk_178 <= 0) && Flags_GetSwitch(play, OBJLIFT_GET_SWITCH_FLAG(&this->dyna.actor))) { Actor_Kill(&this->dyna.actor); return; } diff --git a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c index b5ba51418..569a6e6f2 100644 --- a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c +++ b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c @@ -75,7 +75,7 @@ void ObjOcarinalift_Init(Actor* thisx, PlayState* play) { this->unk170 = Lib_SegmentedToVirtual(path->points); func_80AC94C0(this, this->unk168); if ((OBJOCARINALIFT_GET_C(&this->dyna.actor) != OBJOCARINALIFT_PARAM_1) && - (Flags_GetSwitch(play, OBJOCARINALIFT_GET_SWITCH_FLAG(&this->dyna.actor)))) { + Flags_GetSwitch(play, OBJOCARINALIFT_GET_SWITCH_FLAG(&this->dyna.actor))) { func_80AC96B4(this); } else { func_80AC9AB8(this); diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c index cbd94d808..43bf3cb21 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -105,8 +105,8 @@ void ObjSyokudai_Init(Actor* thisx, PlayState* play) { this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); if (OBJ_SYOKUDAI_GET_START_LIT(thisx) || - ((type != OBJ_SYOKUDAI_TYPE_NO_SWITCH || switchFlag != 0x7F) && Flags_GetSwitch(play, switchFlag))) { - + (((type != OBJ_SYOKUDAI_TYPE_NO_SWITCH) || (switchFlag != OBJ_SYOKUDAI_SWITCH_FLAG_NONE)) && + Flags_GetSwitch(play, switchFlag))) { s32 groupSize = OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx); this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; @@ -239,7 +239,7 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) { player->unk_B28 = 0xC8; } if (groupSize == 0) { - if ((type == OBJ_SYOKUDAI_TYPE_NO_SWITCH) && (switchFlag == 0x7F)) { + if ((type == OBJ_SYOKUDAI_TYPE_NO_SWITCH) && (switchFlag == OBJ_SYOKUDAI_SWITCH_FLAG_NONE)) { this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; } else if (thisx->csId >= 0) { this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH; @@ -267,9 +267,11 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->standCollider.base); Collider_UpdateCylinder(thisx, &this->flameCollider); CollisionCheck_SetAC(play, &play->colChkCtx, &this->flameCollider.base); - if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) && (--this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) && - (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) { - sNumLitTorchesInGroup--; + if (this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) { + this->snuffTimer--; + if ((this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) && (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) { + sNumLitTorchesInGroup--; + } } if (this->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT) { s32 pad2; diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h index d49f38289..2ea8dc2fc 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h @@ -5,6 +5,13 @@ struct ObjSyokudai; +#define OBJ_SYOKUDAI_GET_TYPE(thisx) ((thisx)->params >> 0xC) +#define OBJ_SYOKUDAI_GET_START_LIT(thisx) ((thisx)->params & 0x800) +#define OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx) (((thisx)->params >> 7) & 0xF) +#define OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) + +#define OBJ_SYOKUDAI_SWITCH_FLAG_NONE 0x7F + typedef struct ObjSyokudai { /* 0x000 */ Actor actor; /* 0x144 */ ColliderCylinder standCollider; @@ -48,11 +55,6 @@ typedef enum { #define OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS 10 #define OBJ_SYOKUDAI_LIGHT_RADIUS_MAX 250 -#define OBJ_SYOKUDAI_GET_TYPE(thisx) ((thisx)->params >> 0xC) -#define OBJ_SYOKUDAI_GET_START_LIT(thisx) ((thisx)->params & 0x800) -#define OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx) (((thisx)->params >> 7) & 0xF) -#define OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) - #define OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize) ((groupSize * 50) + 100) #endif // Z_OBJ_SYOKUDAI_H From 9e5777e473225436803a1ec2325b099963083ee5 Mon Sep 17 00:00:00 2001 From: Nuss <67802335+hack-nuss@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:02:31 +0200 Subject: [PATCH 8/9] object_po (#1426) * naming * typos and sLimbToBodyParts * POE_LIMB_MAX instead of 21 * typos * EnumName * prefix --- assets/xml/objects/object_po.xml | 110 ++++++++++++---------- src/overlays/actors/ovl_En_Poh/z_en_poh.c | 94 +++++++++--------- src/overlays/actors/ovl_En_Poh/z_en_poh.h | 29 +++--- 3 files changed, 122 insertions(+), 111 deletions(-) diff --git a/assets/xml/objects/object_po.xml b/assets/xml/objects/object_po.xml index 98dbc61b1..a430d178b 100644 --- a/assets/xml/objects/object_po.xml +++ b/assets/xml/objects/object_po.xml @@ -1,53 +1,65 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 1c301a8bf..f0109b40a 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -7,7 +7,6 @@ #include "prevent_bss_reordering.h" #include "z_en_poh.h" #include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h" -#include "objects/object_po/object_po.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_200 | ACTOR_FLAG_IGNORE_QUAKE) @@ -167,8 +166,7 @@ void EnPoh_Init(Actor* thisx, PlayState* play) { this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); Lights_PointGlowSetInfo(&this->lightInfo, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, 255, 255, 255, 0); - SkelAnime_Init(play, &this->skelAnime, &object_po_Skel_0050D0, &object_po_Anim_000A60, this->jointTable, - this->morphTable, 21); + SkelAnime_Init(play, &this->skelAnime, &gPoeSkel, &gPoeFloatAnim, this->jointTable, this->morphTable, POE_LIMB_MAX); this->actor.bgCheckFlags |= BGCHECKFLAG_PLAYER_400; func_80B2D0E8(this); } @@ -215,7 +213,7 @@ void func_80B2C9B8(EnPoh* this, PlayState* play) { } void func_80B2CA4C(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0); + Animation_PlayLoop(&this->skelAnime, &gPoeDisappearAnim); this->unk_18E = Rand_S16Offset(2, 3); this->actionFunc = func_80B2CAA4; this->actor.speed = 0.0f; @@ -241,7 +239,7 @@ void func_80B2CAA4(EnPoh* this, PlayState* play) { } void func_80B2CB60(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60); + Animation_PlayLoop(&this->skelAnime, &gPoeFloatAnim); this->unk_18E = Rand_S16Offset(15, 3); this->colliderCylinder.base.acFlags |= AC_ON; this->actionFunc = func_80B2CBBC; @@ -276,7 +274,7 @@ void func_80B2CBBC(EnPoh* this, PlayState* play) { } void func_80B2CD14(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60); + Animation_PlayLoop(&this->skelAnime, &gPoeFloatAnim); this->actionFunc = func_80B2CD64; this->unk_18E = 0; this->actor.speed = 2.0f; @@ -315,7 +313,7 @@ void func_80B2CD64(EnPoh* this, PlayState* play) { } void func_80B2CEC8(EnPoh* this) { - Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0001A8, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &gPoeAttackAnim, -6.0f); this->unk_18E = 12; this->actor.speed = 0.0f; Actor_PlaySfx(&this->actor, NA_SE_EN_PO_LAUGH); @@ -344,7 +342,7 @@ void func_80B2CF28(EnPoh* this, PlayState* play) { } void func_80B2CFF8(EnPoh* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &object_po_Anim_0004EC, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gPoeDamagedAnim, -6.0f); func_800BE504(&this->actor, &this->colliderCylinder); this->colliderCylinder.base.acFlags &= ~AC_ON; this->actor.speed = 5.0f; @@ -366,7 +364,7 @@ void func_80B2D07C(EnPoh* this, PlayState* play) { void func_80B2D0E8(EnPoh* this) { this->unk_197 = 0; this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; - Animation_PlayOnceSetSpeed(&this->skelAnime, &object_po_Anim_0011C4, 0.0f); + Animation_PlayOnceSetSpeed(&this->skelAnime, &gPoeAppearAnim, 0.0f); this->actionFunc = func_80B2D140; } @@ -445,7 +443,7 @@ void func_80B2D300(EnPoh* this, PlayState* play) { } void func_80B2D5DC(EnPoh* this) { - Animation_PlayOnce(&this->skelAnime, &object_po_Anim_000A60); + Animation_PlayOnce(&this->skelAnime, &gPoeFloatAnim); this->actionFunc = func_80B2D628; this->actor.speed = -5.0f; } @@ -462,7 +460,7 @@ void func_80B2D628(EnPoh* this, PlayState* play) { } void func_80B2D694(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0); + Animation_PlayLoop(&this->skelAnime, &gPoeDisappearAnim); this->unk_192 = BINANG_ROT180(this->actor.world.rot.y); this->actionFunc = func_80B2D6EC; this->actor.speed = 0.0f; @@ -540,7 +538,7 @@ void func_80B2D980(EnPoh* this, PlayState* play) { } void func_80B2DAD0(EnPoh* this) { - Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0006E0, -5.0f); + Animation_MorphToLoop(&this->skelAnime, &gPoeFleeAnim, -5.0f); this->actor.speed = 5.0f; this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); this->colliderCylinder.base.acFlags |= AC_ON; @@ -585,7 +583,7 @@ void func_80B2DC50(EnPoh* this, PlayState* play) { void func_80B2DD2C(EnPoh* this, PlayState* play) { if ((this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) || (this->actor.floorHeight <= BGCHECK_Y_MIN)) { - EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, object_po_DL_002D28); + EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, gPoeLanternDL); func_80B2E0B0(this); } @@ -864,34 +862,34 @@ s32 EnPoh_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p return false; } -static s8 sLimbToBodyParts[OBJECT_PO_LIMB_MAX] = { - BODYPART_NONE, // OBJECT_PO_LIMB_NONE - BODYPART_NONE, // OBJECT_PO_LIMB_01 - BODYPART_NONE, // OBJECT_PO_LIMB_02 - BODYPART_NONE, // OBJECT_PO_LIMB_03 - ENPOH_BODYPART_4, // OBJECT_PO_LIMB_04 - ENPOH_BODYPART_5, // OBJECT_PO_LIMB_05 - BODYPART_NONE, // OBJECT_PO_LIMB_06 - BODYPART_NONE, // OBJECT_PO_LIMB_07 - BODYPART_NONE, // OBJECT_PO_LIMB_08 - ENPOH_BODYPART_0, // OBJECT_PO_LIMB_09 - ENPOH_BODYPART_1, // OBJECT_PO_LIMB_0A - BODYPART_NONE, // OBJECT_PO_LIMB_0B - BODYPART_NONE, // OBJECT_PO_LIMB_0C - BODYPART_NONE, // OBJECT_PO_LIMB_0D - BODYPART_NONE, // OBJECT_PO_LIMB_0E - BODYPART_NONE, // OBJECT_PO_LIMB_0F - ENPOH_BODYPART_2, // OBJECT_PO_LIMB_10 - BODYPART_NONE, // OBJECT_PO_LIMB_11 - BODYPART_NONE, // OBJECT_PO_LIMB_12 - ENPOH_BODYPART_3, // OBJECT_PO_LIMB_13 - BODYPART_NONE, // OBJECT_PO_LIMB_14 +static s8 sLimbToBodyParts[POE_LIMB_MAX] = { + BODYPART_NONE, // POE_LIMB_NONE + BODYPART_NONE, // POE_LIMB_ROOT + BODYPART_NONE, // POE_LIMB_ROOT_WRAPPER + BODYPART_NONE, // POE_LIMB_BOTTOM_CLOAK_ROOT + POE_BODYPART_BOTTOM_CLOAK, // POE_LIMB_BOTTOM_CLOAK + POE_BODYPART_TOP_CLOAK, // POE_LIMB_TOP_CLOAK + BODYPART_NONE, // POE_LIMB_LEFT_ARM_ROOT + BODYPART_NONE, // POE_LIMB_LEFT_ARM_WRAPPER + BODYPART_NONE, // POE_LIMB_LEFT_FOREARM_ROOT + POE_BODYPART_LEFT_FOREARM, // POE_LIMB_LEFT_FOREARM + POE_BODYPART_LEFT_UPPER_ARM, // POE_LIMB_LEFT_UPPER_ARM + BODYPART_NONE, // POE_LIMB_FACE + BODYPART_NONE, // POE_LIMB_RIGHT_ARM_ROOT + BODYPART_NONE, // POE_LIMB_RIGHT_ARM_WRAPPER + BODYPART_NONE, // POE_LIMB_RIGHT_FOREARM_ROOT + BODYPART_NONE, // POE_LIMB_RIGHT_ARM_HAND_ROOT + POE_BODYPART_RIGHT_ARM_HAND, // POE_LIMB_RIGHT_ARM_HAND + BODYPART_NONE, // POE_LIMB_LANTERN_ROOT + BODYPART_NONE, // POE_LIMB_LANTERN + POE_BODYPART_RIGHT_FOREARM, // POE_LIMB_RIGHT_FOREARM + BODYPART_NONE, // POE_LIMB_RIGHT_UPPER_ARM }; static Vec3f D_80B2F734[] = { - { -600.0f, 500.0f, 1700.0f }, // ENPOH_BODYPART_7 - { -600.0f, 500.0f, -1700.0f }, // ENPOH_BODYPART_8 - { 1000.0f, 1700.0f, 0.0f }, // ENPOH_BODYPART_9 + { -600.0f, 500.0f, 1700.0f }, // POE_BODYPART_7 + { -600.0f, 500.0f, -1700.0f }, // POE_BODYPART_8 + { 1000.0f, 1700.0f, 0.0f }, // POE_BODYPART_9 }; void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { @@ -903,7 +901,7 @@ void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Collider_UpdateSpheres(limbIndex, &this->colliderSph); if ((this->actionFunc == func_80B2D300) && (this->unk_18E >= 2) && (limbIndex == 5)) { gSPMatrix((*gfx)++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList((*gfx)++, object_po_DL_002608); + gSPDisplayList((*gfx)++, gPoeBurnDL); } if (limbIndex == 18) { @@ -921,19 +919,19 @@ void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, bodyPartIndex = sLimbToBodyParts[limbIndex]; if (bodyPartIndex != BODYPART_NONE) { - if (bodyPartIndex <= ENPOH_BODYPART_3) { + if (bodyPartIndex <= POE_BODYPART_RIGHT_FOREARM) { Matrix_MultZero(&this->bodyPartsPos[bodyPartIndex]); - } else if (bodyPartIndex == ENPOH_BODYPART_4) { + } else if (bodyPartIndex == POE_BODYPART_BOTTOM_CLOAK) { Matrix_MultVecX(2000.0f, &this->bodyPartsPos[bodyPartIndex]); } else { s32 i; Vec3f* vec = &this->bodyPartsPos[bodyPartIndex + 2]; Vec3f* vec2 = &D_80B2F734[0]; - Matrix_MultVecX(-2000.0f, &this->bodyPartsPos[bodyPartIndex]); // ENPOH_BODYPART_5 - Matrix_MultVecY(-2000.0f, &this->bodyPartsPos[bodyPartIndex + 1]); // ENPOH_BODYPART_6 + Matrix_MultVecX(-2000.0f, &this->bodyPartsPos[bodyPartIndex]); // POE_BODYPART_TOP_CLOAK + Matrix_MultVecY(-2000.0f, &this->bodyPartsPos[bodyPartIndex + 1]); // POE_BODYPART_6 - for (i = bodyPartIndex + 2; i < ENPOH_BODYPART_MAX; i++, vec++, vec2++) { + for (i = bodyPartIndex + 2; i < POE_BODYPART_MAX; i++, vec++, vec2++) { Matrix_MultVec3f(vec2, vec); } } @@ -978,10 +976,10 @@ void EnPoh_Draw(Actor* thisx, PlayState* play) { Matrix_Put(&this->unk_3D8); gSPMatrix(&gfx[2], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&gfx[3], object_po_DL_002D28); + gSPDisplayList(&gfx[3], gPoeLanternDL); POLY_OPA_DISP = &gfx[4]; - Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, ENPOH_BODYPART_MAX, + Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, POE_BODYPART_MAX, this->actor.scale.x * 100.0f * this->drawDmgEffScale, 0.0f, this->drawDmgEffAlpha, ACTOR_DRAW_DMGEFF_LIGHT_ORBS); @@ -1018,7 +1016,7 @@ void func_80B2F37C(Actor* thisx, PlayState* play) { this->actor.world.pos.z + sp7C.z, this->unk_198, this->unk_199, this->unk_19A, 200); gSPMatrix(&gfx[2], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&gfx[3], object_po_DL_002D28); + gSPDisplayList(&gfx[3], gPoeLanternDL); POLY_OPA_DISP = &gfx[4]; } else { @@ -1033,7 +1031,7 @@ void func_80B2F37C(Actor* thisx, PlayState* play) { Matrix_RotateYF(BINANG_TO_RAD(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000), 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_po_DL_003850); + gSPDisplayList(POLY_XLU_DISP++, gPoeSoulDL); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/src/overlays/actors/ovl_En_Poh/z_en_poh.h index 5f7439e4a..7c3e47eed 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.h +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.h @@ -2,23 +2,24 @@ #define Z_EN_POH_H #include "global.h" +#include "objects/object_po/object_po.h" struct EnPoh; typedef void (*EnPohActionFunc)(struct EnPoh*, PlayState*); typedef enum EnPohBodyPart { - /* 0 */ ENPOH_BODYPART_0, - /* 1 */ ENPOH_BODYPART_1, - /* 2 */ ENPOH_BODYPART_2, - /* 3 */ ENPOH_BODYPART_3, - /* 4 */ ENPOH_BODYPART_4, - /* 5 */ ENPOH_BODYPART_5, - /* 6 */ ENPOH_BODYPART_6, - /* 7 */ ENPOH_BODYPART_7, - /* 8 */ ENPOH_BODYPART_8, - /* 9 */ ENPOH_BODYPART_9, - /* 10 */ ENPOH_BODYPART_MAX + /* 0 */ POE_BODYPART_LEFT_FOREARM, + /* 1 */ POE_BODYPART_LEFT_UPPER_ARM, + /* 2 */ POE_BODYPART_RIGHT_ARM_HAND, + /* 3 */ POE_BODYPART_RIGHT_FOREARM, + /* 4 */ POE_BODYPART_BOTTOM_CLOAK, + /* 5 */ POE_BODYPART_TOP_CLOAK, + /* 6 */ POE_BODYPART_6, + /* 7 */ POE_BODYPART_7, + /* 8 */ POE_BODYPART_8, + /* 9 */ POE_BODYPART_9, + /* 10 */ POE_BODYPART_MAX } EnPohBodyPart; typedef struct EnPoh { @@ -38,11 +39,11 @@ typedef struct EnPoh { /* 0x199 */ u8 unk_199; /* 0x19A */ u8 unk_19A; /* 0x19B */ u8 unk_19B; - /* 0x19C */ Vec3s jointTable[21]; - /* 0x21A */ Vec3s morphTable[21]; + /* 0x19C */ Vec3s jointTable[POE_LIMB_MAX]; + /* 0x21A */ Vec3s morphTable[POE_LIMB_MAX]; /* 0x298 */ f32 drawDmgEffAlpha; /* 0x29C */ f32 drawDmgEffScale; - /* 0x2A0 */ Vec3f bodyPartsPos[ENPOH_BODYPART_MAX]; + /* 0x2A0 */ Vec3f bodyPartsPos[POE_BODYPART_MAX]; /* 0x318 */ LightNode* lightNode; /* 0x31C */ LightInfo lightInfo; /* 0x32C */ ColliderCylinder colliderCylinder; From 1d3f38dcaae480b7dc7f22ab75e606492583f9d1 Mon Sep 17 00:00:00 2001 From: Nuss <67802335+hack-nuss@users.noreply.github.com> Date: Mon, 16 Oct 2023 00:01:04 +0200 Subject: [PATCH 9/9] object_zoraegg (#1439) * naming * improvements * bss order --- assets/xml/objects/object_zoraegg.xml | 74 +++++++++++-------- .../actors/ovl_En_Zoraegg/z_en_zoraegg.c | 50 ++++++------- .../actors/ovl_En_Zoraegg/z_en_zoraegg.h | 9 ++- .../actors/ovl_player_actor/z_player.c | 1 + 4 files changed, 74 insertions(+), 60 deletions(-) diff --git a/assets/xml/objects/object_zoraegg.xml b/assets/xml/objects/object_zoraegg.xml index 175c6aeb2..0fd05641d 100644 --- a/assets/xml/objects/object_zoraegg.xml +++ b/assets/xml/objects/object_zoraegg.xml @@ -1,34 +1,48 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c index 6440493cf..099f75a57 100644 --- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c +++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c @@ -6,7 +6,6 @@ #include "z_en_zoraegg.h" #include "objects/gameplay_keep/gameplay_keep.h" -#include "objects/object_zoraegg/object_zoraegg.h" #define FLAGS (ACTOR_FLAG_10) @@ -81,9 +80,9 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) { }; Actor_SetScale(&this->actor, 0.006f); - SkelAnime_InitFlex(play, &this->skelAnime, &object_zoraegg_Skel_004C90, &object_zoraegg_Anim_005098, - this->jointTable, this->morphTable, 7); - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_005098); + SkelAnime_InitFlex(play, &this->skelAnime, &gZoraBabySkel, &gZoraBabySwimAnim, this->jointTable, this->morphTable, + ZORA_BABY_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gZoraBabySwimAnim); ActorShape_Init(&this->actor.shape, 1100.0f, NULL, 0.0f); this->actionFunc = func_80B32084; @@ -166,7 +165,7 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) { case ZORA_EGG_TYPE_08: case ZORA_EGG_TYPE_09: this->cueType = cueTypes[ZORA_EGG_GET_TYPE(&this->actor) - ZORA_EGG_TYPE_03]; - Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_001E08); + Animation_PlayOnce(&this->skelAnime, &gZoraBabyHatchAnim); this->unk_1EC = 1; this->unk_1EE = 0; this->unk_1EF = 0; @@ -187,7 +186,7 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) { this->cueType = cueTypes[ZORA_EGG_GET_TYPE(&this->actor) - ZORA_EGG_TYPE_0A]; this->unk_1EC = 2; this->actionFunc = func_80B324B0; - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim); this->unk_1EE = 0; this->unk_1ED = 0; this->unk_1EA |= 3; @@ -426,13 +425,13 @@ void func_80B324B0(EnZoraegg* this, PlayState* play) { if (this->unk_1EA & 4) { if (Cutscene_IsCueInChannel(play, this->cueType) && (play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 3)) { - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim); this->unk_1EA &= ~4; } } else { if (Cutscene_IsCueInChannel(play, this->cueType) && (play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 4)) { - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004E04); + Animation_PlayLoop(&this->skelAnime, &gZoraBabySongLearnedAnim); this->unk_1EA |= 4; } } @@ -444,14 +443,14 @@ void func_80B324B0(EnZoraegg* this, PlayState* play) { this->unk_1E4 = Rand_ZeroFloat(5.0f); } } else if (this->unk_1EA & 4) { - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim); this->unk_1EA &= ~4; } } void func_80B32644(EnZoraegg* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { - Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim); this->unk_1EE = 0; this->unk_1EA |= 2; } @@ -474,8 +473,8 @@ void func_80B326F4(EnZoraegg* this, PlayState* play) { if (Cutscene_IsCueInChannel(play, this->cueType) && (play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 3)) { - Animation_Change(&this->skelAnime, &object_zoraegg_Anim_004D20, 1.0f, 0.0f, - Animation_GetLastFrame(&object_zoraegg_Anim_004D20), ANIMMODE_ONCE, 5.0f); + Animation_Change(&this->skelAnime, &gZoraBabyFormNoteAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gZoraBabyFormNoteAnim), ANIMMODE_ONCE, 5.0f); this->unk_1E8 = 0; this->actionFunc = func_80B32644; SET_WEEKEVENTREG(WEEKEVENTREG_19_40); @@ -495,14 +494,14 @@ void func_80B32820(EnZoraegg* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { if (this->unk_1E8 >= 2) { this->actionFunc = func_80B326F4; - Animation_Change(&this->skelAnime, &object_zoraegg_Anim_005098, 1.0f, 0.0f, - Animation_GetLastFrame(&object_zoraegg_Anim_005098), ANIMMODE_LOOP, 10.0f); + Animation_Change(&this->skelAnime, &gZoraBabySwimAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gZoraBabySwimAnim), ANIMMODE_LOOP, 10.0f); this->unk_1E8 = 0; SkelAnime_Update(&this->skelAnime); return; } - Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4); + Animation_PlayOnce(&this->skelAnime, &gZoraBabySwimUpAnim); this->unk_1E8 += 1; SkelAnime_Update(&this->skelAnime); } @@ -520,7 +519,7 @@ void func_80B32928(EnZoraegg* this, PlayState* play) { } if (SkelAnime_Update(&this->skelAnime)) { - Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4); + Animation_PlayOnce(&this->skelAnime, &gZoraBabySwimUpAnim); this->unk_1EA |= 1; this->actionFunc = func_80B32820; this->unk_1E8 = 0; @@ -653,13 +652,13 @@ void EnZoraegg_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); - if (DECR(this->unk_1F4) == 0) { - this->unk_1F4 = Rand_S16Offset(60, 60); + if (DECR(this->blinkTimer) == 0) { + this->blinkTimer = Rand_S16Offset(60, 60); } - this->unk_1F2 = this->unk_1F4; - if (this->unk_1F2 >= 3) { - this->unk_1F2 = 0; + this->eyeIndex = this->blinkTimer; + if (this->eyeIndex >= 3) { + this->eyeIndex = 0; } } @@ -730,14 +729,14 @@ void func_80B331C8(Actor* thisx, PlayState* play) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); - gSPDisplayList(POLY_OPA_DISP++, object_zoraegg_DL_005250); + gSPDisplayList(POLY_OPA_DISP++, gZoraEggDL); } else { Gfx_SetupDL72(POLY_XLU_DISP++); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1ED); - gSPDisplayList(POLY_XLU_DISP++, object_zoraegg_DL_005250); + gSPDisplayList(POLY_XLU_DISP++, gZoraEggDL); } Matrix_Pop(); @@ -856,16 +855,15 @@ void EnZoraegg_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* } } -TexturePtr D_80B33950[] = { object_zoraegg_Tex_003430, object_zoraegg_Tex_004430, object_zoraegg_Tex_004830 }; - void func_80B33818(Actor* thisx, PlayState* play) { + static TexturePtr sZoraBabyEyeTextures[] = { gZoraBabyEyeOpenTex, gZoraBabyEyeHalfTex, gZoraBabyEyeClosedTex }; EnZoraegg* this = THIS; OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL25_Opa(play->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B33950[this->unk_1F2])); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sZoraBabyEyeTextures[this->eyeIndex])); SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnZoraegg_OverrideLimbDraw, EnZoraegg_PostLimbDraw, &this->actor); diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h index 84fce59df..a74c5a4c8 100644 --- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h +++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h @@ -2,6 +2,7 @@ #define Z_EN_ZORAEGG_H #include "global.h" +#include "objects/object_zoraegg/object_zoraegg.h" struct EnZoraegg; @@ -44,8 +45,8 @@ typedef enum { typedef struct EnZoraegg { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; - /* 0x188 */ Vec3s jointTable[7]; - /* 0x1B2 */ Vec3s morphTable[7]; + /* 0x188 */ Vec3s jointTable[ZORA_BABY_LIMB_MAX]; + /* 0x1B2 */ Vec3s morphTable[ZORA_BABY_LIMB_MAX]; /* 0x1DC */ Actor* unk_1DC; /* 0x1E0 */ f32 unk_1E0; /* 0x1E4 */ f32 unk_1E4; @@ -56,8 +57,8 @@ typedef struct EnZoraegg { /* 0x1EE */ u8 unk_1EE; /* 0x1EF */ u8 unk_1EF; /* 0x1F0 */ u16 cueType; - /* 0x1F2 */ s16 unk_1F2; - /* 0x1F4 */ s16 unk_1F4; + /* 0x1F2 */ s16 eyeIndex; + /* 0x1F4 */ s16 blinkTimer; /* 0x1F8 */ EnZoraeggActionFunc actionFunc; } EnZoraegg; // size = 0x1FC diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index 6e19ae832..43021a023 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -4,6 +4,7 @@ * Description: Player */ +#include "prevent_bss_reordering.h" #include "global.h" #include "z64horse.h" #include "z64quake.h"