diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml
index 28fa975d7d..011e8f7fc7 100644
--- a/assets/xml/objects/gameplay_field_keep.xml
+++ b/assets/xml/objects/gameplay_field_keep.xml
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index 2be5a95a76..2551b65b56 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -654,15 +654,15 @@
-
-
-
+
+
+
-
+
diff --git a/assets/xml/objects/object_haka_door.xml b/assets/xml/objects/object_haka_door.xml
index 7534924457..1376d03569 100644
--- a/assets/xml/objects/object_haka_door.xml
+++ b/assets/xml/objects/object_haka_door.xml
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/assets/xml/objects/object_hidan_objects.xml b/assets/xml/objects/object_hidan_objects.xml
index 5c54244bb8..fe0405d9dd 100644
--- a/assets/xml/objects/object_hidan_objects.xml
+++ b/assets/xml/objects/object_hidan_objects.xml
@@ -79,8 +79,8 @@
-
-
+
+
diff --git a/include/z64actor.h b/include/z64actor.h
index 43626f8331..f3d43e76ea 100644
--- a/include/z64actor.h
+++ b/include/z64actor.h
@@ -498,6 +498,29 @@ typedef enum {
/* 0xFF */ NAVI_ENEMY_NONE = 0xFF
} NaviEnemy;
+#define TRANSITION_ACTOR_PARAMS_INDEX_SHIFT 10
+#define GET_TRANSITION_ACTOR_INDEX(actor) ((u16)(actor)->params >> TRANSITION_ACTOR_PARAMS_INDEX_SHIFT)
+
+// EnDoor and DoorKiller share openAnim and playerIsOpening
+// Due to alignment, a substruct cannot be used in the structs of these actors.
+#define DOOR_ACTOR_BASE \
+ /* 0x0000 */ Actor actor; \
+ /* 0x014C */ SkelAnime skelAnime; \
+ /* 0x0190 */ u8 openAnim; \
+ /* 0x0191 */ u8 playerIsOpening
+
+typedef struct DoorActorBase {
+ /* 0x0000 */ DOOR_ACTOR_BASE;
+} DoorActorBase;
+
+typedef enum {
+ /* 0x00 */ DOOR_OPEN_ANIM_ADULT_L,
+ /* 0x01 */ DOOR_OPEN_ANIM_CHILD_L,
+ /* 0x02 */ DOOR_OPEN_ANIM_ADULT_R,
+ /* 0x03 */ DOOR_OPEN_ANIM_CHILD_R,
+ /* 0x04 */ DOOR_OPEN_ANIM_MAX
+} DoorOpenAnim;
+
#define UPDBGCHECKINFO_FLAG_0 (1 << 0) // check wall
#define UPDBGCHECKINFO_FLAG_1 (1 << 1) // check ceiling
#define UPDBGCHECKINFO_FLAG_2 (1 << 2) // check floor and water
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index d70e755761..091f6fc022 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -2840,7 +2840,7 @@ void Actor_SpawnTransitionActors(PlayState* play, ActorContext* actorCtx) {
(transitionActor->sides[1].room == play->roomCtx.prevRoom.num)))) {
Actor_Spawn(actorCtx, play, (s16)(transitionActor->id & 0x1FFF), transitionActor->pos.x,
transitionActor->pos.y, transitionActor->pos.z, 0, transitionActor->rotY, 0,
- (i << 0xA) + transitionActor->params);
+ (i << TRANSITION_ACTOR_PARAMS_INDEX_SHIFT) + transitionActor->params);
transitionActor->id = -transitionActor->id;
numActors = play->transiActorCtx.numActors;
diff --git a/src/code/z_play.c b/src/code/z_play.c
index a9e82de442..c32ef6b63e 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1748,7 +1748,7 @@ s32 func_800C0D34(PlayState* this, Actor* actor, s16* yaw) {
return 0;
}
- transitionActor = &this->transiActorCtx.list[(u16)actor->params >> 10];
+ transitionActor = &this->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(actor)];
frontRoom = transitionActor->sides[0].room;
if (frontRoom == transitionActor->sides[1].room) {
diff --git a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
index 2af79ba80d..6eef8528d8 100644
--- a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
+++ b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
@@ -491,7 +491,7 @@ void DemoEffect_Init(Actor* thisx, PlayState* play2) {
this->jewel.type = DEMO_EFFECT_JEWEL_ZORA;
this->jewel.isPositionInit = 0;
DemoEffect_InitJewel(play, this);
- Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTOR_EN_DOOR);
+ Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_BOSS);
if ((play->sceneNum == SCENE_BDAN) && GET_INFTABLE(INFTABLE_145)) {
Actor_Kill(&this->actor);
return;
diff --git a/src/overlays/actors/ovl_Door_Killer/z_door_killer.c b/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
index 26ccfe851b..4de1c4913e 100644
--- a/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
+++ b/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
@@ -117,8 +117,8 @@ void DoorKiller_Init(Actor* thisx, PlayState* play2) {
Actor_SetScale(&this->actor, 0.01f);
this->timer = 0;
this->hasHitPlayerOrGround = 0;
- this->animStyle = 0;
- this->playerIsOpening = 0;
+ this->openAnim = 0;
+ this->playerIsOpening = false;
switch ((u8)(this->actor.params & 0xFF)) {
case DOOR_KILLER_DOOR:
@@ -416,7 +416,7 @@ void DoorKiller_Wait(DoorKiller* this, PlayState* play) {
if (this->playerIsOpening) {
this->actionFunc = DoorKiller_WaitBeforeWobble;
this->timer = 10;
- this->playerIsOpening = 0;
+ this->playerIsOpening = false;
return;
}
diff --git a/src/overlays/actors/ovl_Door_Killer/z_door_killer.h b/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
index 2fe74808b8..37865805ea 100644
--- a/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
+++ b/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
@@ -7,7 +7,7 @@
/*
* Associated switch flag: (params >> 8) & 0x3F
* ((params >> 8) & 0x3F) == 0x3F means no switch flag is checked / set
-*/
+ */
typedef struct {
/* 0x00 */ s16 objectId;
@@ -19,10 +19,7 @@ struct DoorKiller;
typedef void (*DoorKillerActionFunc)(struct DoorKiller*, PlayState*);
typedef struct DoorKiller {
- /* 0x0000 */ Actor actor;
- /* 0x014C */ SkelAnime skelAnime;
- /* 0x0190 */ u8 animStyle; // Must be at same offset as animStyle in EnDoor due to the cast in func_80839800
- /* 0x0191 */ u8 playerIsOpening; // Must be at same offset as playerIsOpening in EnDoor
+ /* 0x0000 */ DOOR_ACTOR_BASE;
/* 0x0192 */ Vec3s jointTable[9];
/* 0x01C8 */ ColliderCylinder colliderCylinder;
/* 0x0214 */ void* texture;
diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
index c2defefefb..489224a9cd 100644
--- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
+++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
@@ -174,7 +174,7 @@ void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc
}
s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) {
- TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[(u16)this->dyna.actor.params >> 0xA];
+ TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->dyna.actor)];
s8 frontRoom = transitionEntry->sides[0].room;
s32 doorType = this->doorType;
ShutterObjectInfo* temp_t0 = &sObjectInfo[this->unk_16B];
@@ -278,7 +278,7 @@ void DoorShutter_Destroy(Actor* thisx, PlayState* play) {
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
if (this->dyna.actor.room >= 0) {
- s32 transitionActorId = (u16)this->dyna.actor.params >> 0xA;
+ s32 transitionActorId = GET_TRANSITION_ACTOR_INDEX(&this->dyna.actor);
play->transiActorCtx.list[transitionActorId].id *= -1;
}
@@ -540,7 +540,7 @@ void func_80997220(DoorShutter* this, PlayState* play) {
func_8002DBD0(&this->dyna.actor, &vec, &player->actor.world.pos);
this->dyna.actor.room =
- play->transiActorCtx.list[(u16)this->dyna.actor.params >> 0xA].sides[(vec.z < 0.0f) ? 0 : 1].room;
+ play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->dyna.actor)].sides[(vec.z < 0.0f) ? 0 : 1].room;
if (room != this->dyna.actor.room) {
Room tempRoom = play->roomCtx.curRoom;
@@ -727,7 +727,8 @@ void DoorShutter_Draw(Actor* thisx, PlayState* play) {
}
} else {
if (sp70->b != NULL) {
- TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[(u16)this->dyna.actor.params >> 0xA];
+ TransitionActorEntry* transitionEntry =
+ &play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->dyna.actor)];
if (play->roomCtx.prevRoom.num >= 0 ||
transitionEntry->sides[0].room == transitionEntry->sides[1].room) {
diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.c b/src/overlays/actors/ovl_En_Door/z_en_door.c
index 161f3ffbf5..72eaa67c82 100644
--- a/src/overlays/actors/ovl_En_Door/z_en_door.c
+++ b/src/overlays/actors/ovl_En_Door/z_en_door.c
@@ -44,17 +44,32 @@ const ActorInit En_Door_InitVars = {
(ActorFunc)EnDoor_Draw,
};
+typedef struct {
+ /* 0x00 */ s16 sceneNum;
+ /* 0x02 */ u8 dListIndex;
+ /* 0x04 */ s16 objectId;
+} EnDoorInfo;
+
+typedef enum {
+ /* 0 */ DOOR_DL_DEFAULT,
+ /* 1 */ DOOR_DL_FIRE_TEMPLE,
+ /* 2 */ DOOR_DL_WATER_TEMPLE,
+ /* 3 */ DOOR_DL_SHADOW,
+ /* 4 */ DOOR_DL_DEFAULT_FIELD_KEEP,
+ /* 5 */ DOOR_DL_MAX
+} EnDoorDListIndex;
+
/**
* Controls which object and display lists to use in a given scene
*/
static EnDoorInfo sDoorInfo[] = {
- { SCENE_HIDAN, 1, OBJECT_HIDAN_OBJECTS },
- { SCENE_MIZUSIN, 2, OBJECT_MIZU_OBJECTS },
- { SCENE_HAKADAN, 3, OBJECT_HAKA_DOOR },
- { SCENE_HAKADANCH, 3, OBJECT_HAKA_DOOR },
+ { SCENE_HIDAN, DOOR_DL_FIRE_TEMPLE, OBJECT_HIDAN_OBJECTS },
+ { SCENE_MIZUSIN, DOOR_DL_WATER_TEMPLE, OBJECT_MIZU_OBJECTS },
+ { SCENE_HAKADAN, DOOR_DL_SHADOW, OBJECT_HAKA_DOOR },
+ { SCENE_HAKADANCH, DOOR_DL_SHADOW, OBJECT_HAKA_DOOR },
// KEEP objects should remain last and in this order
- { -1, 0, OBJECT_GAMEPLAY_KEEP },
- { -1, 4, OBJECT_GAMEPLAY_FIELD_KEEP },
+ { -1, DOOR_DL_DEFAULT, OBJECT_GAMEPLAY_KEEP },
+ { -1, DOOR_DL_DEFAULT_FIELD_KEEP, OBJECT_GAMEPLAY_FIELD_KEEP },
};
static InitChainEntry sInitChain[] = {
@@ -62,18 +77,33 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_STOP),
};
-static AnimationHeader* sDoorAnims[] = { &gDoor3Anim, &gDoor1Anim, &gDoor4Anim, &gDoor2Anim };
+static AnimationHeader* sDoorAnims[DOOR_OPEN_ANIM_MAX] = {
+ &gDoorAdultOpeningLeftAnim, // DOOR_OPEN_ANIM_ADULT_L
+ &gDoorChildOpeningLeftAnim, // DOOR_OPEN_ANIM_CHILD_L
+ &gDoorAdultOpeningRightAnim, // DOOR_OPEN_ANIM_ADULT_R
+ &gDoorChildOpeningRightAnim, // DOOR_OPEN_ANIM_CHILD_R
+};
-static u8 sDoorAnimOpenFrames[] = { 25, 25, 25, 25 };
+static u8 sDoorAnimOpenFrames[DOOR_OPEN_ANIM_MAX] = {
+ 25, // DOOR_OPEN_ANIM_ADULT_L
+ 25, // DOOR_OPEN_ANIM_CHILD_L
+ 25, // DOOR_OPEN_ANIM_ADULT_R
+ 25, // DOOR_OPEN_ANIM_CHILD_R
+};
-static u8 sDoorAnimCloseFrames[] = { 60, 70, 60, 70 };
+static u8 sDoorAnimCloseFrames[DOOR_OPEN_ANIM_MAX] = {
+ 60, // DOOR_OPEN_ANIM_ADULT_L
+ 70, // DOOR_OPEN_ANIM_CHILD_L
+ 60, // DOOR_OPEN_ANIM_ADULT_R
+ 70, // DOOR_OPEN_ANIM_CHILD_R
+};
-static Gfx* sDoorDLists[5][2] = {
- { gDoorLeftDL, gDoorRightDL },
- { gFireTempleDoorWithHandleFrontDL, gFireTempleDoorWithHandleBackDL },
- { gWaterTempleDoorLeftDL, gWaterTempleDoorRightDL },
- { object_haka_door_DL_0013B8, object_haka_door_DL_001420 },
- { gFieldDoor1DL, gFieldDoor2DL },
+static Gfx* sDoorDLists[DOOR_DL_MAX][2] = {
+ { gDoorLeftDL, gDoorRightDL }, // DOOR_DL_DEFAULT
+ { gFireTempleDoorWithHandleLeftDL, gFireTempleDoorWithHandleRightDL }, // DOOR_DL_FIRE_TEMPLE
+ { gWaterTempleDoorLeftDL, gWaterTempleDoorRightDL }, // DOOR_DL_WATER_TEMPLE
+ { gShadowDoorLeftDL, gShadowDoorRightDL }, // DOOR_DL_SHADOW
+ { gFieldDoorLeftDL, gFieldDoorRightDL }, // DOOR_DL_DEFAULT_FIELD_KEEP
};
void EnDoor_Init(Actor* thisx, PlayState* play2) {
@@ -87,7 +117,8 @@ void EnDoor_Init(Actor* thisx, PlayState* play2) {
objectInfo = &sDoorInfo[0];
Actor_ProcessInitChain(&this->actor, sInitChain);
- SkelAnime_Init(play, &this->skelAnime, &gDoorSkel, &gDoor3Anim, this->jointTable, this->morphTable, 5);
+ SkelAnime_Init(play, &this->skelAnime, &gDoorSkel, &gDoorAdultOpeningLeftAnim, this->jointTable, this->morphTable,
+ 5);
for (i = 0; i < ARRAY_COUNT(sDoorInfo) - 2; i++, objectInfo++) {
if (play->sceneNum == objectInfo->sceneNum) {
break;
@@ -113,7 +144,7 @@ void EnDoor_Init(Actor* thisx, PlayState* play2) {
}
// Double doors
- if (this->actor.params & 0x40) {
+ if (ENDOOR_IS_DOUBLE_DOOR(&this->actor)) {
EnDoor* other;
xOffset = Math_CosS(this->actor.shape.rot.y) * 30.0f;
@@ -121,7 +152,7 @@ void EnDoor_Init(Actor* thisx, PlayState* play2) {
other = (EnDoor*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_DOOR,
this->actor.world.pos.x + xOffset, this->actor.world.pos.y,
this->actor.world.pos.z - zOffset, 0, this->actor.shape.rot.y + 0x8000, 0,
- this->actor.params & ~0x40);
+ this->actor.params & ~ENDOOR_PARAMS_DOUBLE_DOOR_FLAG);
if (other != NULL) {
other->unk_192 = 1;
}
@@ -135,7 +166,7 @@ void EnDoor_Destroy(Actor* thisx, PlayState* play) {
TransitionActorEntry* transitionEntry;
EnDoor* this = (EnDoor*)thisx;
- transitionEntry = &play->transiActorCtx.list[(u16)this->actor.params >> 0xA];
+ transitionEntry = &play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->actor)];
if (transitionEntry->id < 0) {
transitionEntry->id = -transitionEntry->id;
}
@@ -145,7 +176,7 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) {
s32 doorType;
if (Object_IsLoaded(&play->objectCtx, this->requiredObjBankIndex)) {
- doorType = this->actor.params >> 7 & 7;
+ doorType = ENDOOR_GET_TYPE(&this->actor);
this->actor.flags &= ~ACTOR_FLAG_4;
this->actor.objBankIndex = this->requiredObjBankIndex;
this->actionFunc = EnDoor_Idle;
@@ -156,7 +187,7 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) {
}
this->actor.world.rot.y = 0x0000;
if (doorType == DOOR_LOCKED) {
- if (!Flags_GetSwitch(play, this->actor.params & 0x3F)) {
+ if (!Flags_GetSwitch(play, ENDOOR_GET_LOCKED_SWITCH_FLAG(&this->actor))) {
this->lockTimer = 10;
}
} else if (doorType == DOOR_AJAR) {
@@ -165,7 +196,7 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) {
this->actor.world.rot.y = -0x1800;
}
} else if (doorType == DOOR_CHECKABLE) {
- this->actor.textId = (this->actor.params & 0x3F) + 0x0200;
+ this->actor.textId = ENDOOR_GET_CHECKABLE_TEXT_ID(&this->actor) + 0x0200;
if (this->actor.textId == 0x0229 && !GET_EVENTCHKINF(EVENTCHKINF_14)) {
// Talon's house door. If Talon has not been woken up at Hyrule Castle
// this door should be openable at any time of day.
@@ -178,7 +209,7 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) {
}
}
// Replace the door type it was loaded with by the new type
- this->actor.params = (this->actor.params & ~0x380) | (doorType << 7);
+ this->actor.params = (this->actor.params & ~ENDOOR_PARAMS_TYPE_MASK) | (doorType << ENDOOR_PARAMS_TYPE_SHIFT);
}
}
@@ -188,15 +219,15 @@ void EnDoor_Idle(EnDoor* this, PlayState* play) {
Vec3f playerPosRelToDoor;
s16 yawDiff;
- doorType = this->actor.params >> 7 & 7;
+ doorType = ENDOOR_GET_TYPE(&this->actor);
func_8002DBD0(&this->actor, &playerPosRelToDoor, &player->actor.world.pos);
- if (this->playerIsOpening != 0) {
+ if (this->playerIsOpening) {
this->actionFunc = EnDoor_Open;
- Animation_PlayOnceSetSpeed(&this->skelAnime, sDoorAnims[this->animStyle],
+ Animation_PlayOnceSetSpeed(&this->skelAnime, sDoorAnims[this->openAnim],
(player->stateFlags1 & PLAYER_STATE1_27) ? 0.75f : 1.5f);
if (this->lockTimer != 0) {
gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--;
- Flags_SetSwitch(play, this->actor.params & 0x3F);
+ Flags_SetSwitch(play, ENDOOR_GET_LOCKED_SWITCH_FLAG(&this->actor));
Audio_PlayActorSfx2(&this->actor, NA_SE_EV_CHAIN_KEY_UNLOCK);
}
} else if (!Player_InCsMode(play)) {
@@ -268,8 +299,8 @@ void EnDoor_Open(EnDoor* this, PlayState* play) {
if (DECR(this->lockTimer) == 0) {
if (SkelAnime_Update(&this->skelAnime)) {
this->actionFunc = EnDoor_Idle;
- this->playerIsOpening = 0;
- } else if (Animation_OnFrame(&this->skelAnime, sDoorAnimOpenFrames[this->animStyle])) {
+ this->playerIsOpening = false;
+ } else if (Animation_OnFrame(&this->skelAnime, sDoorAnimOpenFrames[this->openAnim])) {
Audio_PlayActorSfx2(&this->actor, (play->sceneNum == SCENE_HAKADAN || play->sceneNum == SCENE_HAKADANCH ||
play->sceneNum == SCENE_HIDAN)
? NA_SE_EV_IRON_DOOR_OPEN
@@ -280,7 +311,7 @@ void EnDoor_Open(EnDoor* this, PlayState* play) {
EffectSsBubble_Spawn(play, &this->actor.world.pos, 60.0f, 100.0f, 50.0f, 0.15f);
}
}
- } else if (Animation_OnFrame(&this->skelAnime, sDoorAnimCloseFrames[this->animStyle])) {
+ } else if (Animation_OnFrame(&this->skelAnime, sDoorAnimCloseFrames[this->openAnim])) {
Audio_PlayActorSfx2(&this->actor, (play->sceneNum == SCENE_HAKADAN || play->sceneNum == SCENE_HAKADANCH ||
play->sceneNum == SCENE_HIDAN)
? NA_SE_EV_IRON_DOOR_CLOSE
@@ -306,10 +337,11 @@ s32 EnDoor_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
if (limbIndex == 4) {
doorDLists = sDoorDLists[this->dListIndex];
- transitionEntry = &play->transiActorCtx.list[(u16)this->actor.params >> 0xA];
+ transitionEntry = &play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->actor)];
rot->z += this->actor.world.rot.y;
if ((play->roomCtx.prevRoom.num >= 0) || (transitionEntry->sides[0].room == transitionEntry->sides[1].room)) {
- rotDiff = ((this->actor.shape.rot.y + this->skelAnime.jointTable[3].z) + rot->z) -
+ // Draw the side of the door that is visible to the camera
+ rotDiff = this->actor.shape.rot.y + this->skelAnime.jointTable[3].z + rot->z -
Math_Vec3f_Yaw(&play->view.eye, &this->actor.world.pos);
*dList = (ABS(rotDiff) < 0x4000) ? doorDLists[0] : doorDLists[1];
} else {
diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.h b/src/overlays/actors/ovl_En_Door/z_en_door.h
index b7e3d5d2f1..05c41e16c0 100644
--- a/src/overlays/actors/ovl_En_Door/z_en_door.h
+++ b/src/overlays/actors/ovl_En_Door/z_en_door.h
@@ -22,11 +22,14 @@
*
*/
-typedef struct {
- /* 0x00 */ s16 sceneNum;
- /* 0x02 */ u8 dListIndex;
- /* 0x04 */ s16 objectId;
-} EnDoorInfo;
+#define ENDOOR_PARAMS_TYPE_SHIFT 7
+#define ENDOOR_PARAMS_TYPE_MASK (7 << ENDOOR_PARAMS_TYPE_SHIFT)
+#define ENDOOR_GET_TYPE(thisx) ((thisx)->params >> ENDOOR_PARAMS_TYPE_SHIFT & 7)
+#define ENDOOR_PARAMS_DOUBLE_DOOR_FLAG 0x40
+#define ENDOOR_IS_DOUBLE_DOOR(thisx) ((thisx)->params & ENDOOR_PARAMS_DOUBLE_DOOR_FLAG)
+#define ENDOOR_GET_LOCKED_SWITCH_FLAG(thisx) ((thisx)->params & 0x3F)
+#define ENDOOR_GET_CHECKABLE_TEXT_ID(thisx) ((thisx)->params & 0x3F)
+
typedef enum {
/* 0x00 */ DOOR_ROOMLOAD, // loads rooms
@@ -44,10 +47,7 @@ struct EnDoor;
typedef void (*EnDoorActionFunc)(struct EnDoor*, PlayState*);
typedef struct EnDoor {
- /* 0x0000 */ Actor actor;
- /* 0x014C */ SkelAnime skelAnime;
- /* 0x0190 */ u8 animStyle; // Must be at same offset as animStyle in DoorKiller due to the cast in func_80839800
- /* 0x0191 */ u8 playerIsOpening; // Must be at same offset as playerIsOpening in DoorKiller due to the cast in func_80839800
+ /* 0x0000 */ DOOR_ACTOR_BASE;
/* 0x0192 */ u8 unk_192;
/* 0x0193 */ s8 requiredObjBankIndex;
/* 0x0194 */ s8 dListIndex;
diff --git a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
index 31940309b1..5cafe6cd86 100644
--- a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
+++ b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
@@ -93,7 +93,7 @@ void EnHeishi2_Init(Actor* thisx, PlayState* play) {
if ((this->type == 6) || (this->type == 9)) {
this->actor.draw = EnHeishi2_DrawKingGuard;
this->actor.flags &= ~ACTOR_FLAG_0;
- Actor_ChangeCategory(play, &play->actorCtx, &this->actor, 6);
+ Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_PROP);
if (this->type == 6) {
this->actionFunc = EnHeishi2_DoNothing1;
diff --git a/src/overlays/actors/ovl_En_Holl/z_en_holl.c b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
index 8eac637164..3e0065b07f 100644
--- a/src/overlays/actors/ovl_En_Holl/z_en_holl.c
+++ b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
@@ -100,7 +100,7 @@ void EnHoll_Init(Actor* thisx, PlayState* play) {
}
void EnHoll_Destroy(Actor* thisx, PlayState* play) {
- s32 transitionActorIdx = (u16)thisx->params >> 0xA;
+ s32 transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(thisx);
TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[transitionActorIdx];
transitionEntry->id = -transitionEntry->id;
@@ -129,7 +129,7 @@ void func_80A58DD4(EnHoll* this, PlayState* play) {
absZ = fabsf(vec.z);
if (vec.y > PLANE_Y_MIN && vec.y < PLANE_Y_MAX && fabsf(vec.x) < PLANE_HALFWIDTH &&
absZ < sHorizTriggerDists[phi_t0][0]) {
- transitionActorIdx = (u16)this->actor.params >> 0xA;
+ transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
if (absZ > sHorizTriggerDists[phi_t0][1]) {
if (play->roomCtx.prevRoom.num >= 0 && play->roomCtx.status == 0) {
this->actor.room = play->transiActorCtx.list[transitionActorIdx].sides[this->side].room;
@@ -167,7 +167,7 @@ void func_80A59014(EnHoll* this, PlayState* play) {
temp = EnHoll_IsKokiriLayer8();
if (temp || (PLANE_Y_MIN < vec.y && vec.y < PLANE_Y_MAX && fabsf(vec.x) < planeHalfWidth &&
(absZ = fabsf(vec.z), 100.0f > absZ && absZ > 50.0f))) {
- s32 transitionActorIdx = (u16)this->actor.params >> 0xA;
+ s32 transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
s32 side = (vec.z < 0.0f) ? 0 : 1;
TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[transitionActorIdx];
s32 room = transitionEntry->sides[side].room;
@@ -190,7 +190,7 @@ void func_80A591C0(EnHoll* this, PlayState* play) {
s32 transitionActorIdx;
if (this->actor.xzDistToPlayer < 500.0f && absY < 700.0f) {
- transitionActorIdx = (u16)this->actor.params >> 0xA;
+ transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
if (absY < 95.0f) {
play->unk_11E18 = 0xFF;
} else if (absY > 605.0f) {
@@ -228,7 +228,7 @@ void func_80A593A4(EnHoll* this, PlayState* play) {
play->unk_11E18 = (200.0f - absY) * 1.7f;
}
if (absY > 50.0f) {
- transitionActorIdx = (u16)this->actor.params >> 0xA;
+ transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
side = (0.0f < this->actor.yDistToPlayer) ? 0 : 1;
this->actor.room = play->transiActorCtx.list[transitionActorIdx].sides[side].room;
if (this->actor.room != play->roomCtx.curRoom.num &&
@@ -252,7 +252,7 @@ void func_80A59520(EnHoll* this, PlayState* play) {
if (this->actor.xzDistToPlayer < 120.0f) {
absY = fabsf(this->actor.yDistToPlayer);
if (absY < 200.0f && absY > 50.0f) {
- transitionActorIdx = (u16)this->actor.params >> 0xA;
+ transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
side = (0.0f < this->actor.yDistToPlayer) ? 0 : 1;
this->actor.room = play->transiActorCtx.list[transitionActorIdx].sides[side].room;
if (this->actor.room != play->roomCtx.curRoom.num &&
@@ -281,7 +281,7 @@ void func_80A59618(EnHoll* this, PlayState* play) {
absZ = fabsf(vec.z);
if (PLANE_Y_MIN < vec.y && vec.y < PLANE_Y_MAX && fabsf(vec.x) < PLANE_HALFWIDTH_2 && absZ < 100.0f) {
this->unk_14F = 1;
- transitionActorIdx = (u16)this->actor.params >> 0xA;
+ transitionActorIdx = GET_TRANSITION_ACTOR_INDEX(&this->actor);
play->unk_11E18 = 0xFF - (s32)((absZ - 50.0f) * 5.9f);
if (play->unk_11E18 >= 0x100) {
play->unk_11E18 = 0xFF;
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 37331f17bb..746dc74541 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
@@ -379,7 +379,7 @@ void EnPoh_SetupDeath(EnPoh* this, PlayState* play) {
if (this->infoIdx != EN_POH_INFO_COMPOSER) {
this->actor.shape.rot.x = -0x8000;
}
- Actor_ChangeCategory(play, &play->actorCtx, &this->actor, 8);
+ Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_MISC);
this->unk_198 = 60;
this->actionFunc = EnPoh_Death;
}
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index e335eea240..327f08e26c 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -39,13 +39,6 @@ typedef struct {
#define GET_ITEM_NONE \
{ ITEM_NONE, 0, 0, 0, OBJECT_INVALID }
-typedef enum {
- /* 0x00 */ KNOB_ANIM_ADULT_L,
- /* 0x01 */ KNOB_ANIM_CHILD_L,
- /* 0x02 */ KNOB_ANIM_ADULT_R,
- /* 0x03 */ KNOB_ANIM_CHILD_R
-} KnobDoorAnim;
-
typedef struct {
/* 0x00 */ u8 itemId;
/* 0x02 */ s16 actorId;
@@ -4308,7 +4301,7 @@ s32 func_80839768(PlayState* play, Player* this, Vec3f* arg2, CollisionPoly** ar
s32 func_80839800(Player* this, PlayState* play) {
DoorShutter* doorShutter;
- EnDoor* door; // Can also be DoorKiller*
+ DoorActorBase* door;
s32 doorDirection;
f32 sp78;
f32 sp74;
@@ -4373,26 +4366,26 @@ s32 func_80839800(Player* this, PlayState* play) {
}
if (doorShutter->dyna.actor.category == ACTORCAT_DOOR) {
- this->doorBgCamIndex = play->transiActorCtx.list[(u16)doorShutter->dyna.actor.params >> 10]
- .sides[(doorDirection > 0) ? 0 : 1]
- .bgCamIndex;
+ this->doorBgCamIndex =
+ play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&doorShutter->dyna.actor)]
+ .sides[(doorDirection > 0) ? 0 : 1]
+ .bgCamIndex;
Actor_DisableLens(play);
}
} else {
- // This actor can be either EnDoor or DoorKiller.
- // Don't try to access any struct vars other than `animStyle` and `playerIsOpening`! These two variables
- // are common across the two actors' structs however most other variables are not!
- door = (EnDoor*)doorActor;
+ // The door actor can be either EnDoor or DoorKiller.
+ door = (DoorActorBase*)doorActor;
- door->animStyle = (doorDirection < 0.0f) ? (LINK_IS_ADULT ? KNOB_ANIM_ADULT_L : KNOB_ANIM_CHILD_L)
- : (LINK_IS_ADULT ? KNOB_ANIM_ADULT_R : KNOB_ANIM_CHILD_R);
+ door->openAnim = (doorDirection < 0.0f)
+ ? (LINK_IS_ADULT ? DOOR_OPEN_ANIM_ADULT_L : DOOR_OPEN_ANIM_CHILD_L)
+ : (LINK_IS_ADULT ? DOOR_OPEN_ANIM_ADULT_R : DOOR_OPEN_ANIM_CHILD_R);
- if (door->animStyle == KNOB_ANIM_ADULT_L) {
+ if (door->openAnim == DOOR_OPEN_ANIM_ADULT_L) {
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_9, this->modelAnimType);
- } else if (door->animStyle == KNOB_ANIM_CHILD_L) {
+ } else if (door->openAnim == DOOR_OPEN_ANIM_CHILD_L) {
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_10, this->modelAnimType);
- } else if (door->animStyle == KNOB_ANIM_ADULT_R) {
+ } else if (door->openAnim == DOOR_OPEN_ANIM_ADULT_R) {
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_11, this->modelAnimType);
} else {
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_12, this->modelAnimType);
@@ -4422,17 +4415,21 @@ s32 func_80839800(Player* this, PlayState* play) {
func_80832224(this);
func_80832F54(play, this, 0x28F);
+ // If this door is the second half of a double door (spawned as child)
if (doorActor->parent != NULL) {
doorDirection = -doorDirection;
}
- door->playerIsOpening = 1;
+ door->playerIsOpening = true;
+ // If the door actor is not DoorKiller
if (this->doorType != PLAYER_DOORTYPE_FAKE) {
+ // The door actor is EnDoor
+
this->stateFlags1 |= PLAYER_STATE1_29;
Actor_DisableLens(play);
- if (((doorActor->params >> 7) & 7) == 3) {
+ if (ENDOOR_GET_TYPE(doorActor) == DOOR_SCENEEXIT) {
sp4C.x = doorActor->world.pos.x - (sp6C * sp74);
sp4C.y = doorActor->world.pos.y + 10.0f;
sp4C.z = doorActor->world.pos.z - (sp6C * sp78);
@@ -4445,7 +4442,7 @@ s32 func_80839800(Player* this, PlayState* play) {
}
} else {
Camera_ChangeDoorCam(Play_GetCamera(play, CAM_ID_MAIN), doorActor,
- play->transiActorCtx.list[(u16)doorActor->params >> 10]
+ play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(doorActor)]
.sides[(doorDirection > 0) ? 0 : 1]
.bgCamIndex,
0, 38.0f * D_808535EC, 26.0f * D_808535EC, 10.0f * D_808535EC);
@@ -4454,8 +4451,9 @@ s32 func_80839800(Player* this, PlayState* play) {
}
if ((this->doorType != PLAYER_DOORTYPE_FAKE) && (doorActor->category == ACTORCAT_DOOR)) {
- frontRoom =
- play->transiActorCtx.list[(u16)doorActor->params >> 10].sides[(doorDirection > 0) ? 0 : 1].room;
+ frontRoom = play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(doorActor)]
+ .sides[(doorDirection > 0) ? 0 : 1]
+ .room;
if ((frontRoom >= 0) && (frontRoom != play->roomCtx.curRoom.num)) {
func_8009728C(play, &play->roomCtx, frontRoom);