diff options
| author | krimtonz <33664508+krimtonz@users.noreply.github.com> | 2021-01-14 14:17:03 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-14 15:17:03 -0500 |
| commit | 2810aa2b9c4298b45bcc7ac9c8a8faa58d5f5efb (patch) | |
| tree | f15afb2c20047abed136e82d04e08c969b5b6ad0 /src | |
| parent | fcc4a8190d78640d917831d21e017fbb8668fa5d (diff) | |
ovl_En_Owl (#573)
* begin En_Owl
* EnOwl wip
* fix conflicts
* owl wip
* wip
* cleanup
* more cleanup
* remove unused asm
* run formatter
* match EnOwl_Init
* formatting
* pr updates
* forgot the enum values in WaitZoraRiver
* merge fixes
* Fix merge issues
* review changes + more
* name
Co-authored-by: fig <fig02srl@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/overlays/actors/ovl_En_Owl/z_en_owl.c | 1561 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_En_Owl/z_en_owl.h | 34 |
2 files changed, 1449 insertions, 146 deletions
diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 8276e8fec..bfd901ae4 100644 --- a/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -1,25 +1,79 @@ +/* + * File: z_en_owl.c + * Overlay: ovl_En_Owl + * Description: Owl + */ + #include "z_en_owl.h" +#include "vt.h" #define FLAGS 0x00000019 #define THIS ((EnOwl*)thisx) +extern AnimationHeader D_0600C1C4; +extern CsCmdActorAction D_0201E6A0; +extern CsCmdActorAction D_0201B0C0; +extern AnimationHeader D_06001168; +extern FlexSkeletonHeader D_0600C0E8; +extern FlexSkeletonHeader D_060100B0; +extern AnimationHeader D_060015CC; +extern AnimationHeader D_0600C8A0; +extern AnimationHeader D_0600C684; + void EnOwl_Init(Actor* thisx, GlobalContext* globalCtx); void EnOwl_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnOwl_Update(Actor* thisx, GlobalContext* globalCtx); void EnOwl_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnOwl_ChangeMode(EnOwl* this, EnOwlActionFunc, OwlFunc, SkelAnime*, AnimationHeader*, f32); +void EnOwl_WaitDefault(EnOwl* this, GlobalContext* globalCtx); +void func_80ACC540(EnOwl* this); +void EnOwl_WaitOutsideKokiri(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitHyruleCastle(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitKakariko(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitGerudo(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitLakeHylia(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitZoraRiver(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitHyliaShortcut(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitDeathMountainShortcut(EnOwl* this, GlobalContext* globalCtx); +void func_80ACB3E0(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitLWPreSaria(EnOwl* this, GlobalContext* globalCtx); +void EnOwl_WaitLWPostSaria(EnOwl* this, GlobalContext* globalCtx); +void func_80ACD4D4(EnOwl* this, GlobalContext* globalCtx); +void func_80ACD130(EnOwl* this, GlobalContext* globalCtx, s32 arg2); +void func_80ACBAB8(EnOwl* this, GlobalContext* globalCtx); +void func_80ACD2CC(EnOwl* this, GlobalContext* globalCtx); +void func_80ACAA54(EnOwl* this, GlobalContext* globalCtx); +void func_80ACAC6C(EnOwl* this, GlobalContext* globalCtx); +void func_80ACADF0(EnOwl* this, GlobalContext* globalCtx); +void func_80ACAF74(EnOwl* this, GlobalContext* globalCtx); +void func_80ACC30C(EnOwl* this, GlobalContext* globalCtx); +void func_80ACB4FC(EnOwl* this, GlobalContext* globalCtx); +void func_80ACB680(EnOwl* this, GlobalContext* globalCtx); +void func_80ACC460(EnOwl* this); +void func_80ACBEA0(EnOwl*, GlobalContext*); + +typedef enum { + /* 0x00 */ OWL_DEFAULT, + /* 0x01 */ OWL_OUTSIDE_KOKIRI, + /* 0x02 */ OWL_HYRULE_CASTLE, + /* 0x03 */ OWL_KAKARIKO, + /* 0x04 */ OWL_HYLIA_GERUDO, + /* 0x05 */ OWL_LAKE_HYLIA, + /* 0x06 */ OWL_ZORA_RIVER, + /* 0x07 */ OWL_HYLIA_SHORTCUT, + /* 0x08 */ OWL_DEATH_MOUNTAIN, + /* 0x09 */ OWL_DEATH_MOUNTAIN2, + /* 0x0A */ OWL_DESSERT_COLOSSUS, + /* 0x0B */ OWL_LOST_WOODS_PRESARIA, + /* 0x0C */ OWL_LOST_WOODS_POSTSARIA +} EnOwlType; + +typedef enum { + /* 0x00 */ OWL_REPEAT, + /* 0x01 */ OWL_OK +} EnOwlMessageChoice; -extern UNK_TYPE D_0201B0C0; -extern UNK_TYPE D_0201E6A0; -extern UNK_TYPE D_06001168; -extern UNK_TYPE D_060015CC; -extern UNK_TYPE D_0600C0E8; -extern UNK_TYPE D_0600C1C4; -extern UNK_TYPE D_0600C684; -extern UNK_TYPE D_0600C8A0; -extern UNK_TYPE D_060100B0; - -/* const ActorInit En_Owl_InitVars = { ACTOR_EN_OWL, ACTORTYPE_NPC, @@ -31,141 +85,1358 @@ const ActorInit En_Owl_InitVars = { (ActorFunc)EnOwl_Update, (ActorFunc)EnOwl_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/EnOwl_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/EnOwl_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA3B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA3F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA558.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA5C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA62C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA690.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA6C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA71C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA76C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA7E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA88C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA928.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACA998.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAA54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAAC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAB2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAB88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAC6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACACD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAD34.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACADF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAE5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAEB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAF74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACAFE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB03C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB0B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB148.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB1A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB22C.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB274.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB2B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB344.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB3E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB440.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB4FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB568.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB5C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB680.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB6EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB748.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB904.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACB994.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBA24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBAB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBC0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBD4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBEA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACBF50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC00C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC23C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC30C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC390.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC540.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC5CC.s") +ColliderCylinderInit sOwlCylinderInit = { + { COLTYPE_UNK10, 0x00, 0x11, 0x39, 0x10, COLSHAPE_CYLINDER }, + { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 }, + { 30, 40, 0, { 0, 0, 0 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACC624.s") +InitChainEntry sOwlInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 25, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 1400, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 2000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 2400, ICHAIN_STOP), +}; +void EnOwl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnOwl* this = THIS; + ColliderCylinder* collider; + s32 owlType; + s32 switchFlag; + + Actor_ProcessInitChain(&this->actor, sOwlInitChain); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawFunc_Circle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600C0E8, &D_060015CC, this->jointTable, this->morphTable, 21); + SkelAnime_InitFlex(globalCtx, &this->skelAnime2, &D_060100B0, &D_0600C8A0, this->jointTable2, this->morphTable2, + 16); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sOwlCylinderInit); + this->actor.colChkInfo.mass = 0xFF; + this->actor.minVelocityY = -10.0f; + this->actor.unk_4C = 500.0f; + EnOwl_ChangeMode(this, EnOwl_WaitDefault, func_80ACC540, &this->skelAnime2, &D_0600C8A0, 0.0f); + this->actionFlags = this->unk_406 = this->unk_409 = 0; + this->unk_405 = 4; + this->unk_404 = this->unk_407 = 0; + this->unk_408 = 4; + owlType = (this->actor.params & 0xFC0) >> 6; + switchFlag = (this->actor.params & 0x3F); + if (this->actor.params == 0xFFF) { + owlType = OWL_OUTSIDE_KOKIRI; + switchFlag = 0x20; + } + osSyncPrintf(VT_FGCOL(CYAN) " 会話フクロウ %4x no = %d, sv = %d\n" VT_RST, this->actor.params, owlType, + switchFlag); // conversation owl %4x no = %d, sv = %d + + if ((owlType != OWL_DEFAULT) && (switchFlag < 0x20) && Flags_GetSwitch(globalCtx, switchFlag)) { + osSyncPrintf("savebitでフクロウ退避\n"); // Save owl with savebit + Actor_Kill(&this->actor); + return; + } + + this->unk_3EE = 0; + this->unk_400 = this->actor.posRot.rot.y; + + switch (owlType) { + case OWL_DEFAULT: + this->actionFunc = EnOwl_WaitDefault; + this->actor.uncullZoneForward = 4000.0f; + this->unk_40A = 0; + break; + case OWL_OUTSIDE_KOKIRI: + this->actionFunc = EnOwl_WaitOutsideKokiri; + break; + case OWL_HYRULE_CASTLE: + this->actionFlags |= 2; + this->unk_3EE = 0x20; + this->actionFunc = EnOwl_WaitHyruleCastle; + break; + case OWL_KAKARIKO: + if (gSaveContext.eventChkInf[4] & 1) { + // has zelda's letter + osSyncPrintf("フクロウ退避\n"); // Owl evacuation + Actor_Kill(&this->actor); + return; + } + + this->actionFunc = EnOwl_WaitKakariko; + break; + case OWL_HYLIA_GERUDO: + if (gSaveContext.eventChkInf[4] & 8) { + // has ocarina of time + osSyncPrintf("フクロウ退避\n"); // Owl evacuation + Actor_Kill(&this->actor); + return; + } + this->actionFunc = EnOwl_WaitGerudo; + break; + case OWL_LAKE_HYLIA: + this->actionFunc = EnOwl_WaitLakeHylia; + break; + case OWL_ZORA_RIVER: + if ((gSaveContext.eventChkInf[3] & 0x200) || !(gSaveContext.eventChkInf[4] & 1)) { + // opened zora's domain or has zelda's letter + osSyncPrintf("フクロウ退避\n"); // Owl evacuation + Actor_Kill(&this->actor); + return; + } + + this->actionFunc = EnOwl_WaitZoraRiver; + break; + case OWL_HYLIA_SHORTCUT: + this->actionFunc = EnOwl_WaitHyliaShortcut; + Flags_UnsetSwitch(globalCtx, 0x23); + return; + case OWL_DEATH_MOUNTAIN: + this->actionFunc = EnOwl_WaitDeathMountainShortcut; + break; + case OWL_DEATH_MOUNTAIN2: + this->actionFunc = EnOwl_WaitDeathMountainShortcut; + break; + case OWL_DESSERT_COLOSSUS: + this->actionFunc = func_80ACB3E0; + break; + case OWL_LOST_WOODS_PRESARIA: + if (!CHECK_QUEST_ITEM(QUEST_SONG_LULLABY)) { + osSyncPrintf("フクロウ退避\n"); // Owl evacuation + Actor_Kill(&this->actor); + return; + } + this->actionFunc = EnOwl_WaitLWPreSaria; + break; + case OWL_LOST_WOODS_POSTSARIA: + if (!CHECK_QUEST_ITEM(QUEST_SONG_SARIA)) { + osSyncPrintf("フクロウ退避\n"); // Owl evacuation + Actor_Kill(&this->actor); + return; + } + this->actionFunc = EnOwl_WaitLWPostSaria; + break; + default: + // Outside kokiri forest + osSyncPrintf(VT_FGCOL(CYAN)); + osSyncPrintf("no = %d \n", owlType); + osSyncPrintf( + "未完成のフクロウ未完成のフクロウ未完成のフクロウ\n"); // Unfinished owl unfinished owl unfinished owl + osSyncPrintf(VT_RST); + this->actionFlags |= 2; + this->unk_3EE = 0x20; + this->actionFunc = EnOwl_WaitOutsideKokiri; + break; + } +} + +void EnOwl_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnOwl* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +/** + * Rotates this to the player instance + */ +void EnOwl_LookAtLink(EnOwl* this, GlobalContext* globalCtx) { + s16 yaw; + Player* player = PLAYER; + + yaw = Math_Vec3f_Yaw(&this->actor.posRot.pos, &player->actor.posRot.pos); + this->actor.posRot.rot.y = yaw; + this->actor.shape.rot.y = yaw; +} + +/** + * Checks if link is within `targetDist` units, initalize the camera for the owl. + * returns 0 if the link is not within `targetDistance`, returns 1 once link is within + * the distance, and the camera has been initalized. + */ +s32 EnOwl_CheckInitTalk(EnOwl* this, GlobalContext* globalCtx, u16 textId, f32 targetDist, u16 flags) { + s32 timer; + f32 distCheck; + + if (func_8002F194(&this->actor, globalCtx) != 0) { + if (this->actor.params == 0xFFF) { + this->actionFlags |= 0x40; + timer = -100; + } else { + if (Rand_ZeroOne() < 0.5f) { + timer = (flags & 1) ? -97 : -99; + this->actionFlags |= 0x40; + } else { + timer = (flags & 1) ? -96 : -98; + this->actionFlags &= ~0x40; + } + } + this->cameraIdx = func_800800F8(globalCtx, 0x21FC, timer, &this->actor, 0); + return true; + } else { + this->actor.textId = textId; + distCheck = (flags & 2) ? 200.0f : 1000.0f; + if (this->actor.xzDistToLink < targetDist) { + this->actor.flags |= 0x10000; + func_8002F1C4(&this->actor, globalCtx, targetDist, distCheck, 0); + } + + return false; + } +} + +s32 func_80ACA558(EnOwl* this, GlobalContext* globalCtx, u16 textId) { + if (func_8002F194(&this->actor, globalCtx)) { + return true; + } else { + this->actor.textId = textId; + if (this->actor.xzDistToLink < 120.0f) { + func_8002F1C4(&this->actor, globalCtx, 350.0f, 1000.0f, 0); + } + + return false; + } +} + +void func_80ACA5C8(EnOwl* this) { + EnOwl_ChangeMode(this, func_80ACBEA0, func_80ACC540, &this->skelAnime, &D_0600C684, 0.0f); + this->eyeTexIndex = 0; + this->blinkTimer = Rand_S16Offset(60, 60); +} + +void func_80ACA62C(EnOwl* this, GlobalContext* globalCtx) { + s32 switchFlag; + + switchFlag = this->actor.params & 0x3F; + if (switchFlag < 0x20) { + Flags_SetSwitch(globalCtx, switchFlag); + osSyncPrintf(VT_FGCOL(CYAN) " Actor_Environment_sw = %d\n" VT_RST, Flags_GetSwitch(globalCtx, switchFlag)); + } + func_80ACA5C8(this); +} + +void func_80ACA690(EnOwl* this, GlobalContext* globalCtx) { + if ((this->unk_3EE & 0x3F) == 0) { + func_80ACA62C(this, globalCtx); + } +} + +void func_80ACA6C0(EnOwl* this) { + if (Rand_CenteredFloat(1.0f) < 0.0f) { + this->actionFlags |= 0x20; + } else { + this->actionFlags &= ~0x20; + } +} + +void func_80ACA71C(EnOwl* this) { + func_80ACA6C0(this); + this->unk_3F2 = 0; + this->actionFlags |= 0x10; + this->unk_408 = 4; + this->unk_404 = 0; + this->unk_406 = 0; + this->unk_405 = 4; + this->unk_407 = this->unk_3F2; +} + +void func_80ACA76C(EnOwl* this, GlobalContext* globalCtx) { + func_8002DF54(globalCtx, &this->actor, 8); + + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + func_80ACA62C(this, globalCtx); + this->actor.flags &= ~0x10000; + } +} + +void func_80ACA7E0(EnOwl* this, GlobalContext* globalCtx) { + func_8002DF54(globalCtx, &this->actor, 8); + + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + if ((this->unk_3EE & 0x3F) == 0) { + func_80ACA62C(this, globalCtx); + } else { + this->actionFlags &= ~2; + func_80ACA71C(this); + this->actionFunc = func_80ACA690; + } + this->actor.flags &= ~0x10000; + } +} + +void EnOwl_ConfirmKokiriMessage(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x2065); + break; + case OWL_OK: + func_8010B720(globalCtx, 0x2067); + this->actionFunc = func_80ACA76C; + break; + } + } +} + +void EnOwl_WaitOutsideKokiri(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x2064, 360.0f, 0) != 0) { + // Sets BGM + func_800F5C64(0x5A); + + this->actionFunc = EnOwl_ConfirmKokiriMessage; + // spoke to owl by lost woods + gSaveContext.eventChkInf[6] |= 0x8000; + } +} + +void func_80ACA998(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x2069); + this->actionFunc = func_80ACAA54; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x206B); + this->actionFunc = func_80ACA7E0; + break; + } + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACAA54(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x206A); + this->actionFunc = func_80ACA998; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void func_80ACAAC0(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x2069); + this->actionFunc = func_80ACAA54; + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitHyruleCastle(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x2068, 540.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACAAC0; + } +} + +void func_80ACAB88(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + // obtained zelda's letter + if (gSaveContext.eventChkInf[4] & 1) { + func_8010B720(globalCtx, 0x206D); + } else { + func_8010B720(globalCtx, 0x206C); + } + this->actionFunc = func_80ACAC6C; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x206E); + this->actionFunc = func_80ACA7E0; + break; + } + + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACAC6C(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x206A); + this->actionFunc = func_80ACAB88; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitKakariko(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x206C, 480.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACAC6C; + } +} + +void func_80ACAD34(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x206F); + this->actionFunc = func_80ACADF0; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x2070); + this->actionFunc = func_80ACA7E0; + break; + } + + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACADF0(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x206A); + this->actionFunc = func_80ACAD34; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitGerudo(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x206F, 360.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACADF0; + } +} + +void func_80ACAEB8(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x2071); + this->actionFunc = func_80ACAF74; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x2072); + this->actionFunc = func_80ACA7E0; + break; + } + + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACAF74(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x206A); + this->actionFunc = func_80ACAEB8; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitLakeHylia(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x2071, 360.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACAF74; + } +} + +void func_80ACB03C(EnOwl* this, GlobalContext* globalCtx) { + func_8002DF54(globalCtx, &this->actor, 8); + + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + func_80ACA62C(this, globalCtx); + this->actor.flags &= ~0x10000; + } +} + +void EnOwl_WaitZoraRiver(EnOwl* this, GlobalContext* globalCtx) { + u16 textId; + + EnOwl_LookAtLink(this, globalCtx); + + if (CHECK_QUEST_ITEM(QUEST_SONG_SARIA)) { + if (CHECK_QUEST_ITEM(QUEST_SONG_LULLABY)) { + textId = 0x4031; + } else { + textId = 0x4017; + } + } else { + textId = 0x4002; + } + + if (EnOwl_CheckInitTalk(this, globalCtx, textId, 360.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB03C; + } +} + +void func_80ACB148(EnOwl* this, GlobalContext* globalCtx) { + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + func_80ACA5C8(this); + this->actionFunc = func_80ACC30C; + Flags_SetSwitch(globalCtx, 0x23); + } +} + +void EnOwl_WaitHyliaShortcut(EnOwl* this, GlobalContext* globalCtx) { + u16 textId; + // Spoke to Owl in Lake Hylia + if (gSaveContext.infTable[25] & 0x20) { + textId = 0x4004; + } else { + textId = 0x4003; + } + + EnOwl_LookAtLink(this, globalCtx); + if (func_80ACA558(this, globalCtx, textId) != 0) { + gSaveContext.infTable[25] |= 0x20; + func_800F5C64(0x5A); + this->actionFunc = func_80ACB148; + } +} + +void func_80ACB22C(EnOwl* this, GlobalContext* globalCtx) { + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + func_80ACA5C8(this); + this->actionFunc = func_80ACC30C; + } +} + +void func_80ACB274(EnOwl* this, GlobalContext* globalCtx) { + if (func_8002F334(&this->actor, globalCtx) != 0) { + Audio_SetBGM(0x110000FF); + this->actionFunc = EnOwl_WaitDeathMountainShortcut; + } +} + +void EnOwl_WaitDeathMountainShortcut(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (!gSaveContext.magicAcquired) { + if (func_80ACA558(this, globalCtx, 0x3062) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB274; + return; + } + } else { + if (func_80ACA558(this, globalCtx, 0x3063) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB22C; + } + } +} + +void func_80ACB344(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x607A); + break; + case OWL_OK: + func_8010B720(globalCtx, 0x607C); + this->actionFunc = func_80ACA7E0; + break; + } + } +} + +void func_80ACB3E0(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x6079, 360.0f, 2) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB344; + } +} + +void func_80ACB440(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x10C1); + this->actionFunc = func_80ACB4FC; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x10C3); + this->actionFunc = func_80ACA7E0; + } + + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACB4FC(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x10C2); + this->actionFunc = func_80ACB440; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitLWPreSaria(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x10C0, 190.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB4FC; + } +} + +void func_80ACB5C4(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 4 && func_80106BC8(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case OWL_REPEAT: + func_8010B720(globalCtx, 0x10C5); + this->actionFunc = func_80ACB680; + break; + case OWL_OK: + func_8010B720(globalCtx, 0x10C7); + this->actionFunc = func_80ACA7E0; + break; + } + + this->actionFlags &= ~2; + func_80ACA71C(this); + } +} + +void func_80ACB680(EnOwl* this, GlobalContext* globalCtx) { + if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx) != 0) { + func_8010B720(globalCtx, 0x10C6); + this->actionFunc = func_80ACB5C4; + this->actionFlags |= 2; + func_80ACA71C(this); + } +} + +void EnOwl_WaitLWPostSaria(EnOwl* this, GlobalContext* globalCtx) { + EnOwl_LookAtLink(this, globalCtx); + + if (EnOwl_CheckInitTalk(this, globalCtx, 0x10C4, 360.0f, 0) != 0) { + func_800F5C64(0x5A); + this->actionFunc = func_80ACB680; + } +} + +void func_80ACB748(EnOwl* this, GlobalContext* globalCtx) { + static Vec3f D_80ACD62C = { 0.0f, 0.0f, 0.0f }; + f32 unkf2; + f32 xyzDist; + u32 owlType; + + owlType = (this->actor.params & 0xFC0) >> 6; + xyzDist = Math3D_Vec3f_DistXYZ(&this->eye, &globalCtx->view.eye) / 45.0f; + this->eye.x = globalCtx->view.eye.x; + this->eye.y = globalCtx->view.eye.y; + this->eye.z = globalCtx->view.eye.z; + xyzDist = xyzDist; + + if (xyzDist > 1.0f) { + xyzDist = 1.0f; + } + + switch (owlType) { + case 7: + unkf2 = xyzDist * 2.f; + func_800F436C(&D_80ACD62C, NA_SE_EV_FLYING_AIR - SFX_FLAG, unkf2); + if ((globalCtx->csCtx.frames > 324) || + ((globalCtx->csCtx.frames >= 142 && (globalCtx->csCtx.frames <= 266)))) { + func_800F4414(&D_80ACD62C, NA_SE_EN_OWL_FLUTTER, unkf2); + } + if (globalCtx->csCtx.frames == 85) { + func_800F436C(&D_80ACD62C, NA_SE_EV_PASS_AIR, unkf2); + } + break; + case 8: + case 9: + unkf2 = xyzDist * 2.f; + func_800F436C(&D_80ACD62C, NA_SE_EV_FLYING_AIR - SFX_FLAG, unkf2); + if ((globalCtx->csCtx.frames >= 420) || + ((0xC1 < globalCtx->csCtx.frames && (globalCtx->csCtx.frames <= 280)))) { + func_800F4414(&D_80ACD62C, NA_SE_EN_OWL_FLUTTER, unkf2); + } + if (globalCtx->csCtx.frames == 217) { + func_800F436C(&D_80ACD62C, NA_SE_EV_PASS_AIR, unkf2); + } + break; + } +} + +void func_80ACB904(EnOwl* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != CS_STATE_IDLE && (globalCtx->csCtx.npcActions[7] != NULL)) { + if (this->unk_40A != globalCtx->csCtx.npcActions[7]->action) { + func_80ACD130(this, globalCtx, 7); + func_80ACBAB8(this, globalCtx); + } + func_80ACD2CC(this, globalCtx); + } + + if (this->actionFlags & 0x80) { + func_80ACB748(this, globalCtx); + } +} + +void func_80ACB994(EnOwl* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != CS_STATE_IDLE && (globalCtx->csCtx.npcActions[7] != NULL)) { + if (this->unk_40A != globalCtx->csCtx.npcActions[7]->action) { + func_80ACD130(this, globalCtx, 7); + func_80ACBAB8(this, globalCtx); + } + func_80ACD4D4(this, globalCtx); + } + + if (this->actionFlags & 0x80) { + func_80ACB748(this, globalCtx); + } +} + +void EnOwl_WaitDefault(EnOwl* this, GlobalContext* globalCtx) { + u16 angle; + + if (globalCtx->csCtx.state != CS_STATE_IDLE && (globalCtx->csCtx.npcActions[7] != NULL)) { + if (this->unk_40A != globalCtx->csCtx.npcActions[7]->action) { + this->actionFlags |= 4; + func_80ACD130(this, globalCtx, 7); + func_80ACBAB8(this, globalCtx); + } else { + this->actor.posRot.rot.z = globalCtx->csCtx.npcActions[7]->urot.y; + } + } + + if (this->actionFlags & 0x80) { + func_80ACB748(this, globalCtx); + } +} + +void func_80ACBAB8(EnOwl* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.npcActions[7]->action - 1) { + case 0: + EnOwl_ChangeMode(this, func_80ACB904, func_80ACC540, &this->skelAnime, &D_060015CC, 0.0f); + break; + case 1: + this->actor.draw = EnOwl_Draw; + EnOwl_ChangeMode(this, EnOwl_WaitDefault, func_80ACC540, &this->skelAnime, &D_0600C8A0, 0.0f); + break; + case 2: + this->actor.draw = EnOwl_Draw; + EnOwl_ChangeMode(this, func_80ACB994, func_80ACC540, &this->skelAnime, &D_060015CC, 0.0f); + break; + case 3: + this->actor.draw = NULL; + this->actionFunc = EnOwl_WaitDefault; + break; + case 4: + Actor_Kill(&this->actor); + break; + } + + this->unk_40A = globalCtx->csCtx.npcActions[7]->action; +} + +void func_80ACBC0C(EnOwl* this, GlobalContext* globalCtx) { + this->actor.flags |= 0x20; + + if (this->actor.xzDistToLink > 6000.0f && !(this->actionFlags & 0x80)) { + Actor_Kill(&this->actor); + } + + Math_SmoothStepToS(&this->actor.posRot.rot.y, this->unk_400, 2, 0x80, 0x40); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + + if (this->actor.speedXZ < 16.0f) { + this->actor.speedXZ += 0.5f; + } + + if ((this->unk_3F8 + 1000.0f) < this->actor.posRot.pos.y) { + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y -= 0.4f; + } + } else if (this->actor.velocity.y < 4.0f) { + this->actor.velocity.y += 0.2f; + } + + this->actionFlags |= 8; +} + +void func_80ACBD4C(EnOwl* this, GlobalContext* globalCtx) { + if (this->skelAnime.curFrame > 10.0f) { + Math_SmoothStepToS(&this->actor.posRot.rot.y, this->unk_400, 2, 0x400, 0x40); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + } + + if (this->skelAnime.curFrame > 45.0f) { + this->actor.velocity.y = 2.0f; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 8.0f; + } else if (this->skelAnime.curFrame > 17.0f) { + this->actor.velocity.y = 6.0f; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 4.0f; + } + + if (this->actionFlags & 1) { + EnOwl_ChangeMode(this, func_80ACBC0C, func_80ACC460, &this->skelAnime, &D_060015CC, 0.0f); + this->unk_3FE = 6; + if (this->actionFlags & 0x40) { + this->unk_400 += 0x2000; + } else { + this->unk_400 -= 0x2000; + } + } + + this->actionFlags |= 8; +} + +void func_80ACBEA0(EnOwl* this, GlobalContext* GlobalContext) { + if (this->actionFlags & 1) { + this->unk_3FE = 3; + EnOwl_ChangeMode(this, func_80ACBD4C, func_80ACC540, &this->skelAnime, &D_06001168, 0.0f); + this->unk_3F8 = this->actor.posRot.pos.y; + this->actor.velocity.y = 2.0f; + if (this->actionFlags & 0x40) { + this->unk_400 = this->actor.posRot.rot.y + 0x4000; + } else { + this->unk_400 = this->actor.posRot.rot.y - 0x4000; + } + } + + this->actionFlags |= 8; +} + +void func_80ACBF50(EnOwl* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.posRot.rot.y, this->unk_400, 2, 0x384, 0x258); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + + if (this->actionFlags & 1) { + EnOwl_ChangeMode(this, func_80ACBC0C, func_80ACC460, &this->skelAnime, &D_060015CC, 0.0f); + this->unk_3FE = 6; + this->actor.velocity.y = 2.0f; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 4.0f; + } + this->actionFlags |= 8; +} + +void func_80ACC00C(EnOwl* this, GlobalContext* globalCtx) { + s32 owlType; + s32 temp_v0; + s32 temp_v0_2; + + Math_SmoothStepToS(&this->actor.posRot.rot.y, this->unk_400, 2, 0x384, 0x258); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + + if (this->actor.xzDistToLink < 50.0f) { + if (!Gameplay_InCsMode(globalCtx)) { + owlType = (this->actor.params & 0xFC0) >> 6; + osSyncPrintf(VT_FGCOL(CYAN)); + osSyncPrintf("%dのフクロウ\n", owlType); // "%d owl" + osSyncPrintf(VT_RST); + switch (owlType) { + case 7: + osSyncPrintf(VT_FGCOL(CYAN)); + osSyncPrintf("SPOT 06 の デモがはしった\n"); // Demo of SPOT 06 + osSyncPrintf(VT_RST); + globalCtx->csCtx.segment = SEGMENTED_TO_VIRTUAL(&D_0201B0C0); + this->actor.draw = NULL; + break; + case 8: + case 9: + globalCtx->csCtx.segment = SEGMENTED_TO_VIRTUAL(&D_0201E6A0); + this->actor.draw = NULL; + break; + default: + __assert("0", "../z_en_owl.c", 1693); + break; + } + + func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + gSaveContext.cutsceneTrigger = 1; + func_800F44EC(0x14, 0xA); + this->actionFunc = EnOwl_WaitDefault; + this->unk_40A = 0; + this->actionFlags |= 0x80; + D_8011FB40 = 0; + } + } + + if (this->skelAnime.curFrame >= 37.0f) { + if (this->unk_3FE > 0) { + this->skelAnime.curFrame = 21.0f; + this->unk_3FE--; + } else { + this->actionFunc = func_80ACBF50; + } + } + + this->actionFlags |= 8; +} + +void func_80ACC23C(EnOwl* this, GlobalContext* globalCtx) { + if (this->skelAnime.curFrame < 20.0f) { + this->actor.speedXZ = 1.5f; + } else { + this->actor.speedXZ = 0.0f; + Math_SmoothStepToS(&this->actor.posRot.rot.y, this->unk_400, 2, 0x384, 0x258); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + } + + if (this->skelAnime.curFrame >= 37.0f) { + this->skelAnime.curFrame = 21.0f; + this->actionFunc = func_80ACC00C; + this->unk_3FE = 5; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 0.0f; + } + + this->actionFlags |= 8; +} + +void func_80ACC30C(EnOwl* this, GlobalContext* globalCtx) { + if (this->actionFlags & 1) { + this->unk_3FE = 3; + EnOwl_ChangeMode(this, func_80ACC23C, func_80ACC540, &this->skelAnime, &D_06001168, 0.0f); + this->unk_3F8 = this->actor.posRot.pos.y; + this->actor.velocity.y = 0.2f; + } + + this->actionFlags |= 8; +} + +void func_80ACC390(EnOwl* this) { + SkelAnime_Update(this->curSkelAnime); + + if (this->unk_3FE > 0) { + this->unk_3FE--; + this->actor.shape.rot.z = Math_SinS(this->unk_3FE * 0x333) * 1000.0f; + } else { + this->unk_410 = &func_80ACC460; + this->unk_3FE = 6; + Animation_Change(this->curSkelAnime, &D_060015CC, 1.0f, 0.0f, Animation_GetLastFrame(&D_060015CC), 2, 5.0f); + } +} + +void func_80ACC460(EnOwl* this) { + if (SkelAnime_Update(this->curSkelAnime) != 0) { + if (this->unk_3FE > 0) { + this->unk_3FE--; + Animation_Change(this->curSkelAnime, this->curSkelAnime->animation, 1.0f, 0.0f, + Animation_GetLastFrame(this->curSkelAnime->animation), 2, 0.0f); + } else { + this->unk_3FE = 0xA0; + this->unk_410 = func_80ACC390; + Animation_Change(this->curSkelAnime, &D_0600C1C4, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600C1C4), 0, 5.0f); + } + } +} + +void func_80ACC540(EnOwl* this) { + if (SkelAnime_Update(this->curSkelAnime) != 0) { + Animation_Change(this->curSkelAnime, this->curSkelAnime->animation, 1.0f, 0.0f, + Animation_GetLastFrame(this->curSkelAnime->animation), 2, 0.0f); + this->actionFlags |= 1; + } else { + this->actionFlags &= ~1; + } +} + +s32 func_80ACC5CC(EnOwl* this) { + s32 phi_v1; + s32 ret; + + phi_v1 = (this->actionFlags & 2) ? 0x20 : 0; + + if (phi_v1 == (this->unk_3EE & 0x3F)) { + return true; + } else { + if (this->actionFlags & 0x20) { + this->unk_3EE += 4; + } else { + this->unk_3EE -= 4; + } + + return false; + } +} + +s32 func_80ACC624(EnOwl* this, GlobalContext* globalCtx) { + s32 switchFlag = (this->actor.params & 0xFC0) >> 6; + + if (globalCtx->sceneNum != SCENE_SPOT11) { + return true; + } else if (switchFlag == 0xA) { + return true; + } else if (globalCtx->csCtx.frames >= 300 && globalCtx->csCtx.frames <= 430) { + return true; + } else if (globalCtx->csCtx.frames >= 1080 && globalCtx->csCtx.frames <= 1170) { + return true; + } else { + return false; + } +} + +#ifdef NON_MATCHING +// Minor regalloc surrounding the unk_3EE at the end of the function. +void EnOwl_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOwl* this = THIS; + s16 phi_a1; + + Collider_CylinderUpdate(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + func_8002E4B4(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 5); + this->unk_410(this); + this->actionFlags &= ~8; + this->actionFunc(this, globalCtx); + if (this->actor.update == NULL) { + // Owl disappears + osSyncPrintf("フクロウ消滅!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + return; + } + + if (!(this->actionFlags & 0x80) && func_80ACC624(this, globalCtx)) { + if ((this->skelAnime.animation == &D_06001168 && + (this->skelAnime.curFrame == 2.0f || this->skelAnime.curFrame == 9.0f || + this->skelAnime.curFrame == 23.0f || this->skelAnime.curFrame == 40.0f || + this->skelAnime.curFrame == 58.0f)) || + (this->skelAnime.animation == &D_060015CC && this->skelAnime.curFrame == 4.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_OWL_FLUTTER); + } + } + + if (this->actor.draw != NULL) { + Actor_MoveForward(&this->actor); + } + + if (this->actionFlags & 2) { + this->eyeTexIndex = 2; + } else { + if (DECR(this->blinkTimer) == 0) { + this->blinkTimer = Rand_S16Offset(60, 60); + } + + this->eyeTexIndex = this->blinkTimer; + + if (this->eyeTexIndex >= 3) { + this->eyeTexIndex = 0; + } + } + + if (!(this->actionFlags & 8)) { + phi_a1 = 0; + if (this->actionFlags & 0x10) { + switch (this->unk_404) { + case 0: + this->unk_404 = 1; + this->unk_405 = 6; + break; + case 1: + this->unk_405--; + + if (this->unk_405 != 0) { + phi_a1 = Math_CosS(this->unk_405 * 8192) * 4096.0f; + } else { + if (this->actionFlags & 2) { + this->unk_3EE = 0; + } else { + this->unk_3EE = 0x20; + } + + if (this->actionFlags & 0x20) { + this->unk_3EE -= 4; + } else { + this->unk_3EE += 4; + } + this->unk_404++; + } + + if (this->actionFlags & 0x20) { + phi_a1 = -phi_a1; + } + break; + case 2: + if (func_80ACC5CC(this)) { + this->actionFlags &= ~0x10; + this->unk_406 = (s32)Rand_ZeroFloat(20.0f) + 0x3C; + this->unk_404 = 0; + func_80ACA6C0(this); + } + break; + default: + break; + } + } else { + if (this->unk_406 > 0) { + this->unk_406--; + } else { + if (this->unk_404 == 0) { + if (Rand_ZeroOne() < 0.3f) { + this->unk_404 = 4; + this->unk_405 = 0xC; + } else { + this->unk_404 = 1; + this->unk_405 = 4; + } + } + + this->unk_405--; + + switch (this->unk_404) { + case 1: + phi_a1 = Math_SinS((-this->unk_405 * 4096) + 0x4000) * 5000.0f; + if (this->unk_405 <= 0) { + this->unk_405 = (s32)(Rand_ZeroFloat(15.0f) + 5.0f); + this->unk_404 = 2; + } + break; + case 2: + phi_a1 = 0x1388; + if (this->unk_405 <= 0) { + this->unk_404 = 3; + this->unk_405 = 4; + } + break; + case 3: + phi_a1 = Math_SinS(this->unk_405 * 4096) * 5000.0f; + if (this->unk_405 <= 0) { + this->unk_406 = (s32)Rand_ZeroFloat(20.0f) + 0x3C; + this->unk_404 = 0; + func_80ACA6C0(this); + } + break; + case 4: + phi_a1 = Math_SinS(this->unk_405 * 8192) * 5000.0f; + if (this->unk_405 <= 0) { + this->unk_406 = (s32)Rand_ZeroFloat(20.0f) + 0x3C; + this->unk_404 = 0; + func_80ACA6C0(this); + } + break; + default: + break; + } + + if (this->actionFlags & 0x20) { + phi_a1 = -phi_a1; + } + } + + if (this->unk_409 > 0) { + this->unk_409--; + } else { + this->unk_408--; + switch (this->unk_407) { + case 0: + this->unk_3F2 = (-this->unk_408 * 0x5DC) + 0x1770; + if (this->unk_408 <= 0) { + this->unk_407 = 1; + this->unk_408 = (s32)(Rand_ZeroFloat(15.0f) + 5.0f); + } + break; + case 1: + this->unk_3F2 = 0x1770; + if (this->unk_408 <= 0) { + this->unk_407 = 2; + this->unk_408 = 4; + } + break; + case 2: + this->unk_3F2 = this->unk_408 * 0x5DC; + if (this->unk_408 <= 0) { + this->unk_407 = 0; + this->unk_408 = 4; + this->unk_409 = (s32)Rand_ZeroFloat(40.0f) + 0xA0; + } + break; + default: + break; + } + } + } + if (phi_a1) {} + this->unk_3F0 = (s16)(this->unk_3EE * 1024) + phi_a1; + this->unk_3EC = ABS(this->unk_3F0) >> 3; + } else { + this->unk_3F2 = 0; + if (this->actionFlags & 2) { + this->unk_3F0 = -0x8000; + } else { + this->unk_3F0 = 0; + } + + this->unk_3EC = ABS(this->unk_3F0) >> 3; + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/EnOwl_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACCE00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACCF34.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/EnOwl_Draw.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD0B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD130.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD1C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD220.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD2CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Owl/func_80ACD4D4.s") +#endif + +s32 EnOwl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** gfx, Vec3f* pos, Vec3s* rot, void* thisx) { + EnOwl* this = THIS; + + switch (limbIndex) { + case 3: + rot->x += this->unk_3F0; + rot->z += this->unk_3EC; + rot->z -= this->unk_3F2; + break; + case 2: + rot->z += this->unk_3F2; + break; + case 4: + if (!(this->actionFlags & 8)) { + rot->y -= (s16)(this->unk_3EC * 1.5f); + } + break; + case 5: + if (!(this->actionFlags & 8)) { + rot->y += (s16)(this->unk_3EC * 1.5f); + } + break; + default: + break; + } + return 0; +} + +void EnOwl_PostLimbUpdate(GlobalContext* globalCtx, s32 limbIndex, Gfx** gfx, Vec3s* rot, void* thisx) { + EnOwl* this = THIS; + Vec3f vec; + + vec.z = 0.0f; + if (this->actionFlags & 2) { + vec.x = 700.0f; + vec.y = 400.0f; + } else { + vec.y = 0.0f; + vec.x = 1400.0f; + } + if (limbIndex == 3) { + Matrix_MultVec3f(&vec, &this->actor.posRot2.pos); + } +} + +void EnOwl_Draw(Actor* thisx, GlobalContext* globalCtx) { + static u64* eyeTextures[] = { 0x060089A8, 0x06008DA8, 0x060091A8 }; + EnOwl* this = THIS; + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_owl.c", 2247); + + func_800943C8(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 8, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTexIndex])); + SkelAnime_DrawFlexOpa(globalCtx, this->curSkelAnime->skeleton, this->curSkelAnime->jointTable, + this->curSkelAnime->dListCount, EnOwl_OverrideLimbDraw, EnOwl_PostLimbUpdate, this); + + CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_owl.c", 2264); +} + +void EnOwl_ChangeMode(EnOwl* this, EnOwlActionFunc actionFunc, OwlFunc arg2, SkelAnime* skelAnime, + AnimationHeader* animation, f32 transitionRate) { + this->curSkelAnime = skelAnime; + Animation_Change(this->curSkelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), 2, transitionRate); + this->actionFunc = actionFunc; + this->unk_410 = arg2; +} + +void func_80ACD130(EnOwl* this, GlobalContext* globalCtx, s32 idx) { + Vec3f startPos; + + startPos.x = globalCtx->csCtx.npcActions[idx]->startPos.x; + startPos.y = globalCtx->csCtx.npcActions[idx]->startPos.y; + startPos.z = globalCtx->csCtx.npcActions[idx]->startPos.z; + this->actor.posRot.pos = startPos; + this->actor.posRot.rot.y = this->actor.shape.rot.y = globalCtx->csCtx.npcActions[idx]->rot.y; + this->actor.shape.rot.z = globalCtx->csCtx.npcActions[idx]->urot.z; +} + +f32 func_80ACD1C4(GlobalContext* globalCtx, s32 idx) { + f32 ret; + + ret = func_8006F93C(globalCtx->csCtx.npcActions[idx]->endFrame, globalCtx->csCtx.npcActions[idx]->startFrame, + globalCtx->csCtx.frames); + if (ret > 1.0f) { + ret = 1.0f; + } + return ret; +} + +void func_80ACD220(EnOwl* this, Vec3f* arg1, f32 arg2) { + Vec3f rpy; + + rpy.x = (arg1->x - this->actor.posRot.pos.x) * arg2; + rpy.y = (arg1->y - this->actor.posRot.pos.y) * arg2; + rpy.z = (arg1->z - this->actor.posRot.pos.z) * arg2; + + Math_StepToF(&this->actor.velocity.y, rpy.y, 1.0f); + this->actor.speedXZ = sqrtf(SQ(rpy.x) + SQ(rpy.z)); + this->actor.posRot.rot.y = Math_Vec3f_Yaw(&this->actor.posRot.pos, arg1); + this->actor.shape.rot.y = this->actor.posRot.rot.y; +} + +void func_80ACD2CC(EnOwl* this, GlobalContext* globalCtx) { + Vec3f pos; + s32 angle; + f32 t; + f32 phi_f2; + + t = func_80ACD1C4(globalCtx, 7); + pos.x = globalCtx->csCtx.npcActions[7]->startPos.x; + pos.y = globalCtx->csCtx.npcActions[7]->startPos.y; + pos.z = globalCtx->csCtx.npcActions[7]->startPos.z; + angle = (s16)globalCtx->csCtx.npcActions[7]->rot.y - this->actor.posRot.rot.z; + if (angle < 0) { + angle += 0x10000; + } + angle = (s16)((t * angle) + this->actor.posRot.rot.z); + angle = (u16)angle; + if (this->actionFlags & 4) { + phi_f2 = globalCtx->csCtx.npcActions[7]->urot.x; + phi_f2 *= 0.054931640625f; + if (phi_f2 < 0.0f) { + phi_f2 += 360.0f; + } + pos.x -= Math_SinS(angle) * phi_f2; + pos.z += Math_CosS(angle) * phi_f2; + this->unk_3F8 = phi_f2; + this->actor.posRot.pos = pos; + this->actor.draw = &EnOwl_Draw; + this->actionFlags &= ~4; + this->actor.speedXZ = 0.0f; + return; + } + pos.x -= Math_SinS(angle) * this->unk_3F8; + pos.z += Math_CosS(angle) * this->unk_3F8; + func_80ACD220(this, &pos, 1.0f); +} + +void func_80ACD4D4(EnOwl* this, GlobalContext* globalCtx) { + Vec3f pos; + Vec3f endPosf; + f32 temp_ret; + CsCmdActorAction* actorCmd; + + temp_ret = func_80ACD1C4(globalCtx, 7); + pos.x = globalCtx->csCtx.npcActions[7]->startPos.x; + pos.y = globalCtx->csCtx.npcActions[7]->startPos.y; + pos.z = globalCtx->csCtx.npcActions[7]->startPos.z; + actorCmd = globalCtx->csCtx.npcActions[7]; + endPosf.x = actorCmd->endPos.x; + endPosf.y = actorCmd->endPos.y; + endPosf.z = actorCmd->endPos.z; + pos.x = (endPosf.x - pos.x) * temp_ret + pos.x; + pos.y = (endPosf.y - pos.y) * temp_ret + pos.y; + pos.z = (endPosf.z - pos.z) * temp_ret + pos.z; + func_80ACD220(this, &pos, 1.0f); +} diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.h b/src/overlays/actors/ovl_En_Owl/z_en_owl.h index f36a82090..2f7949965 100644 --- a/src/overlays/actors/ovl_En_Owl/z_en_owl.h +++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.h @@ -6,9 +6,41 @@ struct EnOwl; +typedef void (*EnOwlActionFunc)(struct EnOwl*, GlobalContext*); +typedef void (*OwlFunc)(struct EnOwl*); + typedef struct EnOwl { /* 0x0000 */ Actor actor; - /* 0x014C */ char unk_14C[0x2C8]; + /* 0x014C */ ColliderCylinder collider; + /* 0x0198 */ SkelAnime skelAnime; + /* 0x01DC */ Vec3s jointTable[21]; + /* 0x025A */ Vec3s morphTable[21]; + /* 0x02D8 */ SkelAnime skelAnime2; + /* 0x031C */ Vec3s jointTable2[16]; + /* 0x037C */ Vec3s morphTable2[16]; + /* 0x03DC */ SkelAnime* curSkelAnime; + /* 0x03E0 */ Vec3f eye; + /* 0x03EC */ s16 unk_3EC; + /* 0x03EE */ s16 unk_3EE; + /* 0x03F0 */ s16 unk_3F0; + /* 0x03F2 */ s16 unk_3F2; + /* 0x03F4 */ s16 eyeTexIndex; + /* 0x03F6 */ s16 blinkTimer; + /* 0x03F8 */ f32 unk_3F8; + /* 0x03FC */ u16 actionFlags; + /* 0x03FE */ u16 unk_3FE; + /* 0x0400 */ s16 unk_400; + /* 0x0402 */ s16 cameraIdx; + /* 0x0404 */ u8 unk_404; + /* 0x0405 */ u8 unk_405; + /* 0x0406 */ u8 unk_406; + /* 0x0407 */ u8 unk_407; + /* 0x0408 */ u8 unk_408; + /* 0x0409 */ u8 unk_409; + /* 0x040A */ u8 unk_40A; + /* 0x040B */ u8 unk_40B; + /* 0x040C */ EnOwlActionFunc actionFunc; + /* 0x0410 */ OwlFunc unk_410; } EnOwl; // size = 0x0414 extern const ActorInit En_Owl_InitVars; |
