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);