From f181c2f10eb500bf366e4da3d0ed08ac4d97a713 Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Mon, 19 Dec 2022 02:42:24 +0100 Subject: [PATCH] DoorShutter logic docs (#1418) * DoorShutter logic docs * Comment on two more funcs * Fix comment on DoorShutter_UnbarredCheckSwitchFlag I mmissed the `!(... == SHUTTER_FRONT_CLEAR)` * Remove types 8,9,10 from enum as they aren't referenced by any transition actor list in all scenes * Add `DOORSHUTTER_PARAMS` macro to pack params * `DoorShutter_WaitPlayerShock` -> `DoorShutter_WaitPlayerSurprised` * --comma * moveState -> isActive * Add mention about SlidingDoorActorBase.isActive being a timer in niche DoorShutter cases --- include/z64actor.h | 10 + .../actors/ovl_Boss_Goma/z_boss_goma.c | 4 +- .../actors/ovl_Door_Gerudo/z_door_gerudo.c | 2 +- .../actors/ovl_Door_Gerudo/z_door_gerudo.h | 3 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 218 ++++++++++++------ .../actors/ovl_Door_Shutter/z_door_shutter.h | 21 +- src/overlays/actors/ovl_En_fHG/z_en_fhg.c | 4 +- .../actors/ovl_player_actor/z_player.c | 12 +- 8 files changed, 178 insertions(+), 96 deletions(-) diff --git a/include/z64actor.h b/include/z64actor.h index a9c5b910b7..ad627d6f3e 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -527,6 +527,16 @@ typedef struct DoorActorBase { /* 0x0000 */ DOOR_ACTOR_BASE; } DoorActorBase; +// DoorShutter and DoorGerudo share isActive +// Due to alignment, a substruct cannot be used in the structs of these actors. +#define SLIDING_DOOR_ACTOR_BASE \ + /* 0x0000 */ DynaPolyActor dyna; \ + /* 0x0164 */ s16 isActive // Set to true by player when using the door. Also a timer for niche cases in DoorShutter + +typedef struct SlidingDoorActorBase { + /* 0x0000 */ SLIDING_DOOR_ACTOR_BASE; +} SlidingDoorActorBase; + typedef enum { /* 0x00 */ DOOR_OPEN_ANIM_ADULT_L, /* 0x01 */ DOOR_OPEN_ANIM_CHILD_L, diff --git a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index d0bc025060..22bb524bcd 100644 --- a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -684,7 +684,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { if (GET_EVENTCHKINF(EVENTCHKINF_70)) { BossGoma_SetupEncounterState4(this, play); Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, 164.72f, -480.0f, - 397.68002f, 0, -0x705C, 0, 0x180); + 397.68002f, 0, -0x705C, 0, DOORSHUTTER_PARAMS(SHUTTER_GOHMA_BLOCK, 0)); } else { func_8002DF54(play, &this->actor, PLAYER_CSMODE_8); this->actionState = 1; @@ -748,7 +748,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { if (this->frameCount == 176) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, 164.72f, -480.0f, - 397.68002f, 0, -0x705C, 0, SHUTTER_GOHMA_BLOCK << 6); + 397.68002f, 0, -0x705C, 0, DOORSHUTTER_PARAMS(SHUTTER_GOHMA_BLOCK, 0)); } if (this->frameCount == 176) { diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c index 432045a500..98ed8418a3 100644 --- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c +++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c @@ -97,7 +97,7 @@ s32 func_80994750(DoorGerudo* this, PlayState* play) { } void func_8099485C(DoorGerudo* this, PlayState* play) { - if (this->unk_164 != 0) { + if (this->isActive) { this->actionFunc = func_8099496C; gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] -= 1; Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h index fc545e0e0e..c00a0fa669 100644 --- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h +++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h @@ -9,8 +9,7 @@ struct DoorGerudo; typedef void (*DoorGerudoActionFunc)(struct DoorGerudo*, PlayState*); typedef struct DoorGerudo { - /* 0x0000 */ DynaPolyActor dyna; - /* 0x0164 */ s16 unk_164; + /* 0x0000 */ SLIDING_DOOR_ACTOR_BASE; /* 0x0166 */ u8 unk_166; /* 0x0168 */ DoorGerudoActionFunc actionFunc; } DoorGerudo; // size = 0x016C 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 152f92f38a..c41b227aed 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -34,16 +34,16 @@ void DoorShutter_Draw(Actor* thisx, PlayState* play); void DoorShutter_RequestQuakeAndRumble(PlayState* play, s16 quakeY, s16 quakeDuration, s16 camId); void DoorShutter_WaitForObject(DoorShutter* this, PlayState* play); -void func_80996A54(DoorShutter* this, PlayState* play); -void func_80996B00(DoorShutter* this, PlayState* play); -void func_80996B0C(DoorShutter* this, PlayState* play); -void func_80996EE8(DoorShutter* this, PlayState* play); -void func_80996F98(DoorShutter* this, PlayState* play); -void func_80997004(DoorShutter* this, PlayState* play); -void func_80997150(DoorShutter* this, PlayState* play); -void func_809973E8(DoorShutter* this, PlayState* play); +void DoorShutter_WaitClear(DoorShutter* this, PlayState* play); +void DoorShutter_Unopenable(DoorShutter* this, PlayState* play); +void DoorShutter_Idle(DoorShutter* this, PlayState* play); +void DoorShutter_BarAndWaitSwitchFlag(DoorShutter* this, PlayState* play); +void DoorShutter_UnbarredCheckSwitchFlag(DoorShutter* this, PlayState* play); +void DoorShutter_Open(DoorShutter* this, PlayState* play); +void DoorShutter_Unbar(DoorShutter* this, PlayState* play); +void DoorShutter_Close(DoorShutter* this, PlayState* play); void DoorShutter_JabuDoorClose(DoorShutter* this, PlayState* play); -void func_80997568(DoorShutter* this, PlayState* play); +void DoorShutter_WaitPlayerSurprised(DoorShutter* this, PlayState* play); void DoorShutter_GohmaBlockFall(DoorShutter* this, PlayState* play); void DoorShutter_GohmaBlockBounce(DoorShutter* this, PlayState* play); void DoorShutter_PhantomGanonBarsRaise(DoorShutter* this, PlayState* play); @@ -338,9 +338,17 @@ static void* sBossDoorTextures[] = { void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc) { this->actionFunc = actionFunc; - this->unk_16F = 0; + this->actionTimer = 0; } +/** + * Setup the correct action depending on the door type. + * + * This function is called repeatedly and not just on actor init, to check the door being barred, + * and to handle door types that make the door behave different on the front/back sides. + * + * @return true if the door is barred + */ s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&this->dyna.actor)]; s8 frontRoom = transitionEntry->sides[0].room; @@ -349,6 +357,7 @@ s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { if (doorType != SHUTTER_KEY_LOCKED) { if (frontRoom == transitionEntry->sides[1].room) { + // if player is in front if (ABS((s16)(this->dyna.actor.shape.rot.y - this->dyna.actor.yawTowardsPlayer)) < 0x4000) { frontRoom = -1; } @@ -356,8 +365,10 @@ s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { if (frontRoom == this->dyna.actor.room) { if (doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) { // Swap the back clear to the front clear doorType = SHUTTER_FRONT_CLEAR; + } else if (doorType == SHUTTER_BOSS) { + doorType = SHUTTER_BACK_LOCKED; } else { - doorType = (doorType == SHUTTER_BOSS) ? SHUTTER_BACK_LOCKED : SHUTTER; + doorType = SHUTTER; } } } @@ -365,23 +376,24 @@ s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { if (doorType == SHUTTER_FRONT_CLEAR) { if (!Flags_GetClear(play, this->dyna.actor.room)) { - DoorShutter_SetupAction(this, func_80996A54); + DoorShutter_SetupAction(this, DoorShutter_WaitClear); this->barsClosedAmount = 1.0f; return true; } } else if (doorType == SHUTTER_FRONT_SWITCH || doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) { - if (!Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80996EE8); + if (!Flags_GetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor))) { + DoorShutter_SetupAction(this, DoorShutter_BarAndWaitSwitchFlag); this->barsClosedAmount = 1.0f; return true; + } else { + DoorShutter_SetupAction(this, DoorShutter_UnbarredCheckSwitchFlag); + return false; } - DoorShutter_SetupAction(this, func_80996F98); - return false; } else if (doorType == SHUTTER_BACK_LOCKED) { - DoorShutter_SetupAction(this, func_80996B00); + DoorShutter_SetupAction(this, DoorShutter_Unopenable); return false; } - DoorShutter_SetupAction(this, func_80996B0C); + DoorShutter_SetupAction(this, DoorShutter_Idle); return false; } @@ -396,7 +408,7 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); this->dyna.actor.home.pos.z = this->dyna.actor.shape.yOffset; DynaPolyActor_Init(&this->dyna, 0); - this->doorType = (this->dyna.actor.params >> 6) & 0xF; + this->doorType = DOORSHUTTER_GET_TYPE(&this->dyna.actor); styleType = sTypeStyles[this->doorType]; if (styleType < 0) { @@ -417,7 +429,7 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { } } this->bossDoorTexIndex = bossDoorInfo->texIndex; - } else { + } else { // DOORSHUTTER_STYLE_PHANTOM_GANON, DOORSHUTTER_STYLE_GOHMA_BLOCK this->dyna.actor.room = -1; } @@ -430,7 +442,7 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { this->styleType = styleType; if (this->doorType == SHUTTER_KEY_LOCKED || this->doorType == SHUTTER_BOSS) { - if (!Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { + if (!Flags_GetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor))) { this->unlockTimer = 10; } Actor_SetFocus(&this->dyna.actor, 60.0f); @@ -474,7 +486,7 @@ void DoorShutter_WaitForObject(DoorShutter* this, PlayState* play) { DoorShutter_SetupAction(this, DoorShutter_GohmaBlockFall); } else { DoorShutter_SetupAction(this, DoorShutter_PhantomGanonBarsRaise); - this->unk_164 = 7; + this->isActive = 7; } } else { DoorShutter_SetupDoor(this, play); @@ -539,13 +551,19 @@ s32 DoorShutter_GetPlayerSide(DoorShutter* this, PlayState* play) { return 0.0f; } -void func_80996A54(DoorShutter* this, PlayState* play) { +/** + * The door is barred and waiting for the room to be cleared. + * + * Either the permanent room clear flag or temporary room clear flag may be set to unbar the door. + * When that happens, the permanent room clear flag is set. + */ +void DoorShutter_WaitClear(DoorShutter* this, PlayState* play) { if (Flags_GetClear(play, this->dyna.actor.room) || Flags_GetTempClear(play, this->dyna.actor.room)) { Flags_SetClear(play, this->dyna.actor.room); - DoorShutter_SetupAction(this, func_80997150); + DoorShutter_SetupAction(this, DoorShutter_Unbar); OnePointCutscene_Attention(play, &this->dyna.actor); OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); - this->unk_16F = -100; + this->actionTimer = -100; } else if (DoorShutter_GetPlayerSide(this, play) != 0) { Player* player = GET_PLAYER(play); @@ -553,15 +571,25 @@ void func_80996A54(DoorShutter* this, PlayState* play) { } } -void func_80996B00(DoorShutter* this, PlayState* play) { +/** + * The door cannot be interacted with. + */ +void DoorShutter_Unopenable(DoorShutter* this, PlayState* play) { } -void func_80996B0C(DoorShutter* this, PlayState* play) { - if (this->unk_164 != 0) { - DoorShutter_SetupAction(this, func_80997004); +/** + * The player may open the door. + * If the door is a locked door, having a dungeon key is required and one will be consumed. + * If the door is a boss door, having the boss key is required. + * + * Opening either a locked door or a boss door sets the switch flag taken from actor params. + */ +void DoorShutter_Idle(DoorShutter* this, PlayState* play) { + if (this->isActive) { + DoorShutter_SetupAction(this, DoorShutter_Open); this->dyna.actor.velocity.y = 0.0f; if (this->unlockTimer != 0) { - Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); + Flags_SetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor)); if (this->doorType != SHUTTER_BOSS) { gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--; Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK); @@ -594,7 +622,8 @@ void func_80996B0C(DoorShutter* this, PlayState* play) { } } -void func_80996C60(DoorShutter* this, PlayState* play) { +void DoorShutter_InitOpeningDoorCam(DoorShutter* this, PlayState* play) { + // The actor category is never changed from ACTORCAT_DOOR, this condition always passes if (this->dyna.actor.category == ACTORCAT_DOOR) { Player* player = GET_PLAYER(play); s32 savedGfxType = this->gfxType; @@ -603,19 +632,29 @@ void func_80996C60(DoorShutter* this, PlayState* play) { if (DoorShutter_SetupDoor(this, play)) { doorCamTimer2 = 32; } - DoorShutter_SetupAction(this, func_80997004); + + // Restore action, gfxType and barsClosedAmount after the DoorShutter_SetupDoor call + DoorShutter_SetupAction(this, DoorShutter_Open); this->gfxType = savedGfxType; this->barsClosedAmount = 0.0f; + Camera_ChangeDoorCam(play->cameraPtrs[CAM_ID_MAIN], &this->dyna.actor, player->doorBgCamIndex, 0.0f, 12, doorCamTimer2, 10); } } +/** + * Open the door by progressively sliding it up 200 units. + * Also handles opening Jabu doors, which don't slide like all the other types. + * + * On the first call of opening the door (determined based on y velocity being 0 for non-jabu doors), + * also changes the camera appropriately. + */ s32 DoorShutter_UpdateOpening(DoorShutter* this, PlayState* play) { if (this->gfxType != DOORSHUTTER_GFX_JABU_JABU) { if (this->dyna.actor.velocity.y == 0.0f) { Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_OPEN); - func_80996C60(this, play); + DoorShutter_InitOpeningDoorCam(this, play); } Math_StepToF(&this->dyna.actor.velocity.y, 15.0f, 3.0f); if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 200.0f, @@ -625,7 +664,7 @@ s32 DoorShutter_UpdateOpening(DoorShutter* this, PlayState* play) { } else { if (this->jabuDoorClosedAmount == 100) { Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_BUYODOOR_OPEN); - func_80996C60(this, play); + DoorShutter_InitOpeningDoorCam(this, play); } if (Math_StepToS(&this->jabuDoorClosedAmount, 0, 10)) { return true; @@ -634,6 +673,13 @@ s32 DoorShutter_UpdateOpening(DoorShutter* this, PlayState* play) { return false; } +/** + * Progressively bar or unbar the door. + * + * @param barsClosedAmountTarget 1.0f to bar the door, or 0.0f to unbar. + * + * @return true if the door is fully barred or fully unbarred. + */ s32 DoorShutter_UpdateBarsClosed(DoorShutter* this, PlayState* play, f32 barsClosedAmountTarget) { if (this->barsClosedAmount == (1.0f - barsClosedAmountTarget)) { if (this->gfxType != DOORSHUTTER_GFX_JABU_JABU) { @@ -658,12 +704,15 @@ s32 DoorShutter_UpdateBarsClosed(DoorShutter* this, PlayState* play, f32 barsClo } } -void func_80996EE8(DoorShutter* this, PlayState* play) { +/** + * Bar the door and keep it barred until the switch flag taken from the params is set. + */ +void DoorShutter_BarAndWaitSwitchFlag(DoorShutter* this, PlayState* play) { if (DoorShutter_UpdateBarsClosed(this, play, 1.0f)) { - if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80997150); + if (Flags_GetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor))) { + DoorShutter_SetupAction(this, DoorShutter_Unbar); OnePointCutscene_Attention(play, &this->dyna.actor); - this->unk_16F = -100; + this->actionTimer = -100; } else { if (DoorShutter_GetPlayerSide(this, play) != 0) { Player* player = GET_PLAYER(play); @@ -674,27 +723,39 @@ void func_80996EE8(DoorShutter* this, PlayState* play) { } } -void func_80996F98(DoorShutter* this, PlayState* play) { - if (this->unk_164 == 0 && !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80996EE8); +/** + * The door has been unbarred. + * + * Effectively, this action is only used for switch-flag-barred door types. + * Its purpose is to check the switch flag is still set after the door has been unbarred. + */ +void DoorShutter_UnbarredCheckSwitchFlag(DoorShutter* this, PlayState* play) { + if (!this->isActive && !Flags_GetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor))) { + DoorShutter_SetupAction(this, DoorShutter_BarAndWaitSwitchFlag); } else { - func_80996B0C(this, play); + DoorShutter_Idle(this, play); } } -void func_80997004(DoorShutter* this, PlayState* play) { +/** + * The door is being opened. + * + * The door closes once the player is far enough from the door. + */ +void DoorShutter_Open(DoorShutter* this, PlayState* play) { if (DECR(this->unlockTimer) == 0 && play->roomCtx.status == 0 && DoorShutter_UpdateOpening(this, play)) { - if (((this->doorType == SHUTTER_BOSS) ? 20.0f : 50.0f) < this->dyna.actor.xzDistToPlayer) { + if (this->dyna.actor.xzDistToPlayer > ((this->doorType == SHUTTER_BOSS) ? 20.0f : 50.0f)) { if (DoorShutter_SetupDoor(this, play)) { + // Close faster if the door is barred behind the player this->dyna.actor.velocity.y = 30.0f; } if (this->gfxType != DOORSHUTTER_GFX_JABU_JABU) { Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE); - DoorShutter_SetupAction(this, func_809973E8); + DoorShutter_SetupAction(this, DoorShutter_Close); } else { Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_BUYODOOR_CLOSE); if ((this->doorType == SHUTTER_FRONT_SWITCH || this->doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) && - !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { + !Flags_GetSwitch(play, DOORSHUTTER_GET_SWITCH_FLAG(&this->dyna.actor))) { Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_BUYOSHUTTER_CLOSE); } DoorShutter_SetupAction(this, DoorShutter_JabuDoorClose); @@ -703,29 +764,37 @@ void func_80997004(DoorShutter* this, PlayState* play) { } } -void func_80997150(DoorShutter* this, PlayState* play) { - if (this->unk_16F != 0) { - if (this->unk_16F < 0) { +/** + * The door is being unbarred. + */ +void DoorShutter_Unbar(DoorShutter* this, PlayState* play) { + if (this->actionTimer != 0) { + if (this->actionTimer < 0) { if (play->state.frames % 2 != 0) { - this->unk_16F++; + this->actionTimer++; } - if (this->dyna.actor.category == func_8005B198() || this->unk_16F == 0) { - this->unk_16F = 5; + if (this->dyna.actor.category == func_8005B198() || this->actionTimer == 0) { + this->actionTimer = 5; } } else { - this->unk_16F--; + this->actionTimer--; } } else if (DoorShutter_UpdateBarsClosed(this, play, 0.0f)) { if (!(this->doorType == SHUTTER || this->doorType == SHUTTER_FRONT_CLEAR)) { - DoorShutter_SetupAction(this, func_80996F98); + DoorShutter_SetupAction(this, DoorShutter_UnbarredCheckSwitchFlag); } else { - DoorShutter_SetupAction(this, func_80996B0C); + DoorShutter_SetupAction(this, DoorShutter_Idle); } func_800F5B58(); } } -void func_80997220(DoorShutter* this, PlayState* play) { +/** + * The door has been closed. + * + * The previous room is unloaded. + */ +void DoorShutter_SetupClosed(DoorShutter* this, PlayState* play) { Player* player = GET_PLAYER(play); s8 room = this->dyna.actor.room; @@ -746,15 +815,19 @@ void func_80997220(DoorShutter* this, PlayState* play) { func_80097534(play, &play->roomCtx); Play_SetupRespawnPoint(play, RESPAWN_MODE_DOWN, 0x0EFF); } - this->unk_164 = 0; + this->isActive = false; this->dyna.actor.velocity.y = 0.0f; if (DoorShutter_SetupDoor(this, play) && !(player->stateFlags1 & PLAYER_STATE1_11)) { - DoorShutter_SetupAction(this, func_80997568); + // The door is barred behind the player + DoorShutter_SetupAction(this, DoorShutter_WaitPlayerSurprised); func_8002DF54(play, NULL, PLAYER_CSMODE_2); } } -void func_809973E8(DoorShutter* this, PlayState* play) { +/** + * The door is being closed by sliding downwards to its initial position. + */ +void DoorShutter_Close(DoorShutter* this, PlayState* play) { s32 quakeIndex; if (this->dyna.actor.velocity.y < 20.0f) { @@ -772,18 +845,21 @@ void func_809973E8(DoorShutter* this, PlayState* play) { Quake_SetPerturbations(quakeIndex, 2, 0, 0, 0); Quake_SetDuration(quakeIndex, 10); Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100); - func_80997220(this, play); + DoorShutter_SetupClosed(this, play); } } +/** + * The Jabu door is being closed. + */ void DoorShutter_JabuDoorClose(DoorShutter* this, PlayState* play) { if (Math_StepToS(&this->jabuDoorClosedAmount, 100, 10)) { - func_80997220(this, play); + DoorShutter_SetupClosed(this, play); } } -void func_80997568(DoorShutter* this, PlayState* play) { - if (this->unk_16F++ > 30) { +void DoorShutter_WaitPlayerSurprised(DoorShutter* this, PlayState* play) { + if (this->actionTimer++ > 30) { func_8002DF54(play, NULL, PLAYER_CSMODE_7); DoorShutter_SetupDoor(this, play); } @@ -797,7 +873,7 @@ void DoorShutter_GohmaBlockFall(DoorShutter* this, PlayState* play) { if (!GET_EVENTCHKINF(EVENTCHKINF_70)) { BossGoma* parent = (BossGoma*)this->dyna.actor.parent; - this->unk_164 = 10; + this->isActive = 10; Audio_PlayActorSfx2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); DoorShutter_RequestQuakeAndRumble(play, 2, 10, parent->subCamId); Actor_SpawnFloorDustRing(play, &this->dyna.actor, &this->dyna.actor.world.pos, 70.0f, 20, 8.0f, 500, 10, @@ -810,10 +886,10 @@ void DoorShutter_GohmaBlockBounce(DoorShutter* this, PlayState* play) { f32 bounceFactor; // Bounce a bit (unnoticeable in-game) - if (this->unk_164 != 0) { - this->unk_164--; - bounceFactor = sinf(this->unk_164 * 250.0f / 100.0f); - this->dyna.actor.shape.yOffset = this->unk_164 * 3.0f / 10.0f * bounceFactor; + if (this->isActive != 0) { + this->isActive--; + bounceFactor = sinf(this->isActive * 250.0f / 100.0f); + this->dyna.actor.shape.yOffset = this->isActive * 3.0f / 10.0f * bounceFactor; } } @@ -821,10 +897,10 @@ void DoorShutter_PhantomGanonBarsRaise(DoorShutter* this, PlayState* play) { f32 targetOffsetY; osSyncPrintf("FHG SAKU START !!\n"); - if (this->unk_164 != 0) { - this->unk_164--; + if (this->isActive != 0) { + this->isActive--; } - targetOffsetY = (this->unk_164 % 2 != 0) ? -3.0f : 0.0f; + targetOffsetY = (this->isActive % 2 != 0) ? -3.0f : 0.0f; Math_SmoothStepToF(&this->dyna.actor.world.pos.y, -34.0f + targetOffsetY, 1.0f, 20.0f, 0.0f); osSyncPrintf("FHG SAKU END !!\n"); } diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h index eac14c2f40..4dd268ea84 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h @@ -20,6 +20,11 @@ * */ +#define DOORSHUTTER_GET_TYPE(actor) (((actor)->params >> 6) & 0xF) +#define DOORSHUTTER_GET_SWITCH_FLAG(actor) ((actor)->params & 0x3F) + +#define DOORSHUTTER_PARAMS(type, switchFlag) ((((type) & 0xF) << 6) | ((switchFlag) & 0x3F)) + typedef enum { /* 0x00 */ SHUTTER, /* 0x01 */ SHUTTER_FRONT_CLEAR, @@ -29,14 +34,7 @@ typedef enum { /* 0x05 */ SHUTTER_BOSS, /* 0x06 */ SHUTTER_GOHMA_BLOCK, /* 0x07 */ SHUTTER_FRONT_SWITCH_BACK_CLEAR, - /* 0x08 */ SHUTTER_8, - /* 0x09 */ SHUTTER_9, - /* 0x0A */ SHUTTER_A, - /* 0x0B */ SHUTTER_KEY_LOCKED, - /* 0x0C */ SHUTTER_C, - /* 0x0D */ SHUTTER_D, - /* 0x0E */ SHUTTER_E, - /* 0x0F */ SHUTTER_F + /* 0x0B */ SHUTTER_KEY_LOCKED = 11 } DoorShutterType; struct DoorShutter; @@ -44,8 +42,7 @@ struct DoorShutter; typedef void (*DoorShutterActionFunc)(struct DoorShutter*, PlayState*); typedef struct DoorShutter { - /* 0x0000 */ DynaPolyActor dyna; - /* 0x0164 */ s16 unk_164; + /* 0x0000 */ SLIDING_DOOR_ACTOR_BASE; /* 0x0166 */ s16 jabuDoorClosedAmount; // Ranges from 0 (open) to 100 (closed) /* 0x0168 */ s16 bossDoorTexIndex; /* 0x016A */ u8 doorType; @@ -53,8 +50,8 @@ typedef struct DoorShutter { /* 0x016C */ u8 gfxType; /* 0x016D */ s8 requiredObjBankIndex; /* 0x016E */ s8 unlockTimer; // non-0 if the door is locked, ticks down while the door is unlocking - /* 0x016F */ s8 unk_16F; - /* 0x0170 */ f32 barsClosedAmount; // Ranges from 0.0f (open) to 1.0f (locked) + /* 0x016F */ s8 actionTimer; + /* 0x0170 */ f32 barsClosedAmount; // Ranges from 0.0f (unbarred) to 1.0f (barred) /* 0x0174 */ DoorShutterActionFunc actionFunc; } DoorShutter; // size = 0x0178 diff --git a/src/overlays/actors/ovl_En_fHG/z_en_fhg.c b/src/overlays/actors/ovl_En_fHG/z_en_fhg.c index 096a7cfa0e..3f04705379 100644 --- a/src/overlays/actors/ovl_En_fHG/z_en_fhg.c +++ b/src/overlays/actors/ovl_En_fHG/z_en_fhg.c @@ -138,7 +138,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { if (this->timers[0] == 55) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f, - GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6)); + GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, DOORSHUTTER_PARAMS(SHUTTER_PG_BARS, 0)); } if (this->timers[0] == 51) { Audio_PlayActorSfx2(this->actor.child, NA_SE_EV_SPEAR_FENCE); @@ -177,7 +177,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { if (this->timers[0] == 25) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f, - GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6)); + GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, DOORSHUTTER_PARAMS(SHUTTER_PG_BARS, 0)); } if (this->timers[0] == 21) { Audio_PlayActorSfx2(this->actor.child, NA_SE_EV_SPEAR_FENCE); diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index e631135f03..333f25bca1 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -4579,7 +4579,7 @@ s32 func_80839768(PlayState* play, Player* this, Vec3f* arg2, CollisionPoly** ar } s32 func_80839800(Player* this, PlayState* play) { - DoorShutter* doorShutter; + SlidingDoorActorBase* slidingDoor; DoorActorBase* door; s32 doorDirection; f32 sp78; @@ -4610,9 +4610,9 @@ s32 func_80839800(Player* this, PlayState* play) { sp74 = Math_SinS(doorActor->shape.rot.y); if (this->doorType == PLAYER_DOORTYPE_SLIDING) { - doorShutter = (DoorShutter*)doorActor; + slidingDoor = (SlidingDoorActorBase*)doorActor; - this->currentYaw = doorShutter->dyna.actor.home.rot.y; + this->currentYaw = slidingDoor->dyna.actor.home.rot.y; if (doorDirection > 0) { this->currentYaw -= 0x8000; } @@ -4633,7 +4633,7 @@ s32 func_80839800(Player* this, PlayState* play) { this->unk_45C.x = this->actor.world.pos.x + ((doorDirection * -120.0f) * sp74); this->unk_45C.z = this->actor.world.pos.z + ((doorDirection * -120.0f) * sp78); - doorShutter->unk_164 = 1; + slidingDoor->isActive = true; func_80832224(this); if (this->doorTimer != 0) { @@ -4644,9 +4644,9 @@ s32 func_80839800(Player* this, PlayState* play) { this->linearVelocity = 0.1f; } - if (doorShutter->dyna.actor.category == ACTORCAT_DOOR) { + if (slidingDoor->dyna.actor.category == ACTORCAT_DOOR) { this->doorBgCamIndex = - play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&doorShutter->dyna.actor)] + play->transiActorCtx.list[GET_TRANSITION_ACTOR_INDEX(&slidingDoor->dyna.actor)] .sides[(doorDirection > 0) ? 0 : 1] .bgCamIndex;