This commit is contained in:
Reonu 2025-08-03 19:31:58 +01:00
parent 14b3492792
commit 61d5c8c52b
6 changed files with 330 additions and 123 deletions

View file

@ -22,5 +22,25 @@ vram = 0x80BCF1D0
size = 0x10E0
symbols = [
{ name = "sPamelasFatherAnimationInfo", vram = 0x80bd0008 },
{ 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 },
]

View file

@ -20,3 +20,26 @@ typedef enum PamelasFatherGibdoLimb {
/* 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;

View file

@ -0,0 +1,121 @@
#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;
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;
}

View file

@ -0,0 +1,106 @@
#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_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);
recomp_printf("Skipping\n");
} 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;
}

View file

@ -0,0 +1,59 @@
#include "patches.h"
#include "transform_ids.h"
#include "overlays/actors/ovl_En_Pamera/z_en_pamera.h"
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;
}
}
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;
}

View file

@ -1397,125 +1397,3 @@ RECOMP_PATCH void func_80AADB4C(Actor* thisx, PlayState* play) {
func_80AADF54(play, this);
}
}
#include "overlays/actors/ovl_En_Hg/z_en_hg.h"
extern AnimationInfo sPamelasFatherAnimationInfo[];
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;
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, sPamelasFatherAnimationInfo, HG_ANIM_IDLE);
break;
case 2:
this->csIdList[2] = 0;
this->animIndex = HG_ANIM_LEAN_FORWARD;
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherAnimationInfo, HG_ANIM_LEAN_FORWARD);
break;
case 3:
this->csIdList[2] = 0;
this->animIndex = HG_ANIM_CURL_UP;
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherAnimationInfo, 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, sPamelasFatherAnimationInfo, HG_ANIM_PANIC);
break;
case 5:
this->animIndex = HG_ANIM_LURCH_FORWARD;
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherAnimationInfo, 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, sPamelasFatherAnimationInfo, HG_ANIM_REACH_FORWARD);
break;
case HG_ANIM_CURL_UP:
this->animIndex = HG_ANIM_CROUCHED_PANIC;
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherAnimationInfo, 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;
}