diff --git a/include/functions.h b/include/functions.h index 3c8c8a2f21..49efe79ae9 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3033,7 +3033,7 @@ void func_80169600(GlobalContext* globalCtx, s16 param_2); Camera* Play_GetCamera(GlobalContext* globalCtx, s16 index); s32 Play_CameraSetAtEye(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye); void func_8016981C(GlobalContext* globalCtx, s16 arg1, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4); -// void func_80169940(void); +void func_80169940(GlobalContext* globalCtx, s16 camId, f32 arg2); // void func_80169988(void); void func_801699D4(GlobalContext* globalCtx, s16 arg1, s16 arg2); // void func_80169A50(void); @@ -3838,12 +3838,12 @@ void func_8019E014(void); // void func_8019EB2C(void); // void func_8019F024(void); // void func_8019F05C(void); +void func_8019F170(Vec3f* pos, u16 sfxId); +void func_8019F1C0(Vec3f* pos, u16 sfxId); void play_sound(u16 sfxId); void func_8019F128(u16 sfxId); -// void func_8019F170(void); -void func_8019F1C0(Vec3f* pos, u16 sfxId); -void func_8019F208(void); -void func_8019F230(void); // Plays "No" sound +void func_8019F208(void); // decide +void func_8019F230(void); // cancel // void func_8019F258(void); // void func_8019F300(void); void func_8019F420(Vec3f* pos, u16 sfxId); diff --git a/include/z64.h b/include/z64.h index dbc7b60f4f..2425f47be3 100644 --- a/include/z64.h +++ b/include/z64.h @@ -948,7 +948,7 @@ typedef struct { /* 0x11F23 */ UNK_TYPE1 pad11F23[0xFD]; /* 0x12020 */ u8 unk12020; /* 0x12021 */ u8 choiceIndex; - /* 0x12022 */ UNK_TYPE1 unk12022; + /* 0x12022 */ u8 unk12022; /* 0x12023 */ u8 unk12023; /* 0x12024 */ UNK_TYPE1 unk12024[0x6]; /* 0x1202A */ u16 unk1202A; @@ -956,7 +956,9 @@ typedef struct { /* 0x1202E */ u16 unk1202E; /* 0x12030 */ UNK_TYPE1 pad12030[0x14]; /* 0x12044 */ s16 unk12044; - /* 0x12046 */ UNK_TYPE1 pad12046[0x24]; + /* 0x12046 */ UNK_TYPE1 pad12046[0x2]; + /* 0x12048 */ u8 unk12048; // EnKakasi + /* 0x12049 */ UNK_TYPE1 pad12049[0x21]; /* 0x1206A */ s16 unk1206A; /* 0x1206C */ s32 unk1206C; /* 0x12070 */ UNK_TYPE1 pad12070[0x8]; diff --git a/spec b/spec index 3e5f389111..2983af4dc4 100644 --- a/spec +++ b/spec @@ -1788,8 +1788,7 @@ beginseg name "ovl_En_Kakasi" compress include "build/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.o" - include "build/data/ovl_En_Kakasi/ovl_En_Kakasi.data.o" - include "build/data/ovl_En_Kakasi/ovl_En_Kakasi.reloc.o" + include "build/src/overlays/actors/ovl_En_Kakasi/ovl_En_Kakasi_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 0617bcdd37..436386af91 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -1,7 +1,7 @@ /* * File: z_en_kakasi.c * Overlay: ovl_En_Kakasi - * Description: Pierre + * Description: Pierre the Scarecorw */ #include "z_en_kakasi.h" @@ -15,28 +15,55 @@ void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx); void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8096FCC4(EnKakasi* this, GlobalContext* globalCtx); -void func_8096FE00(EnKakasi* this, GlobalContext* globalCtx); -void func_8097006C(EnKakasi* this, GlobalContext* globalCtx); -void func_80970658(EnKakasi* this, GlobalContext* globalCtx); -void func_80970740(EnKakasi* this, GlobalContext* globalCtx); -void func_80970978(EnKakasi* this, GlobalContext* globalCtx); -void func_80970A9C(EnKakasi* this, GlobalContext* globalCtx); -void func_80970F20(EnKakasi* this, GlobalContext* globalCtx); -void func_80971064(EnKakasi* this, GlobalContext* globalCtx); -void func_80971430(EnKakasi* this, GlobalContext* globalCtx); -void func_809714BC(EnKakasi* this, GlobalContext* globalCtx); -void func_809717D0(EnKakasi* this, GlobalContext* globalCtx); -void func_8097185C(EnKakasi* this, GlobalContext* globalCtx); -void func_8097193C(EnKakasi* this, GlobalContext* globalCtx); -void func_80971A64(EnKakasi* this, GlobalContext* globalCtx); -void func_80971AD4(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupPostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_InitTimeSkipDialogue(EnKakasi* this); +void EnKakasi_SetupIdleStanding(EnKakasi* this); + +void EnKakasi_8096F88C(GlobalContext* globalCtx, EnKakasi* this); + +void EnKakasi_TimeSkipDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_IdleStanding(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_OcarinaRemark(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_TeachingSong(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_PostSongLearnTwirl(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_PostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupDigAway(EnKakasi* this); +void EnKakasi_DiggingAway(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RisenDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupIdleUnderground(EnKakasi* this); +void EnKakasi_IdleUnderground(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupIdleRisen(EnKakasi* this); +void EnKakasi_IdleRisen(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupRiseOutOfGround(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RisingOutOfGround(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_DancingRemark(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupDanceNightAway(EnKakasi* this); +void EnKakasi_DancingNightAway(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_DoNothing(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RegularDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupSongTeach(EnKakasi* this, GlobalContext* globalCtx); + +void EnKakasi_SetupDialogue(EnKakasi* this); + +void EnKakasi_LimbDraw(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, struct Actor* actor); -#if 0 -// static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_80971D80 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 70, 0, { 0, 0, 0 } }, }; @@ -52,80 +79,1092 @@ const ActorInit En_Kakasi_InitVars = { (ActorFunc)EnKakasi_Draw, }; -#endif +static Vec3f D_80971DCC[] = { + { 0.0f, 60.0f, 60.0f }, { 40.0f, 40.0f, 50.0f }, { -40.0f, 40.0f, 50.0f }, + { 40.0f, 20.0f, 110.0f }, { -40.0f, 20.0f, 110.0f }, { 0.0f, 80.0f, 60.0f }, + { 50.0f, 40.0f, -30.0f }, { -50.0f, 40.0f, -30.0f }, { 0.0f, 50.0f, 60.0f }, +}; +Vec3f D_80971E38[] = { + { 0.0f, 55.0f, 60.0f }, { 0.0f, 55.0f, 60.0f }, { -80.0f, 35.0f, 15.0f }, { 80.0f, 45.0f, 15.0f }, + { -10.0f, 35.0f, 65.0f }, { 0.0f, 110.0f, 180.0f }, { 0.0f, 60.0f, 70.0f }, { 0.0f, 60.0f, 70.0f }, + { -80.0f, 50.0f, 40.0f }, { 0.0f, -10.0f, 50.0f }, { 80.0f, 50.0f, 40.0f }, { 0.0f, 120.0f, 40.0f }, + { 0.0f, 28.0f, -50.0f }, { 0.0f, 60.0f, 50.0f }, { 0.0f, 80.0f, 160.0f }, +}; -extern ColliderCylinderInit D_80971D80; +Vec3f D_80971EEC[] = { + { 12.0f, 1.0f, 2.0f }, { 12.0f, 1.0f, 2.0f }, { 2.0f, -6.0f, 0.0f }, { 12.0f, -6.0f, -10.0f }, + { -88.0f, 14.0, -10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, + { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, + { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, +}; -extern UNK_TYPE D_06000214; +Vec3f D_80971FA0[] = { + { -50.0f, 160.0f, -40.0f }, { -50.0f, 160.0f, -40.0f }, { -20.0f, 80.0f, 60.0f }, + { 57.0f, 60.0f, 120.0f }, { 27.0f, 80.0f, 60.0f }, { -3.0f, 50.0f, 70.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Destroy.s") +Vec3f D_80971FE8[] = { + { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { -10.0f, -5.0f, 0.0f }, + { 10.0f, -10.0f, 7.0f }, { 20.0f, 5.0f, 2.0f }, { 10.0f, 5.0f, 2.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Init.s") +// both use in digging away function +Vec3f D_80972030 = { -3.0f, 50.0f, 90.0f }; +Vec3f D_8097203C = { 10.0f, -15.0f, 2.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F800.s") +typedef enum { + /* 0x0 */ ENKAKASI_ANIM_ARMS_CROSSED_ROCKING, // arms crossed and rocking back and forth + /* 0x1 */ ENKAKASI_ANIM_SIDEWAYS_SHAKING, + /* 0x2 */ ENKAKASI_ANIM_HOPPING_REGULAR, // bounce bounce bounce (repeat) + /* 0x3 */ ENKAKASI_ANIM_SPIN_REACH_OFFER, // spin and then reaching toward player + /* 0x4 */ ENKAKASI_ANIM_TWIRL, // slower cinimatic twirl + /* 0x5 */ ENKAKASI_ANIM_ARMS_CROSSED_STILL, // arms crossed but still, also some noise sfx + /* 0x6 */ ENKAKASI_ANIM_WAVE, // "wave" short sideways shake, stops early, partial? unused? + /* 0x7 */ ENKAKASI_ANIM_SLOWROLL, // partial bounch, ends looking left, OFFER anim takes over + /* 0x8 */ ENKAKASI_ANIM_IDLE, // slow stretching wiggle, ends in regular position +} EnKakasi_Animations; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F88C.s") +extern AnimationHeader D_06007444; +extern AnimationHeader D_0600686C; +extern AnimationHeader D_060081A4; +extern AnimationHeader D_06007B90; +extern AnimationHeader D_060071EC; +extern AnimationHeader D_06007444; +extern AnimationHeader D_0600686C; +extern AnimationHeader D_060081A4; +extern AnimationHeader D_06000214; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F8D8.s") +static AnimationHeader* kakasiAnimations[] = { + &D_06007444, &D_0600686C, &D_060081A4, &D_06007B90, &D_060071EC, &D_06007444, &D_0600686C, &D_060081A4, &D_06000214, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FA18.s") +static u8 sAnimModes[] = { ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE, + ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_ONCE }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FAAC.s") +void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FBB8.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FC8C.s") +extern FlexSkeletonHeader D_060065B0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FCC4.s") +void EnKakasi_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + s32 tempCutscene; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FDE8.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &D_80971D80); + SkelAnime_InitFlex(globalCtx, &this->skelanime, &D_060065B0, &D_06000214, 0, 0, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FE00.s") + this->songSummonDist = GET_KAKASI_SUMMON_DISTANCE(this) * 20.0f; + if (this->songSummonDist < 40.0f) { + this->songSummonDist = 40.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970008.s") + this->unkHeight = (this->actor.world.rot.z * 20.0f) + 60.0f; + this->actor.world.rot.z = 0; + this->actor.targetMode = 0; + if (this->actor.world.rot.x > 0 && this->actor.world.rot.x < 8) { + this->actor.targetMode = this->actor.world.rot.x - 1; + } + this->actor.shape.rot.y = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097006C.s") + this->aboveGroundStatus = GET_KAKASI_ABOVE_GROUND(this); + this->actor.world.rot.x = 0; + this->actor.flags |= 0x400; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809705E4.s") + i = 0; + tempCutscene = this->actor.cutscene; + while (tempCutscene != -1) { + // This might be a fake match, no others found yet + tempCutscene = ActorCutscene_GetAdditionalCutscene(this->actorCutscenes[i] = tempCutscene); + i++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970658.s") + if (this->aboveGroundStatus) { + if (gSaveContext.weekEventReg[79] & 0x8) { + this->aboveGroundStatus = ENKAKASI_ABOVE_GROUND_TYPE; + this->songSummonDist = 80.0f; + EnKakasi_SetupIdleUnderground(this); + } else { + Actor_SetHeight(&this->actor, 60.0f); + this->unkFunc = EnKakasi_8096F88C; + if (gSaveContext.weekEventReg[83] & 0x1) { + EnKakasi_InitTimeSkipDialogue(this); + } else { + EnKakasi_SetupIdleStanding(this); + } + } + } else { + EnKakasi_SetupIdleUnderground(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970740.s") +void EnKakasi_SetAnimation(EnKakasi* this, s32 index) { + this->animIndex = index; + this->animeFrameCount = Animation_GetLastFrame(&kakasiAnimations[this->animIndex]->common); + // 1: regular playback speed, 0: starting frame + Animation_Change(&this->skelanime, kakasiAnimations[this->animIndex], 1.0f, 0.0f, this->animeFrameCount, + sAnimModes[this->animIndex], -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970978.s") +/* + * set by init, called... nowhere? left over from OOT? + */ +void EnKakasi_8096F88C(GlobalContext* globalCtx, EnKakasi* this) { + func_8013A530(globalCtx, &this->actor, 0x7, &this->actor.focus.pos, &this->actor.shape.rot, 280.0f, 1800.0f, -1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970A10.s") +void EnKakasi_CheckAnimationSfx(EnKakasi* this) { + if (this->animIndex == ENKAKASI_ANIM_SIDEWAYS_SHAKING || this->animIndex == ENKAKASI_ANIM_ARMS_CROSSED_STILL) { + if (Animation_OnFrame(&this->skelanime, 1.0f) || Animation_OnFrame(&this->skelanime, 8.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_SWING); + } + } + if (this->animIndex == ENKAKASI_ANIM_HOPPING_REGULAR || this->animIndex == ENKAKASI_ANIM_SLOWROLL) { + if (Animation_OnFrame(&this->skelanime, 4.0f) || Animation_OnFrame(&this->skelanime, 8.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_SWING); + } + if (Animation_OnFrame(&this->skelanime, 1.0f) || Animation_OnFrame(&this->skelanime, 9.0f) || + Animation_OnFrame(&this->skelanime, 16.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_IT_KAKASHI_JUMP); + } + if (Animation_OnFrame(&this->skelanime, 18.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_ROLL); + } + } + if (this->animIndex == ENKAKASI_ANIM_SPIN_REACH_OFFER || this->animIndex == ENKAKASI_ANIM_TWIRL) { + if (Animation_OnFrame(&this->skelanime, 1.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASH_LONGI_ROLL); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970A9C.s") +/* + * moves the player's position relative to scarecrow during song teach, also each frame of dance the night away + */ +void EnKakasi_CheckPlayerPosition(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970F20.s") + if (globalCtx->sceneNum == SCENE_8ITEMSHOP) { + player->actor.world.pos.x = -50.0f; + player->actor.world.pos.z = 155.0f; + } else if (globalCtx->sceneNum == SCENE_TENMON_DAI) { + player->actor.world.pos.x = 60.0f; + player->actor.world.pos.z = -190.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970FF8.s") + Math_SmoothStepToS(&player->actor.shape.rot.y, (this->actor.yawTowardsPlayer + 0x8000), 5, 1000, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971064.s") +/* + * this goes off every frame of dancing the night away, and song teaching + * something to do with cutscene camera? + */ +void func_8096FAAC(EnKakasi* this, GlobalContext* globalCtx) { + if (this->cutsceneCamId != MAIN_CAM) { + Math_ApproachF(&this->unk214.x, this->unk238.x, 0.4f, 4.0f); + Math_ApproachF(&this->unk214.y, this->unk238.y, 0.4f, 4.0f); + Math_ApproachF(&this->unk214.z, this->unk238.z, 0.4f, 4.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971430.s") + Math_ApproachF(&this->unk220.x, this->unk244.x, 0.4f, 4.0f); + Math_ApproachF(&this->unk220.y, this->unk244.y, 0.4f, 4.0f); + Math_ApproachF(&this->unk220.z, this->unk244.z, 0.4f, 4.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971440.s") + Math_ApproachF(&this->unk20C, this->unk210, 0.3f, 10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809714BC.s") + Play_CameraSetAtEye(globalCtx, this->cutsceneCamId, &this->unk220, &this->unk214); + func_80169940(globalCtx, this->cutsceneCamId, this->unk20C); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971794.s") +/* + * goes off every frame of song teach, but... doing what? + */ +void func_8096FBB8(EnKakasi* this, GlobalContext* globalCtx) { + if (globalCtx->msgCtx.unk12048 == 0 || globalCtx->msgCtx.unk12048 == 1 || globalCtx->msgCtx.unk12048 == 2 || + globalCtx->msgCtx.unk12048 == 3 || globalCtx->msgCtx.unk12048 == 4) { + // why not 0 < x < 4? fewer branches + this->unk190++; + } + if (this->unk190 != 0 && this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (this->unk190 > 8) { + this->unk190 = 8; + } + if (this->unk190 != 0) { + Math_ApproachF(&this->skelanime.playSpeed, 1.0f, 0.1f, 0.2f); + this->actor.shape.rot.y += 0x800; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809717D0.s") +void EnKakasi_InitTimeSkipDialogue(EnKakasi* this) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SLOWROLL); + this->actionFunc = EnKakasi_TimeSkipDialogue; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097185C.s") +void EnKakasi_TimeSkipDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097193C.s") + if (gSaveContext.respawnFlag != -4 && gSaveContext.respawnFlag != -8) { + if (gSaveContext.time != CLOCK_TIME(6, 0) && gSaveContext.time != CLOCK_TIME(18, 0) && + !(gSaveContext.eventInf[1] & 0x80)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971A38.s") + if (this->actor.textId == 0) { + // dialogue after skipped time 'did you feel that? went by in an instant' + this->actor.textId = 0x1653; + gSaveContext.weekEventReg[0x53] &= (u8)~1; + this->unkMsgState1AC = 5; + player->stateFlags1 |= 0x20; + this->actor.flags |= 0x10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971A64.s") + if (func_800B84D0(&this->actor, globalCtx) != 0) { + player->stateFlags1 &= ~0x20; + this->unkState196 = 2; + this->actor.flags &= ~0x10000; + this->actionFunc = EnKakasi_RegularDialogue; + } else { + func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, -1); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971AD4.s") +void EnKakasi_SetupIdleStanding(EnKakasi* this) { + this->unkState196 = 0; + this->actionFunc = EnKakasi_IdleStanding; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Update.s") +void EnKakasi_IdleStanding(EnKakasi* this, GlobalContext* globalCtx) { + u32 saveContextDay = gSaveContext.day; + s16 passedValue1; + s16 passedValue2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971CE0.s") + // first talk to scarecrow dialogue + this->actor.textId = 0x1644; + if (func_800B8718(&this->actor, globalCtx) != 0) { + this->skelanime.playSpeed = 1.0f; + EnKakasi_SetupSongTeach(this, globalCtx); + return; + } + if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->skelanime.playSpeed = 1.0f; + EnKakasi_SetupDialogue(this); + return; + } + if (globalCtx->actorCtx.unk5 & 0x4) { + func_800B8898(globalCtx, &this->actor, &passedValue1, &passedValue2); + if (this->actor.projectedPos.z > -20.0f && passedValue1 > 0 && passedValue1 < 0x140 && passedValue2 > 0 && + passedValue2 < 0xF0 && this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + // faster shaking + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + this->skelanime.playSpeed = 2.0f; + } + } else if (Player_GetMask(globalCtx) == PLAYER_MASK_KAMARO) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + this->skelanime.playSpeed = 2.0f; + } + } else if (saveContextDay == 3 && gSaveContext.isNight) { + this->skelanime.playSpeed = 1.0f; + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, 1); + } + } else if (this->animIndex != ENKAKASI_ANIM_IDLE) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_IDLE); + } + if (this->actor.xzDistToPlayer < 120.0f) { + func_800B8614(&this->actor, globalCtx, 100.0f); + func_800B874C(&this->actor, globalCtx, 100.0f, 80.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Draw.s") +void EnKakasi_SetupDialogue(EnKakasi* this) { + // bug? starts one animation then changes it a few lines down? + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + + this->unkMsgState1AC = 5; + this->unkState196 = 1; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + this->actionFunc = EnKakasi_RegularDialogue; +} + +void EnKakasi_RegularDialogue(EnKakasi* this, GlobalContext* globalCtx) { + u32 saveContextDay = gSaveContext.day; + f32 currentAnimeFrame = this->skelanime.curFrame; + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 2000, 0); + // if first dialogue + if (this->actor.textId != 0x1644 && this->animeFrameCount <= currentAnimeFrame && + this->animIndex == ENKAKASI_ANIM_SLOWROLL) { + + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + this->unkCounter1A4 = 0; + } + + // if dialogue: oh sorry come back again + if (this->actor.textId == 0x1651 || this->actor.textId == 0x1659) { + if (this->animeFrameCount <= currentAnimeFrame && this->animIndex != ENKAKASI_ANIM_SPIN_REACH_OFFER) { + if (++this->unkCounter1A4 >= 2) { + this->unkCounter1A4 = 0; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + } + } + } + + if (this->unkState1A8 == 2 && this->unkState196 == 2) { + func_800B7298(globalCtx, &this->actor, 0x49); + this->unkState1A8 = 0; + } + + if (this->unkMsgState1AC == func_80152498(&globalCtx->msgCtx) && func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + if (this->unkMsgState1AC == 5) { + // bad song input + if (this->unkState196 == 2 && this->actor.textId == 0x1647) { + func_800B7298(globalCtx, &this->actor, 6); + } + + // after timeskip + if (this->actor.textId == 0x1653) { + u32 saveContextDay2 = gSaveContext.day; + + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + + if (saveContextDay2 == 3 && gSaveContext.isNight) { + // text: dangerous outside + this->actor.textId = 0x164F; + } else if (gSaveContext.isNight) { + // text: would you like to skip time? + this->actor.textId = 0x164E; + } else { + // text: would you like to skip time? 2 + this->actor.textId = 0x1645; + } + + func_80151938(globalCtx, this->actor.textId); + return; + + } else if (this->actor.textId == 0x165D || this->actor.textId == 0x165F || this->actor.textId == 0x1660 || + this->actor.textId == 0x1652) { + func_800B7298(globalCtx, &this->actor, 4); + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_DancingRemark; + } else { + if (!ActorCutscene_GetCanPlayNext(this->actorCutscenes[0])) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_DancingRemark; + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + this->actionFunc = EnKakasi_DancingRemark; + } + } + return; + + } else if (this->actor.textId == 0x1645 || this->actor.textId == 0x164E) { + this->actor.textId = 0x1650; // "Shall we dance? No Yes" + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x1644) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (gSaveContext.isNight) { + this->actor.textId = 0x164E; + } else { + this->actor.textId = 0x1645; + } + + } else if (this->actor.textId == 0x164F) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->actor.textId = 0x165A; + } else if (this->actor.textId == 0x1651) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->actor.textId = 0x1654; + } else if (this->actor.textId == 0x1654) { + this->actor.textId = 0x1655; + } else if (this->actor.textId == 0x1655) { + this->actor.textId = 0x1656; + this->unkMsgState1AC = 4; + } else if (this->actor.textId == 0x1658) { + this->actor.textId = 0x1659; + } else if (this->actor.textId == 0x165A) { + this->actor.textId = 0x165B; + } else if (this->actor.textId == 0x165B) { + this->actor.textId = 0x165C; + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x165E) { + this->actor.textId = 0x165F; + } else { + EnKakasi_SetupIdleStanding(this); + return; + } + } else { + this->unkMsgState1AC = 5; + + if (globalCtx->msgCtx.choiceIndex == 1) { + func_8019F208(); + if (this->actor.textId == 0x1656) { + this->actor.textId = 0x1658; + } else if (this->actor.textId == 0x165C) { + this->actor.textId = 0x165E; + } else if (saveContextDay == 3 && gSaveContext.isNight) { + this->actor.textId = 0x164F; + } else { + this->actor.textId = 0x1652; + } + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + } else { + func_8019F230(); + if (this->actor.textId == 0x1656) { // would you like to learn a song? yes/no + this->actor.textId = 0x1657; + } else if (this->actor.textId == 0x165C) { // would you like to learn a song? yes/no + this->actor.textId = 0x165D; + } else { + this->actor.textId = 0x1651; + } + this->unkCounter1A4 = 0; + if (this->animIndex != ENKAKASI_ANIM_ARMS_CROSSED_ROCKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +void EnKakasi_SetupSongTeach(EnKakasi* this, GlobalContext* globalCtx) { + this->actor.textId = 0x1646; + func_801518B0(globalCtx, this->actor.textId, &this->actor); + this->cutsceneCamId = MAIN_CAM; + this->unk20C = 0.0f; + this->unk210 = 60.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + this->unkState196 = 2; + this->actionFunc = EnKakasi_OcarinaRemark; +} + +/* + * you took out ocarina hes talking about how he wants to hear you play him a song + * before actually teaching + */ +void EnKakasi_OcarinaRemark(EnKakasi* this, GlobalContext* globalCtx) { + if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx) != 0) { + func_80152434(globalCtx, 0x35); + this->unkState1A8 = 0; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_TeachingSong; + + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_TeachingSong; + + } else { + this->unkState1A8 = 1; + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->actionFunc = EnKakasi_TeachingSong; + } + } +} + +void EnKakasi_TeachingSong(EnKakasi* this, GlobalContext* globalCtx) { + Vec3f tempVec; + + EnKakasi_CheckPlayerPosition(this, globalCtx); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + if (this->unkState1A8 == 0) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->unkState1A8 = 1; + this->unkState1A8 = 1; + } + + if (this->unkState1A8 == 1) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + this->unk238.x = D_80971DCC[this->unk190].x; + this->unk238.y = D_80971DCC[this->unk190].y; + this->unk238.z = D_80971DCC[this->unk190].z; + + Math_Vec3f_Copy(&tempVec, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &tempVec, &this->unk238, 1); + Math_Vec3f_Copy(&this->unk244, &this->unk22C); + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + func_8096FAAC(this, globalCtx); + func_8096FBB8(this, globalCtx); + + if (globalCtx->msgCtx.unk1202A == 4) { // song failed + this->unk190 = 0; + this->unkCounter1A4 = 0; + ActorCutscene_Stop(this->actorCutscenes[0]); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_YASE_DEAD); + if (this) {} + this->unkState196 = 2; + this->cutsceneCamId = MAIN_CAM; + this->actor.textId = 0x1647; + this->unkState1A8 = 2; + this->unkMsgState1AC = 5; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + this->actionFunc = EnKakasi_RegularDialogue; + + } else if (globalCtx->msgCtx.unk1202A == 3) { // song success + this->postTeachTimer = 30; + this->skelanime.playSpeed = 2.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + this->actionFunc = EnKakasi_PostSongLearnTwirl; + } + } +} + +void EnKakasi_PostSongLearnTwirl(EnKakasi* this, GlobalContext* globalCtx) { + f32 animeFrame = this->skelanime.curFrame; + + if (this->postTeachTimer == 0 && this->animIndex != ENKAKASI_ANIM_TWIRL) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + this->skelanime.playSpeed = 2.0f; + } + if (this->postTeachTimer == 0 && this->animIndex == ENKAKASI_ANIM_TWIRL && this->animeFrameCount <= animeFrame) { + EnKakasi_SetupPostSongLearnDialogue(this, globalCtx); + } +} + +void EnKakasi_SetupPostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx) { + ActorCutscene_Stop(this->actorCutscenes[0]); + globalCtx->msgCtx.unk1202A = 4; + this->unk190 = 0; + this->unkCounter1A4 = 0; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + this->cutsceneCamId = MAIN_CAM; + this->unkMsgState1AC = 5; + this->unkState1A8 = 1; + this->actionFunc = EnKakasi_PostSongLearnDialogue; + this->unk20C = 0.0f; + this->unk210 = 60.0f; +} + +void EnKakasi_PostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 tempAnimFrame = this->skelanime.curFrame; + Vec3f vec3fCopy; + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + Math_SmoothStepToS(&player->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 5, 1000, 0); + + if (this->unk190 == 0) { + func_801477B4(globalCtx); + func_800B7298(globalCtx, &this->actor, 0x56); + this->actor.textId = 0x1648; + func_801518B0(globalCtx, (this->actor.textId), &this->actor); + this->unkState1A8 = 0; + this->unk190 = 1; + } + + if (this->actor.textId == 0x1648 && this->animIndex == ENKAKASI_ANIM_HOPPING_REGULAR && + this->animeFrameCount <= tempAnimFrame) { + this->unkCounter1A4++; + if (this->unkCounter1A4 >= 2) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + } + + if (this->actor.textId == 0x164B && this->animIndex == ENKAKASI_ANIM_ARMS_CROSSED_ROCKING && + this->animeFrameCount <= tempAnimFrame) { + this->unkCounter1A4++; + if (this->unkCounter1A4 >= 2) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + } + } + + if (this->unkState1A8 == 0) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + func_800B7298(globalCtx, &this->actor, 0x56); + this->unkState1A8 = 1; + } + + if (this->cutsceneCamId != MAIN_CAM) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + EnKakasi_CheckPlayerPosition(this, globalCtx); + this->unk238.x = D_80971FA0[this->unk190].x; + this->unk238.y = D_80971FA0[this->unk190].y; + this->unk238.z = D_80971FA0[this->unk190].z; + Math_Vec3f_Copy(&vec3fCopy, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &vec3fCopy, &this->unk238, 1); + this->unk244.x = D_80971FE8[this->unk190].x + this->unk22C.x; + this->unk244.y = D_80971FE8[this->unk190].y + this->unk22C.y; + this->unk244.z = D_80971FE8[this->unk190].z + this->unk22C.z; + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + } + + func_8096FAAC(this, globalCtx); + + if (this->unkState1A8 != 0 && func_80152498(&globalCtx->msgCtx) == this->unkMsgState1AC && + func_80147624(globalCtx) != 0) { + + func_801477B4(globalCtx); + + if (this->unkMsgState1AC == 5) { + this->unk190++; + if (this->unk190 > 5) { + this->unk190 = 5; + } + + if (this->actor.textId == 0x1648) { + func_800B7298(globalCtx, &this->actor, 7); + this->actor.textId = 0x1649; + if (this->animIndex != ENKAKASI_ANIM_ARMS_CROSSED_ROCKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + + } else if (this->actor.textId == 0x1649) { + this->actor.textId = 0x1660; + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x164A) { + this->actor.textId = 0x164B; + + } else if (this->actor.textId == 0x164B) { + this->actor.textId = 0x164C; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + + } else { + if (this->actor.textId == 0x164C || this->actor.textId == 0x1661) { + EnKakasi_SetupDigAway(this); + return; + } + } + + } else { + this->unkMsgState1AC = 5; + if (globalCtx->msgCtx.choiceIndex == 1) { + func_8019F208(); // play 0x4808 sfx (decide) and calls func_801A75E8 + this->actor.textId = 0x164A; + } else { + func_8019F230(); // play 0x480A sfx (cancel) and calls func_801A75E8 + this->actor.textId = 0x1661; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +/* + * talking before dancing the night away, and cutscene setup + */ +void EnKakasi_DancingRemark(EnKakasi* this, GlobalContext* globalCtx) { + u32 currentDay = gSaveContext.day; + + this->unkState196 = 3; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + if (currentDay == 3 && gSaveContext.isNight) { + EnKakasi_SetupDigAway(this); + } else { + func_801A2BB8(0x3E); + EnKakasi_SetupDanceNightAway(this); + } + } +} + +void EnKakasi_SetupDanceNightAway(EnKakasi* this) { + this->unk190 = 0; + this->unkCounter1A4 = 0; + this->unk20C = 0.0f; + this->unk210 = 60.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + func_8016566C(0xB4); + this->actionFunc = EnKakasi_DancingNightAway; +} + +void EnKakasi_DancingNightAway(EnKakasi* this, GlobalContext* globalCtx) { + f32 currentFrame; + Vec3f localVec3f; + Player* player; + + currentFrame = this->skelanime.curFrame; + EnKakasi_CheckPlayerPosition(this, globalCtx); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + this->unk22C.y = this->actor.home.pos.y + 50.0f; + + this->unk238.x = D_80971E38[this->unk190].x; + this->unk238.y = D_80971E38[this->unk190].y; + this->unk238.z = D_80971E38[this->unk190].z; + Math_Vec3f_Copy(&localVec3f, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &localVec3f, &this->unk238, 1); + + if (1) {} + this->unk244.x = D_80971EEC[this->unk190].x + this->unk22C.x; + this->unk244.y = D_80971EEC[this->unk190].y + this->unk22C.y; + this->unk244.z = D_80971EEC[this->unk190].z + this->unk22C.z; + if (this->unk190 != 6 && this->unk190 != 7) { + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + } + if (this->unk190 >= 7 && this->unk190 != 0xE) { + this->actor.shape.rot.y += 0x800; + } + + func_8096FAAC(this, globalCtx); + + // switching through manual cutscene states + switch (this->unk190) { + case 0: + // twirling + this->unk204 = 0x28; + this->unk190++; + return; + case 1: + // end of twirl, start shaking back and forth + if (this->unk204 == 0 && this->animeFrameCount <= currentFrame) { + this->unk204 = 0x14; + this->unk190++; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + return; + case 2: + // camera view on the left + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 3: + // camera view on the right + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 4: + // camera view close up front + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 5: + // camera view zoomed out front + if (this->unk204 == 0) { + this->unk204 = 0xF; + this->unk190++; + } + return; + case 6: + // zoom in and sweep down in from case 5 + if (this->unk204 == 0) { + this->unk204 = 0xF; + this->unk190++; + } + return; + case 7: + // zoom in close from case 6 + if (this->unk204 == 0) { + this->unk204 = 0xA; + this->unk190++; + } + return; + + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + // multiple quick angle cuts viewing from multiple sides + if (this->unk204 == 0) { + this->unk190++; + this->unk204 = 0xA; + if (this->unk190 == 0xE) { + func_800B7298(globalCtx, &this->actor, 0x49); + func_80165690(); + this->unk204 = 0x14; + } + } + return; + case 14: + // goes off once for some camera changes, + // otherwise its the end when camera is back to normal and link is confused + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + if (this->unk204 == 0) { + player = GET_PLAYER(globalCtx); + + func_80169DCC(globalCtx, 0, Entrance_CreateIndexFromSpawn(0), player->unk_3CE, 0xBFF, &player->unk_3C0, + player->unk_3CC); + func_80169EFC(globalCtx); + + if (0) {} + if (gSaveContext.time > CLOCK_TIME(18, 0) || gSaveContext.time < CLOCK_TIME(6, 0)) { + gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.respawnFlag = -4; + gSaveContext.eventInf[2] |= 0x80; + } else { + gSaveContext.time = CLOCK_TIME(18, 0); + gSaveContext.respawnFlag = -8; + } + gSaveContext.weekEventReg[0x53] |= 1; + this->unk190 = 0; + this->actionFunc = EnKakasi_DoNothing; + } + } +} + +void EnKakasi_DoNothing(EnKakasi* this, GlobalContext* globalCtx) { +} + +void EnKakasi_SetupDigAway(EnKakasi* this) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->unk190 = 0; + this->unkCounter1A4 = 0; + this->unk210 = 60.0f; + this->unk20C = 60.0f; + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->unkState196 = 4; + this->actionFunc = EnKakasi_DiggingAway; +} + +void EnKakasi_DiggingAway(EnKakasi* this, GlobalContext* globalCtx) { + Vec3f tempunk238; + Vec3f tempWorldPos; + + if (this->cutsceneCamId != MAIN_CAM) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + this->unk238.x = D_80972030.x; + this->unk238.y = D_80972030.y; + this->unk238.z = D_80972030.z; + + Math_Vec3f_Copy(&tempunk238, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &tempunk238, &this->unk238, 1); + this->unk244.x = ((f32)D_8097203C.x) + this->unk22C.x; // cast req + this->unk244.y = ((f32)D_8097203C.y) + this->unk22C.y; + this->unk244.z = ((f32)D_8097203C.z) + this->unk22C.z; + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + func_8096FAAC(this, globalCtx); + } + + if (this->unkCounter1A4 < 15) { + this->unkCounter1A4++; + return; + } + + this->actor.shape.rot.y += 0x3000; + Math_SmoothStepToS(&this->unk190, 500, 5, 50, 0); + if ((globalCtx->gameplayFrames % 4) == 0) { + Math_Vec3f_Copy(&tempWorldPos, &this->actor.world.pos); + tempWorldPos.y = this->actor.floorHeight; + tempWorldPos.x += randPlusMinusPoint5Scaled(2.0f); + tempWorldPos.z += randPlusMinusPoint5Scaled(2.0f); + + if (globalCtx->sceneNum == SCENE_8ITEMSHOP) { + EffectSsGSplash_Spawn(globalCtx, &tempWorldPos, 0, 0, 0, randPlusMinusPoint5Scaled(100.0f) + 200.0f); + Audio_PlaySoundAtPosition(globalCtx, &tempWorldPos, 0x32, NA_SE_EV_BOMB_DROP_WATER); + + } else { + func_800BBDAC(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale - 20.0f, 5, + 4.0f, 200, 10, 1); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + } + } + + Math_ApproachF(&this->actor.shape.yOffset, -6000.0f, 0.5f, 200.0f); + if (fabsf(this->actor.shape.yOffset + 6000.0f) < 10.0f) { + gSaveContext.weekEventReg[79] |= 8; + func_800B7298(globalCtx, &this->actor, 6); + ActorCutscene_Stop(this->actorCutscenes[0]); + this->aboveGroundStatus = ENKAKASI_ABOVE_GROUND_TYPE; + this->songSummonDist = 80.0f; + EnKakasi_SetupIdleUnderground(this); + } +} + +void EnKakasi_SetupIdleUnderground(EnKakasi* this) { + this->actor.shape.yOffset = -7000.0; + this->actor.draw = NULL; + this->actor.flags |= 0x8000000; + this->unkState196 = 5; + this->actionFunc = EnKakasi_IdleUnderground; +} + +void EnKakasi_IdleUnderground(EnKakasi* this, GlobalContext* globalCtx) { + if ((gSaveContext.weekEventReg[79] & 0x8) && this->actor.xzDistToPlayer < this->songSummonDist && + (BREG(1) != 0 || globalCtx->msgCtx.unk1202A == 0xD)) { + this->actor.flags &= ~0x8000000; + globalCtx->msgCtx.unk1202A = 4; + this->actionFunc = EnKakasi_SetupRiseOutOfGround; + } +} + +void EnKakasi_SetupRiseOutOfGround(EnKakasi* this, GlobalContext* globalCtx) { + s32 cutsceneIndex; + + cutsceneIndex = 0; + if (this->aboveGroundStatus == ENKAKASI_ABOVE_GROUND_TYPE) { + cutsceneIndex = 1; + } + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[cutsceneIndex]); + + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[cutsceneIndex]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[cutsceneIndex]); + + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[cutsceneIndex], &this->actor); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actor.draw = EnKakasi_Draw; + this->unkState196 = 6; + this->actionFunc = EnKakasi_RisingOutOfGround; + } +} + +void EnKakasi_RisingOutOfGround(EnKakasi* this, GlobalContext* globalCtx) { + this->actor.shape.rot.y += 0x3000; + + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (this->actor.shape.yOffset < -10.0f) { + if ((globalCtx->gameplayFrames % 8) == 0) { + func_800BBDAC(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale - 20.0f, 10, + 8.0f, 500, 10, 1); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + } + Math_ApproachF(&this->actor.shape.yOffset, 0.0f, 0.5f, 200.0f); + } else { + EnKakasi_SetupIdleRisen(this); + } +} + +void EnKakasi_SetupIdleRisen(EnKakasi* this) { + // text: great to see you again + this->actor.textId = 0x164D; + this->unkState196 = 7; + this->actionFunc = EnKakasi_IdleRisen; + this->actor.shape.yOffset = 0.0f; +} + +void EnKakasi_IdleRisen(EnKakasi* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = EnKakasi_RisenDialogue; + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void EnKakasi_RisenDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + + if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + EnKakasi_SetupIdleRisen(this); + } +} + +void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + s32 pad; + + SkelAnime_Update(&this->skelanime); + if (this->actor.draw != NULL) { + EnKakasi_CheckAnimationSfx(this); + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + DECR(this->postTeachTimer); + DECR(this->unk204); + + if (this->unkState196 != 5) { + if (this->unk1BC.x != 0.0f || this->unk1BC.z != 0.0f) { + Math_Vec3f_Copy(&this->actor.focus.pos, &this->unk1BC); + this->actor.focus.pos.y += 10.0f; + if (this->cutsceneCamId == MAIN_CAM) { + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } else { + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.home.rot); + } + } + } else { + Actor_SetHeight(&this->actor, this->unkHeight); + } + + this->actionFunc(this, globalCtx); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 0x1C); + if (this->actor.draw != NULL) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnKakasi_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor) { + EnKakasi* this = (EnKakasi*)actor; + + if (limbIndex == 4) { + // what is D_801D15B0 ? we didn't have to define it, we store the output though + Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk1BC); + } +} + +void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelanime.skeleton, this->skelanime.jointTable, this->skelanime.dListCount, + NULL, EnKakasi_LimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h index b9a18adc55..2cb4f6cba1 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h @@ -6,14 +6,46 @@ struct EnKakasi; typedef void (*EnKakasiActionFunc)(struct EnKakasi*, GlobalContext*); +typedef void (*EnKakasiUnkFunc)(GlobalContext*, struct EnKakasi*); typedef struct EnKakasi { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4]; - /* 0x0148 */ EnKakasiActionFunc actionFunc; - /* 0x014C */ char unk_14C[0x154]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnKakasiUnkFunc unkFunc; // used for one z_snap calling function? + /* 0x148 */ EnKakasiActionFunc actionFunc; + /* 0x14C */ SkelAnime skelanime; + /* 0x190 */ s16 unk190; // camera index for song teaching angles? + /* 0x192 */ s16 postTeachTimer; + /* 0x194 */ s16 aboveGroundStatus; // from params, changed to 2 in init + /* 0x196 */ s16 unkState196; + /* 0x19A */ UNK_TYPE1 pad198[0x8]; + /* 0x1A0 */ s32 animIndex; + /* 0x1A4 */ s32 unkCounter1A4; // counter, counts up to F while he digs away, reused elsewhere + /* 0x1A8 */ s32 unkState1A8; + /* 0x1AC */ s16 unkMsgState1AC; // might be dialog state, compared against func(msgCtx) + /* 0x1AE */ s16 actorCutscenes[3]; + /* 0x1B4 */ f32 animeFrameCount; + /* 0x1B8 */ f32 unkHeight; + /* 0x1BC */ Vec3f unk1BC; // set by post limbdraw func for one limb + /* 0x1C8 */ UNK_TYPE1 pad1C8[0x3C]; + /* 0x204 */ s16 unk204; // set to A, F, 0x14, 0x28 frequently + /* 0x206 */ UNK_TYPE1 pad206[2]; + /* 0x208 */ s16 cutsceneCamId; + /* 0x20C */ f32 unk20C; // passed to unknown function + /* 0x210 */ f32 unk210; // used as a target for 20C to approach + /* 0x214 */ Vec3f unk214; // copied from unk238 regularly + /* 0x220 */ Vec3f unk220; //EnKakasi_TeachingSong + /* 0x22C */ Vec3f unk22C; //actor home copied to here + /* 0x238 */ Vec3f unk238; //copied from D_80971E38[unk190] + /* 0x244 */ Vec3f unk244; + /* 0x250 */ f32 songSummonDist; + /* 0x254 */ ColliderCylinder collider; } EnKakasi; // size = 0x2A0 extern const ActorInit En_Kakasi_InitVars; +#define ENKAKASI_ABOVE_GROUND_TYPE 2 + +#define GET_KAKASI_SUMMON_DISTANCE(this) ((this->actor.params >> 0x8) & 0xFF) +#define GET_KAKASI_ABOVE_GROUND(this) (this->actor.params & 0x1) + #endif // Z_EN_KAKASI_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 7dab11b4dd..43024464d5 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8016,37 +8016,37 @@ 0x8096F4DC:("BgF40Swlift_Draw",), 0x8096F5E0:("EnKakasi_Destroy",), 0x8096F60C:("EnKakasi_Init",), - 0x8096F800:("func_8096F800",), - 0x8096F88C:("func_8096F88C",), + 0x8096F800:("EnKakasi_SetAnimation",), + 0x8096F88C:("EnKakasi_8096F88C",), 0x8096F8D8:("func_8096F8D8",), 0x8096FA18:("func_8096FA18",), 0x8096FAAC:("func_8096FAAC",), 0x8096FBB8:("func_8096FBB8",), - 0x8096FC8C:("func_8096FC8C",), - 0x8096FCC4:("func_8096FCC4",), - 0x8096FDE8:("func_8096FDE8",), - 0x8096FE00:("func_8096FE00",), - 0x80970008:("func_80970008",), - 0x8097006C:("func_8097006C",), + 0x8096FC8C:("EnKakasi_InitTimeSkipDialogue",), + 0x8096FCC4:("EnKakasi_TimeSkipDialogue",), + 0x8096FDE8:("EnKakasi_SetupIdleStanding",), + 0x8096FE00:("EnKakasi_IdleStanding",), + 0x80970008:("EnKakasi_SetupDialogue",), + 0x8097006C:("EnKakasi_RegularDialogue",), 0x809705E4:("func_809705E4",), 0x80970658:("func_80970658",), 0x80970740:("func_80970740",), 0x80970978:("func_80970978",), - 0x80970A10:("func_80970A10",), - 0x80970A9C:("func_80970A9C",), - 0x80970F20:("func_80970F20",), - 0x80970FF8:("func_80970FF8",), - 0x80971064:("func_80971064",), - 0x80971430:("func_80971430",), + 0x80970A10:("EnKakasi_SetupPostSongLearnDialogue",), + 0x80970A9C:("EnKakasi_PostSongLearnDialogue",), + 0x80970F20:("EnKakasi_DancingRemark",), + 0x80970FF8:("EnKakasi_SetupDanceNightAway",), + 0x80971064:("EnKakasi_DancingNightAway",), + 0x80971430:("EnKakasi_DoNothing",), 0x80971440:("func_80971440",), 0x809714BC:("func_809714BC",), 0x80971794:("func_80971794",), 0x809717D0:("func_809717D0",), - 0x8097185C:("func_8097185C",), - 0x8097193C:("func_8097193C",), - 0x80971A38:("func_80971A38",), - 0x80971A64:("func_80971A64",), - 0x80971AD4:("func_80971AD4",), + 0x8097185C:("EnKakasi_SetupRiseOutOfGround",), + 0x8097193C:("EnKakasi_RisingOutOfGround",), + 0x80971A38:("EnKakasi_SetupIdleRisen",), + 0x80971A64:("EnKakasi_IdleRisen",), + 0x80971AD4:("EnKakasi_RisenDialogue",), 0x80971B48:("EnKakasi_Update",), 0x80971CE0:("func_80971CE0",), 0x80971D20:("EnKakasi_Draw",), diff --git a/undefined_syms.txt b/undefined_syms.txt index 56f4cb1b1e..211f78865d 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -2723,6 +2723,15 @@ D_0600D828 = 0x0600D828; D_06000214 = 0x06000214; D_060065B0 = 0x060065B0; +D_06007444 = 0x06007444; +D_0600686C = 0x0600686C; +D_060081A4 = 0x060081A4; +D_06007B90 = 0x06007B90; +D_060071EC = 0x060071EC; +D_06007444 = 0x06007444; +D_0600686C = 0x0600686C; +D_060081A4 = 0x060081A4; +D_06000214 = 0x06000214; // ovl_En_Kame