diff --git a/assets/xml/objects/object_kaizoku_obj.xml b/assets/xml/objects/object_kaizoku_obj.xml
index 6a7457e1c..9ae61accf 100644
--- a/assets/xml/objects/object_kaizoku_obj.xml
+++ b/assets/xml/objects/object_kaizoku_obj.xml
@@ -7,13 +7,13 @@
-
-
+
+
-
-
+
+
diff --git a/spec b/spec
index 52dfd5ba8..a960b8f6d 100644
--- a/spec
+++ b/spec
@@ -4135,8 +4135,7 @@ beginseg
name "ovl_Obj_Y2shutter"
compress
include "build/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.o"
- include "build/data/ovl_Obj_Y2shutter/ovl_Obj_Y2shutter.data.o"
- include "build/data/ovl_Obj_Y2shutter/ovl_Obj_Y2shutter.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Y2shutter/ovl_Obj_Y2shutter_reloc.o"
endseg
beginseg
diff --git a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c
index 6b67bc068..b8110ce6a 100644
--- a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c
+++ b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c
@@ -1,10 +1,11 @@
/*
* File: z_obj_y2shutter.c
* Overlay: ovl_Obj_Y2shutter
- * Description: Pirates' Fortress sliding grate
+ * Description: Pirates' Fortress sliding grated/barred shutters
*/
#include "z_obj_y2shutter.h"
+#include "objects/object_kaizoku_obj/object_kaizoku_obj.h"
#define FLAGS (ACTOR_FLAG_10)
@@ -15,7 +16,19 @@ void ObjY2shutter_Destroy(Actor* thisx, PlayState* play);
void ObjY2shutter_Update(Actor* thisx, PlayState* play);
void ObjY2shutter_Draw(Actor* thisx, PlayState* play);
-#if 0
+typedef struct ShutterInfo {
+ /* 0x00 */ Gfx* dList;
+ /* 0x04 */ CollisionHeader* colHeader;
+ /* 0x08 */ f32 openedOffsetY;
+ /* 0x0C */ f32 openVelocity;
+ /* 0x10 */ f32 openAccel;
+ /* 0x14 */ f32 closeVelocity;
+ /* 0x18 */ f32 closeAccel;
+ /* 0x1C */ u8 openStartSettleTimer;
+ /* 0x1D */ u8 openEndAndCloseSettleTimer;
+ /* 0x1E */ u8 openTimer;
+} ShutterInfo; // size = 0x20
+
const ActorInit Obj_Y2shutter_InitVars = {
ACTOR_OBJ_Y2SHUTTER,
ACTORCAT_BG,
@@ -28,24 +41,136 @@ const ActorInit Obj_Y2shutter_InitVars = {
(ActorFunc)ObjY2shutter_Draw,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80B9AEB0[] = {
+ShutterInfo sShutterInfo[] = {
+ { gPirateBarredShutterDL, &gPirateBarredShutterCol, 120.0f, 20.0f, 3.0f, -20.0f, 3.0f, 4, 8, 160 },
+ { gPirateGratedShutterDL, &gPirateGratedShutterCol, 150.0f, 1.0f, 0.04f, -1.0f, 0.04f, 6, 12, 160 },
+};
+
+static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP),
};
-#endif
+void ObjY2shutter_Init(Actor* thisx, PlayState* play) {
+ s32 pad[2];
+ ShutterInfo* info = &sShutterInfo[OBJY2SHUTTER_GET_TYPE(thisx)];
+ ObjY2shutter* this = THIS;
-extern InitChainEntry D_80B9AEB0[];
+ Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
+ DynaPolyActor_Init(&this->dyna, 0);
+ DynaPolyActor_LoadMesh(play, &this->dyna, info->colHeader);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Y2shutter/ObjY2shutter_Init.s")
+void ObjY2shutter_Destroy(Actor* thisx, PlayState* play) {
+ ObjY2shutter* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Y2shutter/ObjY2shutter_Destroy.s")
+ DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Y2shutter/func_80B9AA20.s")
+void ObjY2shutter_SetupOpen(ObjY2shutter* this, ShutterInfo* info, ShutterType shutterType) {
+ this->openTimer = info->openTimer;
+ this->settleTimer = info->openStartSettleTimer;
+ if (shutterType == SHUTTER_BARRED) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_METALDOOR_OPEN);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Y2shutter/ObjY2shutter_Update.s")
+void ObjY2shutter_Update(Actor* thisx, PlayState* play) {
+ s32 pad;
+ ObjY2shutter* this = THIS;
+ ShutterType shutterType = OBJY2SHUTTER_GET_TYPE(&this->dyna.actor);
+ ShutterInfo* info = &sShutterInfo[shutterType];
+ f32 targetPosY = this->dyna.actor.world.pos.y;
+ f32 targetVelocityY = 0.0f;
+ f32 accelY = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Y2shutter/ObjY2shutter_Draw.s")
+ sShutterInfo[0].openTimer = DREG(84) + 160;
+ sShutterInfo[1].openTimer = DREG(85) + 160;
+
+ if (((shutterType == SHUTTER_BARRED) && (DREG(86) != 0)) || ((shutterType != SHUTTER_BARRED) && (DREG(87) != 0))) {
+ if (shutterType == SHUTTER_BARRED) {
+ DREG(86) = 0;
+ } else {
+ DREG(87) = 0;
+ }
+
+ if (Flags_GetSwitch(play, OBJY2SHUTTER_GET_SWITCHFLAG(&this->dyna.actor))) {
+ Flags_UnsetSwitch(play, OBJY2SHUTTER_GET_SWITCHFLAG(&this->dyna.actor));
+ } else {
+ Flags_SetSwitch(play, OBJY2SHUTTER_GET_SWITCHFLAG(&this->dyna.actor));
+ }
+ }
+
+ if (this->settleTimer == 0) {
+ if (Flags_GetSwitch(play, OBJY2SHUTTER_GET_SWITCHFLAG(&this->dyna.actor))) {
+ s16 cutscene = this->dyna.actor.cutscene;
+
+ if (this->openTimer == 0) {
+ if ((cutscene >= 0) && !ActorCutscene_GetCanPlayNext(cutscene)) {
+ ActorCutscene_SetIntentToPlay(cutscene);
+ } else if (cutscene >= 0) {
+ ActorCutscene_StartAndSetUnkLinkFields(cutscene, &this->dyna.actor);
+ this->openTimer = -1;
+ } else {
+ ObjY2shutter_SetupOpen(this, info, shutterType);
+ }
+ } else if (this->openTimer < 0) {
+ if (func_800F22C4(cutscene, &this->dyna.actor)) {
+ ObjY2shutter_SetupOpen(this, info, shutterType);
+ }
+ } else {
+ targetPosY = this->dyna.actor.home.pos.y + info->openedOffsetY;
+ targetVelocityY = info->openVelocity;
+ accelY = info->openAccel;
+ if (this->openTimer < 2) {
+ Flags_UnsetSwitch(play, OBJY2SHUTTER_GET_SWITCHFLAG(&this->dyna.actor));
+ } else {
+ this->openTimer--;
+ }
+ }
+ } else if (this->openTimer != 0) {
+ this->openTimer = 0;
+ this->settleTimer = info->openStartSettleTimer;
+ if (shutterType == SHUTTER_BARRED) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_METALDOOR_CLOSE);
+ }
+ } else {
+ targetPosY = this->dyna.actor.home.pos.y;
+ targetVelocityY = info->closeVelocity;
+ accelY = info->closeAccel;
+ }
+ }
+
+ Math_StepToF(&this->dyna.actor.velocity.y, targetVelocityY, accelY);
+ this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y;
+
+ if (((this->dyna.actor.world.pos.y - targetPosY) * targetVelocityY) >= 0.0f) {
+ this->dyna.actor.world.pos.y = targetPosY;
+ this->dyna.actor.velocity.y = 0.0f;
+ if (!this->isStationary) {
+ this->isStationary = true;
+ this->settleTimer = info->openEndAndCloseSettleTimer;
+ if (shutterType != SHUTTER_BARRED) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_METALDOOR_STOP);
+ }
+ }
+ } else {
+ this->isStationary = false;
+ if (shutterType != SHUTTER_BARRED) {
+ func_800B9010(&this->dyna.actor, NA_SE_EV_METALDOOR_SLIDE - SFX_FLAG);
+ }
+ }
+
+ if (DECR(this->settleTimer)) {
+ this->dyna.actor.shape.yOffset = 2.0f * (this->settleTimer & 1) * this->settleTimer;
+ }
+}
+
+void ObjY2shutter_Draw(Actor* thisx, PlayState* play) {
+ ObjY2shutter* this = THIS;
+ ShutterInfo* info = &sShutterInfo[(OBJY2SHUTTER_GET_TYPE(&this->dyna.actor))];
+
+ Gfx_DrawDListOpa(play, info->dList);
+}
diff --git a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.h b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.h
index 217bcee6c..dcc95b1b1 100644
--- a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.h
+++ b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.h
@@ -6,10 +6,20 @@
struct ObjY2shutter;
typedef struct ObjY2shutter {
- /* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x1C];
+ /* 0x000 */ DynaPolyActor dyna;
+ /* 0x15C */ s16 openTimer;
+ /* 0x15E */ u8 isStationary; // true if the door is neither opening nor closing
+ /* 0x15F */ u8 settleTimer;
} ObjY2shutter; // size = 0x160
extern const ActorInit Obj_Y2shutter_InitVars;
+typedef enum {
+ /* 0x0 */ SHUTTER_BARRED,
+ /* 0x1 */ SHUTTER_GRATED,
+} ShutterType;
+
+#define OBJY2SHUTTER_GET_TYPE(thisx) (((thisx)->params >> 7) & 1)
+#define OBJY2SHUTTER_GET_SWITCHFLAG(thisx) ((thisx)->params & 0x7F)
+
#endif // Z_OBJ_Y2SHUTTER_H
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 77810cc22..b77506370 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -14954,7 +14954,7 @@
0x80B9A8E8:("ObjY2lift_Draw",),
0x80B9A980:("ObjY2shutter_Init",),
0x80B9A9EC:("ObjY2shutter_Destroy",),
- 0x80B9AA20:("func_80B9AA20",),
+ 0x80B9AA20:("ObjY2shutter_SetupOpen",),
0x80B9AA54:("ObjY2shutter_Update",),
0x80B9AE00:("ObjY2shutter_Draw",),
0x80B9AF50:("func_80B9AF50",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index 0fbd78e38..3ac247a29 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -15316,11 +15316,7 @@
0x80B9A920:("Obj_Y2lift_InitVars","UNK_TYPE1","",0x1),
0x80B9A940:("D_80B9A940","UNK_TYPE1","",0x1),
0x80B9AE50:("Obj_Y2shutter_InitVars","UNK_TYPE1","",0x1),
- 0x80B9AE70:("D_80B9AE70","UNK_TYPE1","",0x1),
- 0x80B9AE8C:("D_80B9AE8C","UNK_TYPE1","",0x1),
- 0x80B9AE8D:("D_80B9AE8D","UNK_TYPE1","",0x1),
- 0x80B9AE8E:("D_80B9AE8E","UNK_TYPE1","",0x1),
- 0x80B9AEAE:("D_80B9AEAE","UNK_TYPE1","",0x1),
+ 0x80B9AE70:("D_80B9AE70","UNK_TYPE1","",0x40),
0x80B9AEB0:("D_80B9AEB0","UNK_TYPE1","",0x1),
0x80B9B660:("Obj_Boat_InitVars","UNK_TYPE1","",0x1),
0x80B9B680:("D_80B9B680","UNK_TYPE1","",0x1),