From b035cdb6055248b6926591432c8dbe6646325e1b Mon Sep 17 00:00:00 2001 From: Reonu <15913880+Reonu@users.noreply.github.com> Date: Mon, 4 Aug 2025 00:50:06 +0100 Subject: [PATCH] Fix all the interpolation glitches in the Gibdo Mask cutscene (#641) --- patches/camera_transform_tagging.c | 11 ++ patches/custom_syms.toml | 30 +++++ .../object_harfgibud/object_harfgibud.h | 45 +++++++ .../objects/object_pamera/object_pamera.h | 26 ++++ patches/gibdo_mask_cutscene_father_gibdo.c | 123 ++++++++++++++++++ patches/gibdo_mask_cutscene_father_human.c | 107 +++++++++++++++ patches/gibdo_mask_cutscene_mask.c | 26 ++++ patches/gibdo_mask_cutscene_pamela.c | 74 +++++++++++ 8 files changed, 442 insertions(+) create mode 100644 patches/dummy_headers/objects/object_harfgibud/object_harfgibud.h create mode 100644 patches/dummy_headers/objects/object_pamera/object_pamera.h create mode 100644 patches/gibdo_mask_cutscene_father_gibdo.c create mode 100644 patches/gibdo_mask_cutscene_father_human.c create mode 100644 patches/gibdo_mask_cutscene_mask.c create mode 100644 patches/gibdo_mask_cutscene_pamela.c diff --git a/patches/camera_transform_tagging.c b/patches/camera_transform_tagging.c index b077b28..60f0d00 100644 --- a/patches/camera_transform_tagging.c +++ b/patches/camera_transform_tagging.c @@ -76,6 +76,17 @@ void camera_post_play_update(PlayState* play) { if (force_interpolation) { force_camera_interpolation(); } + // Dedicated section for workarounds where the heuristic fails to detect small camera teleports. + bool force_no_interpolation = false; + + // Music Box House. The camera gets teleported by a very small amount when Link gets the Gibdo mask. + if (play->sceneId == SCENE_MUSICHOUSE && play->csCtx.scriptIndex == 2 && play->csCtx.curFrame == 525 && active_cam->setting == CAM_SET_FREE0) { + force_no_interpolation = true; + } + + if (force_no_interpolation) { + force_camera_skip_interpolation(); + } } } } diff --git a/patches/custom_syms.toml b/patches/custom_syms.toml index 9128278..c04a941 100644 --- a/patches/custom_syms.toml +++ b/patches/custom_syms.toml @@ -14,3 +14,33 @@ symbols = [ { name = "FileSelect_Init_NORELOCATE", vram = 0x80813C98 }, { name = "DayTelop_Init_NORELOCATE", vram = 0x80815820 }, ] + +[[section]] +name = "..ovl_En_Hg" +rom = 0x01034170 +vram = 0x80BCF1D0 +size = 0x10E0 + +symbols = [ + { name = "sPamelasFatherGibdoAnimationInfo", vram = 0x80bd0008 }, +] + +[[section]] +name = "..ovl_En_Hgo" +rom = 0x01035250 +vram = 0x80BD02B0 +size = 0xF30 + +symbols = [ + { name = "sPamelasFatherHumanAnimationInfo", vram = 0x80BD0EA0 }, +] + +[[section]] +name = "..ovl_En_Pamera" +rom = 0x0103D250 +vram = 0x80BD82B0 +size = 0x2780 + +symbols = [ + { name = "sPamelaAnimationInfo", vram = 0x80BDA4B8 }, +] diff --git a/patches/dummy_headers/objects/object_harfgibud/object_harfgibud.h b/patches/dummy_headers/objects/object_harfgibud/object_harfgibud.h new file mode 100644 index 0000000..97e77d1 --- /dev/null +++ b/patches/dummy_headers/objects/object_harfgibud/object_harfgibud.h @@ -0,0 +1,45 @@ +typedef enum PamelasFatherGibdoLimb { + /* 0x00 */ PAMELAS_FATHER_GIBDO_LIMB_NONE, + /* 0x01 */ PAMELAS_FATHER_GIBDO_LIMB_ROOT, + /* 0x02 */ PAMELAS_FATHER_GIBDO_LIMB_ABDOMEN, + /* 0x03 */ PAMELAS_FATHER_GIBDO_LIMB_CHEST, + /* 0x04 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_UPPER_ARM, + /* 0x05 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOREARM, + /* 0x06 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_HAND, + /* 0x07 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_UPPER_ARM, + /* 0x08 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOREARM, + /* 0x09 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_HAND, + /* 0x0A */ PAMELAS_FATHER_GIBDO_LIMB_EYEBROWS, + /* 0x0B */ PAMELAS_FATHER_GIBDO_LIMB_HEAD, + /* 0x0C */ PAMELAS_FATHER_GIBDO_LIMB_PELVIS, + /* 0x0D */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_THIGH, + /* 0x0E */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_SHIN, + /* 0x0F */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOOT, + /* 0x10 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_THIGH, + /* 0x11 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_SHIN, + /* 0x12 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOOT, + /* 0x13 */ PAMELAS_FATHER_GIBDO_LIMB_MAX +} PamelasFatherGibdoLimb; + +typedef enum PamelasFatherHumanLimb { + /* 0x00 */ PAMELAS_FATHER_HUMAN_LIMB_NONE, + /* 0x01 */ PAMELAS_FATHER_HUMAN_LIMB_ROOT, + /* 0x02 */ PAMELAS_FATHER_HUMAN_LIMB_ABDOMEN, + /* 0x03 */ PAMELAS_FATHER_HUMAN_LIMB_CHEST, + /* 0x04 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_UPPER_ARM, + /* 0x05 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOREARM, + /* 0x06 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_HAND, + /* 0x07 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_UPPER_ARM, + /* 0x08 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOREARM, + /* 0x09 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_HAND, + /* 0x0A */ PAMELAS_FATHER_HUMAN_LIMB_EYEBROWS, + /* 0x0B */ PAMELAS_FATHER_HUMAN_LIMB_HEAD, + /* 0x0C */ PAMELAS_FATHER_HUMAN_LIMB_PELVIS, + /* 0x0D */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_THIGH, + /* 0x0E */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_SHIN, + /* 0x0F */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOOT, + /* 0x10 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_THIGH, + /* 0x11 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_SHIN, + /* 0x12 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOOT, + /* 0x13 */ PAMELAS_FATHER_HUMAN_LIMB_MAX +} PamelasFatherHumanLimb; diff --git a/patches/dummy_headers/objects/object_pamera/object_pamera.h b/patches/dummy_headers/objects/object_pamera/object_pamera.h new file mode 100644 index 0000000..5baeacf --- /dev/null +++ b/patches/dummy_headers/objects/object_pamera/object_pamera.h @@ -0,0 +1,26 @@ +typedef enum PamelaLimb { + /* 0x00 */ PAMELA_LIMB_NONE, + /* 0x01 */ PAMELA_LIMB_ROOT, + /* 0x02 */ PAMELA_LIMB_UPPER_BODY_ROOT, + /* 0x03 */ PAMELA_LIMB_LEFT_UPPER_ARM, + /* 0x04 */ PAMELA_LIMB_LEFT_FOREARM, + /* 0x05 */ PAMELA_LIMB_LEFT_HAND, + /* 0x06 */ PAMELA_LIMB_RIGHT_UPPER_ARM, + /* 0x07 */ PAMELA_LIMB_RIGHT_FOREARM, + /* 0x08 */ PAMELA_LIMB_RIGHT_HAND, + /* 0x09 */ PAMELA_LIMB_HEAD, + /* 0x0A */ PAMELA_LIMB_HAIR_END, + /* 0x0B */ PAMELA_LIMB_CHEST, + /* 0x0C */ PAMELA_LIMB_NECK, + /* 0x0D */ PAMELA_LIMB_LEFT_THIGH, + /* 0x0E */ PAMELA_LIMB_LEFT_LEG, + /* 0x0F */ PAMELA_LIMB_LEFT_FOOT, + /* 0x10 */ PAMELA_LIMB_RIGHT_THIGH, + /* 0x11 */ PAMELA_LIMB_RIGHT_LEG, + /* 0x12 */ PAMELA_LIMB_RIGHT_FOOT, + /* 0x13 */ PAMELA_LIMB_FRONT_DRESS, + /* 0x14 */ PAMELA_LIMB_BACK_DRESS, + /* 0x15 */ PAMELA_LIMB_ABDOMEN, + /* 0x16 */ PAMELA_LIMB_PELVIS, + /* 0x17 */ PAMELA_LIMB_MAX +} PamelaLimb; diff --git a/patches/gibdo_mask_cutscene_father_gibdo.c b/patches/gibdo_mask_cutscene_father_gibdo.c new file mode 100644 index 0000000..cab305b --- /dev/null +++ b/patches/gibdo_mask_cutscene_father_gibdo.c @@ -0,0 +1,123 @@ +#include "patches.h" +#include "transform_ids.h" +#include "overlays/actors/ovl_En_Hg/z_en_hg.h" + +extern AnimationInfo sPamelasFatherGibdoAnimationInfo[]; +extern void EnHg_SetupWait(EnHg* this); + +typedef enum { + /* 0 */ HG_ANIM_IDLE, + /* 1 */ HG_ANIM_LURCH_FORWARD, + /* 2 */ HG_ANIM_RECOIL, + /* 3 */ HG_ANIM_LEAN_FORWARD, + /* 4 */ HG_ANIM_REACH_FORWARD, + /* 5 */ HG_ANIM_CURL_UP, + /* 6 */ HG_ANIM_CROUCHED_PANIC, + /* 7 */ HG_ANIM_PANIC, + /* 8 */ HG_ANIM_MAX +} HgAnimation; + +typedef enum { + /* 0 */ HG_CS_FIRST_ENCOUNTER, + /* 1 */ HG_CS_GET_MASK, + /* 2 */ HG_CS_SUBSEQUENT_ENCOUNTER, + /* 3 */ HG_CS_SONG_OF_HEALING +} HgCsIndex; + +// @recomp Skip interpolation when the animations change during the cutscene, as the +// animation changes are meant to happen at the same time as the camera cuts. +void EnHg_HandleCutscene(EnHg* this, PlayState* play) { + if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_484)) { + s32 cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_484); + + if (this->csIdList[3] != play->csCtx.actorCues[cueChannel]->id) { + this->csIdList[3] = play->csCtx.actorCues[cueChannel]->id; + switch (play->csCtx.actorCues[cueChannel]->id) { + case 1: + this->animIndex = HG_ANIM_IDLE; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_IDLE); + break; + + case 2: + this->csIdList[2] = 0; + this->animIndex = HG_ANIM_LEAN_FORWARD; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_LEAN_FORWARD); + break; + + case 3: + this->csIdList[2] = 0; + this->animIndex = HG_ANIM_CURL_UP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_CURL_UP); + break; + + case 4: + this->csIdList[2] = 0; + this->animIndex = HG_ANIM_PANIC; + if ((this->csIdIndex == HG_CS_GET_MASK) || (this->csIdIndex == HG_CS_SONG_OF_HEALING)) { + Audio_PlaySfx_2(NA_SE_EN_HALF_REDEAD_TRANS); + } + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_PANIC); + break; + + case 5: + this->animIndex = HG_ANIM_LURCH_FORWARD; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_LURCH_FORWARD); + break; + + case 6: + SET_WEEKEVENTREG(WEEKEVENTREG_75_20); + Actor_Kill(&this->actor); + break; + + default: + break; + } + actor_set_interpolation_skipped(&this->actor); + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->animIndex) { + case HG_ANIM_LEAN_FORWARD: + this->animIndex = HG_ANIM_REACH_FORWARD; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_REACH_FORWARD); + break; + + case HG_ANIM_CURL_UP: + this->animIndex = HG_ANIM_CROUCHED_PANIC; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_CROUCHED_PANIC); + break; + + default: + break; + } + actor_set_interpolation_skipped(&this->actor); + } + + switch (this->animIndex) { + case HG_ANIM_LEAN_FORWARD: + case HG_ANIM_REACH_FORWARD: + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_LOOP - SFX_FLAG); + break; + + case HG_ANIM_CURL_UP: + case HG_ANIM_CROUCHED_PANIC: + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_SCREAME - SFX_FLAG); + break; + + case HG_ANIM_PANIC: + if ((this->csIdIndex == HG_CS_FIRST_ENCOUNTER) || (this->csIdIndex == HG_CS_SUBSEQUENT_ENCOUNTER)) { + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_SCREAME - SFX_FLAG); + } + break; + + default: + break; + } + + Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel); + return; + + } else if (play->csCtx.state == CS_STATE_IDLE) { + EnHg_SetupWait(this); + } + + this->csIdList[3] = 99; +} diff --git a/patches/gibdo_mask_cutscene_father_human.c b/patches/gibdo_mask_cutscene_father_human.c new file mode 100644 index 0000000..2ed5fee --- /dev/null +++ b/patches/gibdo_mask_cutscene_father_human.c @@ -0,0 +1,107 @@ +#include "patches.h" +#include "transform_ids.h" +#include "overlays/actors/ovl_En_Hgo/z_en_hgo.h" + +typedef enum { + /* 0 */ HGO_ANIM_ARMS_FOLDED, + /* 1 */ HGO_ANIM_ASTONISHED, + /* 2 */ HGO_ANIM_KNEEL_DOWN_AND_HUG, + /* 3 */ HGO_ANIM_CONSOLE, + /* 4 */ HGO_ANIM_CONSOLE_HEAD_UP, + /* 5 */ HGO_ANIM_REACH_DOWN_TO_LIFT, + /* 6 */ HGO_ANIM_TOSS, + /* 7 */ HGO_ANIM_MAX +} HgoAnimation; + +extern AnimationInfo sPamelasFatherHumanAnimationInfo[]; +extern void EnHgo_Draw(Actor* thisx, PlayState* play); +extern void EnHgo_DoNothing(EnHgo* this, PlayState* play); +extern void EnHgo_SetupInitCollision(EnHgo* this); + +// @recomp Skip interpolation when the animations change during the cutscene, as the +// animation changes are meant to happen at the same time as the camera cuts. +RECOMP_PATCH s32 EnHgo_HandleCsAction(EnHgo* this, PlayState* play) { + s32 cueChannel; + + if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_486)) { + cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_486); + if (this->cueId != play->csCtx.actorCues[cueChannel]->id) { + this->cueId = play->csCtx.actorCues[cueChannel]->id; + switch (play->csCtx.actorCues[cueChannel]->id) { + case 1: + this->animIndex = HGO_ANIM_ARMS_FOLDED; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ARMS_FOLDED); + break; + + case 2: + this->actor.draw = EnHgo_Draw; + this->animIndex = HGO_ANIM_ASTONISHED; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ASTONISHED); + break; + + case 3: + this->animIndex = HGO_ANIM_KNEEL_DOWN_AND_HUG; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_KNEEL_DOWN_AND_HUG); + break; + + case 4: + this->animIndex = HGO_ANIM_CONSOLE; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE); + break; + + case 5: + this->animIndex = HGO_ANIM_CONSOLE_HEAD_UP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE_HEAD_UP); + break; + + case 6: + this->animIndex = HGO_ANIM_REACH_DOWN_TO_LIFT; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_REACH_DOWN_TO_LIFT); + break; + + default: + break; + } + actor_set_interpolation_skipped(&this->actor); + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->animIndex) { + case HGO_ANIM_ASTONISHED: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && !this->isInCutscene) { + this->isInCutscene = true; + if ((gSaveContext.sceneLayer == 0) && + ((play->csCtx.scriptIndex == 2) || (play->csCtx.scriptIndex == 4))) { + Actor_PlaySfx(&this->actor, NA_SE_VO_GBVO02); + } + } + break; + + case HGO_ANIM_KNEEL_DOWN_AND_HUG: + this->animIndex = HGO_ANIM_CONSOLE; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE); + break; + + case HGO_ANIM_REACH_DOWN_TO_LIFT: + this->animIndex = HGO_ANIM_TOSS; + Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_TOSS); + + default: + break; + + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel); + return true; + } + + if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20) && + (this->actionFunc == EnHgo_DoNothing)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y, + this->actor.focus.pos.z, 7, 0, 0, 0x7F5A); + EnHgo_SetupInitCollision(this); + } + + this->cueId = 99; + return false; +} diff --git a/patches/gibdo_mask_cutscene_mask.c b/patches/gibdo_mask_cutscene_mask.c new file mode 100644 index 0000000..7923f87 --- /dev/null +++ b/patches/gibdo_mask_cutscene_mask.c @@ -0,0 +1,26 @@ +#include "patches.h" +#include "transform_ids.h" +#include "overlays/actors/ovl_Dm_Char05/z_dm_char05.h" + +extern void func_80AADF54(PlayState* play, DmChar05* this); + +// @recomp Patched to avoid an interpolation glitch in Pamela's dad's cutscene +// that happens when the mask is meant to teleport offscreen. +RECOMP_PATCH void func_80AADB4C(Actor* thisx, PlayState* play) { + DmChar05* this = (DmChar05*)thisx; + if (this->unk_18E == 0) { + if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_518) && + (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id != 1)) { + // @recomp During this cue the mask does nothing other than teleport offscreen and stay still, + // so we can just skip interpolation the entire time. + if (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id == 3) { + actor_set_interpolation_skipped(thisx); + } + Gfx_SetupDL25_Opa(play->state.gfxCtx); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, &this->actor); + } + } else if (this->unk_18E == 1) { + func_80AADF54(play, this); + } +} diff --git a/patches/gibdo_mask_cutscene_pamela.c b/patches/gibdo_mask_cutscene_pamela.c new file mode 100644 index 0000000..1f7f5a8 --- /dev/null +++ b/patches/gibdo_mask_cutscene_pamela.c @@ -0,0 +1,74 @@ +#include "patches.h" +#include "transform_ids.h" +#include "overlays/actors/ovl_En_Pamera/z_en_pamera.h" + +extern void EnPamera_Draw(Actor* thisx, PlayState* play); +extern void func_80BD9E88(EnPamera* this); +extern void func_80BD9EE0(EnPamera* this); +extern void func_80BDA038(EnPamera* this); +extern void func_80BDA0A0(EnPamera* this); +extern void func_80BDA170(EnPamera* this); +extern void func_80BDA288(EnPamera* this); +extern void func_80BD994C(EnPamera* this, PlayState* play); +extern void EnPamera_HandleDialogue(EnPamera* this, PlayState* play); +extern void func_80BD9904(EnPamera* this); +extern void func_80BD9E60(EnPamera* this); + +// @recomp Skip interpolation when the animations change during the cutscene, as the +// animation changes are meant to happen at the same time as the camera cuts. +RECOMP_PATCH s32 func_80BD9CB8(EnPamera* this, PlayState* play) { + s32 cueChannel; + + if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_485)) { + cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_485); + if (this->cueId != play->csCtx.actorCues[cueChannel]->id) { + this->cueId = play->csCtx.actorCues[cueChannel]->id; + + switch (play->csCtx.actorCues[cueChannel]->id) { + case 1: + func_80BD9E88(this); + break; + + case 2: + if (this->actor.draw == NULL) { + this->actor.draw = EnPamera_Draw; + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + } + func_80BD9EE0(this); + break; + + case 3: + func_80BDA038(this); + break; + + case 4: + func_80BDA0A0(this); + break; + + case 5: + func_80BDA170(this); + break; + + case 6: + func_80BDA288(this); + break; + + default: + break; + } + actor_set_interpolation_skipped(&this->actor); + } + Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel); + this->setupFunc(this, play); + return true; + } + if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20)) { + if ((this->actionFunc != func_80BD994C) && (this->actionFunc != EnPamera_HandleDialogue)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80BD9904(this); + func_80BD9E60(this); + } + } + this->cueId = 99; + return false; +}